# Your schema, your components, four screens

A real Cal.com Prisma schema becomes a small Membership workspace: a filterable list, a record detail, an editable form and a timeline. The same workflow generates React and Vue applications using accepted components from two public shadcn projects.

These are **generated sample records**, not Cal.com customer data. This five-minute walkthrough shows what to ask, what to review, and the result. Reproducing it also takes time to download and install the example projects.

![React Membership detail in dark mode](images/react-detail-1440-dark.png)

[See every screen in React and Vue, light and dark](screenshots.md) · [Watch the short screen recording](images/membership-workflow.gif)

## 1. Connect the local tool

With Node.js 22 or newer and Claude Code installed:

```sh
claude mcp add oods-foundry -- npx -y @oods/foundry@0.11.2
```

Restart Claude Code in a scratch workspace. Download the [pinned Prisma schema](https://raw.githubusercontent.com/calcom/cal.com/54343aa685ae8f33159d2f485ec4a57bad5c574a/packages/prisma/schema.prisma) into it. The importer reads that local file; it never connects to a database.

Use your own shadcn project, or scratch copies of the [React](https://github.com/satnaing/shadcn-admin/tree/e16c87f213a5ba5e45964e9b67c792105ec74d26) and [Vue](https://github.com/Whbbit1999/shadcn-vue-admin/tree/303cf63f6c8ecdd43408ae991c904daa2aad2dd8) examples used here. Keep their manifests, aliases, CSS and installed dependencies. Before asking OODS Foundry to apply adapters, install its libraries **in the component project**:

```sh
npm install @oods/components-react@0.11.2 @oods/component-contracts@0.11.2 @oods/component-styles@0.11.2 @oods/tokens@0.11.2
```

For Vue, replace `@oods/components-react` with `@oods/components-vue` at the same version. For the pinned Vue example, add `--legacy-peer-deps` to this component-project install to accommodate its upstream Vite plugin’s peer range. Generated app installs use plain `npm install`. The MCP connection does not install these project dependencies. See [the component guide](../../packages/foundry/COMPONENTS.md) for supported project layouts.

## 2. Ask for a draft, then inspect it

> Read this Prisma schema with OODS Foundry. Show me the objects, the traits you propose and why, and what you could not read. Inspect Membership in detail. Do not apply it yet.

The assistant calls `object_import` with `action: "draft"` and `source: {path: "<schema.prisma>", format: "prisma"}`. Drafting saves a reviewable import. It calls `object_import_read` with `action: "show"`, the returned `importId`, and `object: "Membership"` to inspect that record's definition, samples and proposals.

Our draft contained **102 objects** and **183 valid trait proposals**: 69 strong and 114 medium. It also reported unsupported source elements and relationship cycles. Review the report; an import does not reproduce every Prisma constraint.

Membership has no name field. Its title joins its required Team and User references, such as “Design · Elena Novak”; the list uses the same title. References read “Team”, “User” and “Custom Role” in both detail and form. Stored enum values remain `OWNER`, `ADMIN` and `MEMBER`, while the screens show Owner, Admin and Member. We accept Timestampable for the declared dates. We decline Stateful because these are roles, not lifecycle states, and decline Ownerable because its proposed field bindings are empty. No status-history panel is shown without events.

For money, a decimal called `total` is not enough. At acceptance, explicitly declare a currency sibling with `currencies: {total: {field: "currency"}}`; add `minorUnits: 100` only if the amount uses minor units. See [importing objects](../../packages/foundry/IMPORTING-OBJECTS.md).

## 3. Accept reviewed objects and component mappings

> For this scratch demo, apply all 102 object definitions so their references resolve. Accept only Membership’s Timestampable proposal; leave the other trait proposals unaccepted. Confirm replacing the shipped User definition with the reviewed Cal.com User definition: Membership’s integer user references need that definition. Then draft mappings from my local shadcn project and show what is supported before applying them.

`object_import` applies an explicit `objects: [{name, proposals: ["<proposal-id>"]}]` selection. Use an empty proposals array for a definition without accepted traits. Confirming the User-name overlap with `confirmShipped: ["User"]` permits that team definition; review its identity and relationships deliberately.

`component_map` drafts with `source: {project: "<absolute project folder>", format: "shadcn"}`. Inspect the result through `component_map_read`, then approve the chosen proposal IDs with `component_map` `action: "apply"`, `draftId` and `accept`. Those actions do not take an extra `apply: true` flag.

We accepted 14 React adapters and 16 Vue adapters. These are proposals based on structural evidence, not behavioral certification. The source-record counts in the draft are different from the number of adapters. Unmapped components keep their OODS implementations; React's pagination is one example in this run.

## 4. Compose, preview and generate

> Compose Membership as list, detail, form and timeline. Create a workflow from those screens, preview it, then generate complete React and Vue applications with the accepted components. Save the returned files unchanged.

| Purpose | Tool call |
|---|---|
| Compose each screen | `design_compose {object: "Membership", context: "list"}`; repeat with `detail`, `form`, `timeline`, then `workflow` |
| Open the running preview | `design_preview {compositionId: "<returned id>", action: "render"}` |
| Inspect saved versions | `design_versions {compositionId: "<returned id>"}` |
| Generate an application | `code_generate {schemaRef: "<workflow ref>", framework: "react", profile: "build", options: {output: "application", payloadMode: "file"}}`; repeat for `vue` |

Copy the returned payload files to separate app folders and follow each generated README:

```sh
npm install
npm run build
npm run dev
```

Generated apps pin the OODS release that generated them; to upgrade, regenerate the app or move all four pins together.

![Vue Membership form on a phone](images/vue-form-390-light.png)

## What happened in the recorded run

The original Claude Code conversation used a fresh profile and an empty npm cache with the 0.11.1 candidate. `brand_read template` fit inline with all three themes. <!-- history -->

For 0.11.2, we replayed the same pinned sources and accepted choices, regenerated both applications, and installed the four matching packed release libraries in each. No imported objects, samples, composed schemas or generated files were hand-edited. The screenshots show those rebuilt apps. The existing React recording is retained: all eight route/theme views were recaptured and visually compared, and its displayed content and layout are unchanged.

The first incomplete object selections were refused atomically because their relationship targets were missing. The successful batch applied 101 definitions but kept the shipped UUID-based User, leaving Cal.com’s integer user references unresolved. A continuation accepted the reviewed Cal.com User definition with no traits, for 102 imported definitions in total. The only accepted trait is Membership’s Timestampable. Two component-mapping calls also supplied an unsupported `apply: true`; both were refused and corrected. The prompts above describe the final accepted choices, not every attempted call.

Both apps passed their TypeScript checks and production builds. We exercised all four routes in both frameworks at 1440 and 390 pixels, in light and dark: 32 screenshots inspected, no page errors or overflow, and no axe WCAG 2.2 A/AA violations. Role filtering reduced five rows to two and reset to five; changing a role, related record and checkbox survived saving and reopening the form. The timeline uses the record's created/updated dates and has no false missing-extension warning. Vue timeline entries now have the same measured 16 px inner padding as React; other screens retain their layout.

The component contract reports still describe adapter limitations. Passing these example interactions is not certification of a whole application. The timeline shows the declared timestamp events; roles remain roles, without a status-history panel. [Run identities and image hashes](run.json) identify the original conversation, current candidate capture and retained recording.

## Sources and licenses

- [Cal.com Prisma schema](https://github.com/calcom/cal.com/blob/54343aa685ae8f33159d2f485ec4a57bad5c574a/packages/prisma/schema.prisma), commit `54343aa685ae8f33159d2f485ec4a57bad5c574a`; the pinned repository [license](https://github.com/calcom/cal.com/blob/54343aa685ae8f33159d2f485ec4a57bad5c574a/LICENSE) is MIT.
- [shadcn-admin](https://github.com/satnaing/shadcn-admin/tree/e16c87f213a5ba5e45964e9b67c792105ec74d26), React, MIT.
- [shadcn-vue-admin](https://github.com/Whbbit1999/shadcn-vue-admin/tree/303cf63f6c8ecdd43408ae991c904daa2aad2dd8), Vue, MIT.

Third-party source stays in the scratch projects. This walkthrough distributes OODS Foundry's text, generated sample-screen images and run metadata. The schema and component authors do not endorse this demo.
