# Tutorial: Develop with a SuperRepo :::callout{theme="neutral" title="Beta"} SuperRepo is in the [beta](../../platform-overview/development-life-cycle/index.md) phase of development and may not be available on your enrollment. Functionality may change during active development. ::: SuperRepos provide the most value when leveraged for full-stack application building, because a SuperRepo enables editing, previewing, and deploying components in lock-step. This tutorial uses the task management application included in the default SuperRepo template. You will learn how to import an existing [object type](../../ontology/overview/index.md#object-and-link-types) and explore the template's link type. You will also connect a [function-backed action](../../action-types/function-actions-overview/index.md) to the frontend to mark tasks as complete. The same development workflow applies to full-stack applications in every domain. To follow along, [create a SuperRepo](../create-a-superrepo/index.md) using the repository creation flow and start its local preview. The template already defines tasks, workers, and the function shown below. Its in-application tutorial guides you through extending these definitions and connecting them to the frontend. Start by looking at the structure of a SuperRepo repository. The root always contains a `foundry.yml` file which lays out the project's components. For example, among other settings, it might have the following: ```yaml components: - type: ONTOLOGY path: ./ontology - type: TYPESCRIPT_FUNCTIONS path: ./functions/typescript-functions - type: APP path: ./app ``` Components can be added, duplicated, or removed from this file to change the shape of your project. [Advanced workflows](../advanced-workflows/index.md#restructure-a-superrepo) provides further details on restructuring workflows. In the following sections, you will work across three layers: 1. Explore importing and defining [Ontology](#expand-the-ontology) types and update task assignments in the seed data. 2. Understand how to write a [TypeScript function](#add-a-function) and its function-backed action. 3. Connect the action to the [application](#expose-the-action-through-the-frontend) frontend. ## Import an existing object type The domain model of a full-stack application within the Palantir platform is defined in the Ontology. In a SuperRepo, existing Ontology types can be imported into the project either by running the `foundry import ontology` command or by using the **Import** sidebar of the [Palantir extension for Visual Studio Code](../../palantir-extension-for-visual-studio-code/overview/index.md). The Import sidebar in the Palantir extension for Visual Studio Code. The wizard then guides you through selecting the type you wish to import. ![The import wizard showing a Worker object type selected for import.](../../../assets/2dc471e3a1e6e297594e631e398d7950bba3fc90448b3fb1d322c5d8927bc3f7.webp) Lastly, selecting the **Import to project** button imports the selected types into the Foundry Project and shows the `foundry import ontology` command that you need to run to codify the import within your repository. ![The import confirmation showing the foundry import ontology command for the Worker object type.](../../../assets/68f7e3b18c5590315ffeae00caec4260698ce1b295906933ea4185c4da2febe4.webp) ## Expand the Ontology The `ontology/src/ontology.mts` file is the home of [Ontology-as-code](../core-concepts/index.md#ontology-as-code), which lets you extend the Ontology using its [TypeScript API ↗](https://github.com/palantir/osdk-ts/blob/main/packages/maker/README.md). For example, the template defines a link type between `TutorialWorker` and `TutorialTask`. Each worker can have many assigned tasks, and each task can have one assignee. The following definition is already included in the template: ```typescript export const assignedTasks: LinkType = defineLink({ apiName: "assignedTasks", one: { object: TutorialWorker, metadata: { apiName: "assignedTasks" }, }, toMany: { object: TutorialTask, metadata: { apiName: "assignee" }, }, manyForeignKeyProperty: "assigneeId", editsEnabled: true, }); ``` :::callout{theme="danger"} Editing seed data resets the local preview data, discarding any objects you created and reverting changes to the seed objects. Seed data is local to the preview and is never deployed.

