diff --git a/images/usage/tools/CloudCode-tasks.png b/images/usage/tools/CloudCode-tasks.png
new file mode 100644
index 00000000..071da591
Binary files /dev/null and b/images/usage/tools/CloudCode-tasks.png differ
diff --git a/images/usage/tools/CloudCode.png b/images/usage/tools/CloudCode.png
new file mode 100644
index 00000000..3fc4d5c3
Binary files /dev/null and b/images/usage/tools/CloudCode.png differ
diff --git a/images/usage/tools/JourneyApps_Project_1.png b/images/usage/tools/JourneyApps_Project_1.png
new file mode 100644
index 00000000..9278e360
Binary files /dev/null and b/images/usage/tools/JourneyApps_Project_1.png differ
diff --git a/images/usage/tools/JourneyApps_Project_2.png b/images/usage/tools/JourneyApps_Project_2.png
new file mode 100644
index 00000000..13155c95
Binary files /dev/null and b/images/usage/tools/JourneyApps_Project_2.png differ
diff --git a/images/usage/tools/JourneyApps_Project_3.png b/images/usage/tools/JourneyApps_Project_3.png
new file mode 100644
index 00000000..2342838c
Binary files /dev/null and b/images/usage/tools/JourneyApps_Project_3.png differ
diff --git a/images/usage/tools/JourneyApps_Project_4.png b/images/usage/tools/JourneyApps_Project_4.png
new file mode 100644
index 00000000..254f52de
Binary files /dev/null and b/images/usage/tools/JourneyApps_Project_4.png differ
diff --git a/images/usage/tools/JourneyApps_Project_5.png b/images/usage/tools/JourneyApps_Project_5.png
new file mode 100644
index 00000000..a33833ae
Binary files /dev/null and b/images/usage/tools/JourneyApps_Project_5.png differ
diff --git a/images/usage/tools/JourneyApps_Project_6.png b/images/usage/tools/JourneyApps_Project_6.png
new file mode 100644
index 00000000..7155d5b1
Binary files /dev/null and b/images/usage/tools/JourneyApps_Project_6.png differ
diff --git a/images/usage/tools/cloudcode-envvar.png b/images/usage/tools/cloudcode-envvar.png
new file mode 100644
index 00000000..d7a50822
Binary files /dev/null and b/images/usage/tools/cloudcode-envvar.png differ
diff --git a/images/usage/tools/test-cloudcode-task.png b/images/usage/tools/test-cloudcode-task.png
new file mode 100644
index 00000000..b9672f32
Binary files /dev/null and b/images/usage/tools/test-cloudcode-task.png differ
diff --git a/mint.json b/mint.json
index 63996715..20ce2e43 100644
--- a/mint.json
+++ b/mint.json
@@ -225,7 +225,8 @@
"usage/tools/powersync-dashboard",
"usage/tools/cli",
"usage/tools/diagnostic-app",
- "usage/tools/monitoring-and-alerting"
+ "usage/tools/monitoring-and-alerting",
+ "usage/tools/mongodb-crud-auth-backend"
]
}
]
diff --git a/usage/tools.mdx b/usage/tools.mdx
index f282bb48..bc41a28f 100644
--- a/usage/tools.mdx
+++ b/usage/tools.mdx
@@ -9,4 +9,5 @@ mode: wide
+
diff --git a/usage/tools/mongodb-crud-auth-backend.mdx b/usage/tools/mongodb-crud-auth-backend.mdx
new file mode 100644
index 00000000..2f254a06
--- /dev/null
+++ b/usage/tools/mongodb-crud-auth-backend.mdx
@@ -0,0 +1,204 @@
+---
+title: MongoDB CRUD & Auth Backend
+description:
+---
+
+This project provides a serverless backend API for a client application using PowerSync.
+
+For more information about CloudCode serverless functions, please visit [this page](https://docs.journeyapps.com/reference/cloudcode/triggering-a-cloudcode-task/trigger-cc-via-http).
+
+# Create New CloudCode Project
+To create a new CloudCode project, following the steps below:
+
+
+ Navigate to the [JourneyApps Portal](https://accounts.journeyapps.com/) (create an account if you do not have one already).
+ You should see a list of your projects if you've created any.
+
+
+
+
+
+ Select `Create Project` at the top right of the screen.
+
+
+
+
+
+ Select `JourneyApps Platform Project` and click `Next`.
+
+
+
+
+
+ Enter a Project name and click `Next`.
+
+
+
+
+
+ There are two options for how you can manage changes to your project:
+ 1. `Basic (Revision)`: A simple workflow with basic restore points
+ 2. `Advanced (Git)`: A git-based workflow with commits, branching and merging.
+
+ Select a `Version Control` option, `Git` provider and click `Next`.
+ For demonstration purposes we will choose `Basic` and `JourneyApps` as our Git provider.
+
+
+
+
+
+ To base your project on a template, select `TypeScript` as your template language, and `MongoDB CRUD & Auth Backend` as your template. You can now create your app
+ by clicking `Create App`.
+
+
+
+
+
+
+# Setting Up CloudCode Serverless Functions
+
+To view the serverless functions, select the **CloudCode** option at the top of the IDE.
+
+
+
+
+
+Here you will find four CloudCode tasks:
+
+
+
+
+1. `generate_keys` - This is a task that can be used to generate a private/public key pair which the `jwks` and `token` tasks require.
+
+
+ This task does not expose an HTTP endpoint and should only be used for development and getting started.
+
+2. `jwks` - This exposes an HTTP endpoint which has a `GET` function which returns the public JWKS details.
+3. `token` - This task exposes an HTTP endpoint which has a `GET` function. This tasks is used by a PowerSync client to generate a token to validate against the PowerSync Service.
+For more information about custom authentication setups for PowerSync, please see [this page](https://docs.powersync.com/installation/authentication-setup/custom) from the PowerSync docs.
+4. `upload` - This task exposes an HTTP endpoint which has a `POST` function which is used to process the write events from a PowerSync client and writes it back to the source MongoDB database.
+
+## Setup
+
+### 1. Generate key pair
+Before using the serverless functions you need to generate a public/private key pair. Do the following to generate the key pair:
+1. Open the `generate_keys` CloudCode task.
+2. Select the **Test CloudCode Task** button at the top right. This will print the public and private key in the task logs window.
+
+
+
+3. Copy and paste the `POWERSYNC_PUBLIC_KEY` and `POWERSYNC_PRIVATE_KEY` to a file — we'll need this in the next step.
+
+
+ This step is only meant for testing and development because the keys are shown in the logs files.
+ For production, [generate a key pair locally](https://github.com/powersync-ja/powersync-jwks-example?tab=readme-ov-file#1-generate-a-key-pair) and move onto step 2 and 3.
+
+
+### 2. Configure a deployment
+Before using the tasks, we need to configure a deployment.
+1. At the top of the IDE, select the `Deployments` option.
+2. Create a new deployment by selecting the `+` icon at the top right, _or_ use the default `Testing` deployment. You can configure different deployments for different environments.
+3. Now select the `Deployment settings` button for the instance.
+4. In the `Deployment settings` - `General` tab, capture a `Domain` value in the text field. The application will validate the domain name to make sure it's available.
+5. Select `Save`.
+6. Deploy the deployment: you can do so by selecting the `Deploy app` button, which can be found on the far right for each of the deployments you have configured. After the deployment is completed, it will take a few minutes for the domain to be available.
+7. Your new domain will be available at `.poweredbyjourney.com`. Open the browser and navigate to the new domain. You should be presented with `Cannot GET /`, because there is no index route.
+
+### 3. Configure environment variables
+To add a new variable, do the following:
+1. Head over to the `Deployment settings` option again.
+2. Select the `Environment Variables` tab.
+
+
+
+3. Capture the variable name in the `Name` text field.
+4. Capture the variable value in the `Value` text field.
+5. (Suggested) Check the `Masked` checkbox to obfuscate the variable value for security purposes.
+6. Repeat until all the variables are added.
+
+To finalize the setup, do the following:
+1. Select the `Save` button. This is important, otherwise the variables will not save.
+2. Deploy the deployment: you can do so by selecting the `Deploy app` button.
+
+To wrap up the deployment, we need to configure the environment variables. The following variables need to be set on the deployment:
+* `POWERSYNC_PUBLIC_KEY` - This is the `POWERSYNC_PUBLIC_KEY` from the values generated in step 1.
+* `POWERSYNC_PRIVATE_KEY` - This is the `POWERSYNC_PRIVATE_KEY` from the values generated in step 1.
+* `MONGO_URI` - This is the MongoDB URI e.g. `mongodb+srv://:@/`
+* `POWERSYNC_URL` - This is the public PowerSync URL that is provided after creating a new PowerSync instance.
+
+### 4. Test
+Open your browser and navigate to `.poweredbyjourney.com/jwks`.
+You must set the JWKS url during to configure the PowerSync instance.
+If the setup was successful, the `jwks` task will render the keys in JSON format. Make sure the format of your JWKS keys matches the format [in this example](https://hlstmcktecziostiaplz.supabase.co/functions/v1/powersync-jwks) JWKS endpoint.
+
+## Usage
+Make sure you've configured a deployment and set up environment variables as described in the **Setup** steps before before using the API.
+
+### Token
+You would call the `token` HTTP API endpoint when you implement the `fetchCredentials()` function on the client application.
+Send a HTTP GET request to `.poweredbyjourney.com/token?user_id=` to fetch a JWT for a user. You must provide a `user_id` in the query string of the request, as this is included in the JWT that is generated.
+
+The response of the request would look like this:
+```json
+{"token":"..."}
+```
+
+### JWKS
+The `jwks` HTTP API endpoint is used by PowerSync to validate the token returned from the `.poweredbyjourney.com/token` endpoint. This URL must be set in the configuration of your PowerSync instance.
+Send an HTTP GET request to `.poweredbyjourney.com/jwks`.
+
+An example of the format can be found using [this link](https://hlstmcktecziostiaplz.supabase.co/functions/v1/powersync-jwks).
+
+### Upload
+You would call the `upload` HTTP API endpoint when you implement the `uploadData()` function on the client application.
+Send an HTTP POST request to `.poweredbyjourney.com/upload`.
+The body of the payload should look like this:
+```
+{
+ "op": "PUT",
+ "table": "lists",
+ "id": "61d19021-0565-4686-acc4-3ea4f8c48839",
+ "data": {
+ "created_at": "2024-10-31 10:33:24",
+ "name": "Name",
+ "owner_id": "8ea4310a-b7c0-4dd7-ae54-51d6e1596b83"
+ }
+}
+```
+
+The API will respond with HTTP status `200` if the write was successful.
+
+## Modifying and making changes
+
+If you need to make changes to the way the `upload` task writes data to the source MongoDB database, do the following:
+
+1. Open the `CloudCode` section at the top of the IDE.
+2. Select and expand the `upload` task in the panel on the left.
+3. The `index.ts` contains the entry point function that accepts the HTTP request.
+4. The `persister.ts` file connects to the MongoDB database and writes the data to the MongoDB database. You can update this file to introduce your database schema, etc.
+
+Example MongoDB database schema setup:
+```typescript
+/**
+* Line 13 in upload/persister.ts
+* Sample schema using to-do list demo. Update this based on your DB schema.
+*/
+export const schema = {
+ lists: {
+ _id: types.string,
+ created_at: types.date,
+ name: types.string,
+ owner_id: types.string
+ },
+ todos: {
+ _id: types.string,
+ completed: types.boolean,
+ created_at: types.date,
+ created_by: types.string,
+ description: types.string,
+ list_id: types.string,
+ completed_at: types.date,
+ completed_by: types.string
+ }
+};
+```