The `assigneeId` property on a task holds its worker's primary key. To assign the unassigned task in the local preview, add `assigneeId: "WORKER-1"` to `TASK-103` in `ontology/seed/001-tasks.mts`. Both object types are seeded in that file. ::: Whenever the `ontology.mts` file changes, the local [Ontology SDK](../../ontology-sdk/overview/index.md) package is regenerated. You can track the rebuild progress in the status display shown by `pnpm run dev` (`pnpm run dev:windows` on Windows), and inspect the `ontology:dev` output using the `Tab` and arrow keys. ![The local preview status display showing the Ontology rebuilding while the other components are ready.](../../../assets/3c65383726ed613c99973543dfe0b2702f0cd793dd652d0d523130aa2bd97ad6.webp) ## Add a function SuperRepos currently support [TypeScript v2 functions](../../functions/typescript-v2-getting-started/index.md). The template uses a function to mark a task as complete and prevent it from being completed twice. Open `completeTask.ts` in `functions/typescript-functions/src/functions`. The function it contains takes an Ontology SDK client and a task as arguments and returns an edit that updates the task's status. ```typescript import { task } from "@ontology/sdk"; import { Client, Osdk } from "@osdk/client"; import { createEditBatch, Edits, UserFacingError } from "@osdk/functions"; export const COMPLETE = "Complete"; type OntologyEdit = Edits.Object; function completeTask( client: Client, taskToComplete: Osdk.Instance, ): OntologyEdit[] { if (taskToComplete.status === COMPLETE) { throw new UserFacingError( `${taskToComplete.title ?? taskToComplete.$primaryKey} is already complete`, ); } const batch = createEditBatch(client); batch.update(taskToComplete, { status: COMPLETE }); return batch.getEdits(); } export const config = { apiName: "completeTask", }; export default completeTask; ``` The Ontology SDK exports `task` and `worker` from the object types' `apiName` values, rather than the `TutorialTask` and `TutorialWorker` constant names used in `ontology.mts`. You can preview this function immediately using the functions support of the [Palantir extension for Visual Studio Code](../../palantir-extension-for-visual-studio-code/overview/index.md). ![The function preview returning an edit that sets a task's status to Complete.](../../../assets/c3fab62ea0e7510f335c9f6d1a3126ecf1998382c8845c828cb0601a0e926c72.webp) This TypeScript v2 function returns Ontology edits; however, these edits need to be applied to the Ontology to take effect. Only actions are allowed to mutate the Ontology's content. To update a task's status, expose `completeTask` as a [function-backed action](../../action-types/function-actions-overview/index.md). The template already exposes this function inside the same `ontology.mts` file that defines the link type by calling the `defineFunctionBackedAction` function as follows: ```typescript export const completeTaskAction: ActionType = defineFunctionBackedAction({ functionApiName: "completeTask", apiName: "complete-task-action", }); ``` This allows you to call `completeTaskAction` through the generated Ontology SDK from inside your React application. ## Expose the action through the frontend The previous sections demonstrated importing an object type, creating a link type, and defining a TypeScript v2 function-backed action. The preview process of the Foundry CLI ensures that these are all exposed through the locally generated Ontology SDK library. You can consume this library from an [Ontology SDK React application](../../ontology-sdk-react-applications/overview/index.md). When using the `@osdk/react` [library ↗](https://palantir.github.io/osdk-ts/react/getting-started/), accessing these newly added items can be done in a few lines, as shown below. ```typescript import { task, completeTaskAction } from "@ontology/sdk"; import { useOsdkAction, useOsdkObjects, } from "@osdk/react"; const { data: tasks } = useOsdkObjects(task, { pageSize: 50 }); const completeAction = useOsdkAction(completeTaskAction); ``` These hooks are already called inside the `Demo` component in `app/src/tutorial/Demo.tsx`. To enable its **Mark as complete** buttons, remove the comment markers around the handler in `getCompleteHandler` and remove `return null`: ```typescript function getCompleteHandler(): | ((taskToComplete: Osdk.Instance) => Promise) | null { return async (taskToComplete) => { await completeAction.applyAction({ taskToComplete }); }; } ``` In the running preview application, select **Add your own logic** in the tutorial navigation. Under **Live preview**, select **Mark as complete** on an incomplete task. Its status changes to **Complete**. Select **Define object relationships** in the tutorial navigation to view each worker's assigned tasks. This view uses `useLinks(item, "assignedTasks", { pageSize: 50 })` to follow the link defined above. ## Conclusion You updated the task assignments, explored a function and its function-backed action, and integrated it with the frontend through the Ontology SDK, all without leaving the repository or your IDE. Before SuperRepos, implementing this feature would have required jumping between four applications, waiting for CI checks, and republishing the Ontology SDK multiple times. SuperRepos are designed to eliminate that overhead. ## Next steps * Review [Advanced workflows](../advanced-workflows/index.md) to declare multiple products, define seed data for preview, or configure the platform API proxy. * [Prepare for your first deployment](../prepare-first-deploy/index.md) to install your product on an enrollment.