# @cake20/runtime AI Reference

## Execution boundary

Website source uses Runtime globals regardless of where work executes. Runtime may
forward standard generated `db` delegates, array-form `$transaction`, DB metering,
ZIP transformations, and XLSX parsing or serialization to `@cake20/worker`. Runtime
keeps the public row-based `excel` API and storage access. Local CLI starts
Worker automatically; production connects through Core's private local IPC. Do not
import Worker or use an internal Worker address from website source.

Core's private Provider executes AI, Playwright-backed MCP browser checks, and external
integrations outside Core. Website Runtime receives only its authenticated mail,
messaging, and payment contracts; Provider is not a website global or configuration.
Interactive transactions and raw Prisma methods are explicit migration cases, not
transparent Worker operations.

## Resolution rule

Do not import Runtime globals. Runtime injects their values and types. Import only an
explicit browser module or type when the current declarations require it.

## Common globals

- `project`: every public Cake20 setting in `package.json`.
- `app`: current website identity, URL, Runtime, timezone, and database metadata.
- `db`: generated Prisma-style model clients and registered `db.sql` functions.
- `z`: schema builder for API input and database field definitions.
- `auth`: built-in login, session identity, authorization, and logout.
- `storage`: persistent website file operations.
- `job`: generated queue calls plus `job.$get(id)`.
- `mail`: configured SMTP sending.
- `telegram`: connected owner alert state and sending.
- `gmail`: connected owner Gmail alert state and sending.
- `payment`: configured Toss, Stripe, or PayPal operations.
- `excel`: read first-sheet rows, return immediate single-sheet XLSX downloads, or
  persist simple row data as XLSX through storage.
- `zip`: pack, unpack, read, and save ZIP data through storage.
- `form`: validated form helpers exposed by Runtime.
- `api`, `$fetch`, `fetchGet`, `fetchPost`: browser HTTP request helpers. `api` is the
  concise default for Cake20 View source.
- `now`, `toDate`, `textDate`, `startOfToday`: date helpers.

Use the installed `@cake20/runtime/src/globals.d.ts` and exported declarations for
exact signatures and availability.

## package.json

Use one valid JSON object as the visible source of Cake20 settings, public metadata,
and website dependencies. Runtime keeps `name`, `private`, `type`, and
`packageManager` normalized. Before the first remote deployment, `name` may be a local
package name. Cake20 Core assigns a `web-` ID on the first deployment and the CLI saves
that ID as the system-managed `name`. Do not add or edit a separate `id` field.

Known platform fields:

- `title`, `description`, `image`, `lang`, `favicon`: metadata.
- `timezone`: IANA timezone.
- `mode`: `auto`, `static`, or `fullstack` website execution mode.
- `data`: `auto`, `local`, or `server`.
- `device`: `desktop`, `tablet`, or `mobile`.
- `orientation`: `landscape` or `portrait`.
- `dependencies`: direct external website packages when enabled.
- `overrides`: transitive dependency constraints when enabled.
- `payment`: payment mode, currency, and enabled providers.

Legacy `project.ts`, `website.ts`, `config.ts`, and `package.ts` settings migrate into
`package.json`. A legacy file is removed only after the package write succeeds.

### Website execution mode

- Missing and empty `mode` values resolve to `auto`.
- AI must inspect the current source whenever it creates or modifies a website.
- Set `mode: "static"` when the website has no own API, file storage, task, queue,
  WebSocket, SSE, database, or other executable `server` source.
- Change `mode` to `fullstack` when adding any such server feature.
- A confirmed static website should not remain on implicit `auto`; explicit `static`
  lets Cake20 serve its built output without a website server process.
- External browser API calls do not by themselves require `fullstack`. Calls to the
  website's own `/api` or `/files` routes do.

## UI contracts

- `app/pages/**/*.tsx`: file-based pages.
- `app/layouts/**/*.tsx`: shared page frames.
- `app/components/**/*.tsx`: auto-imported components.
- `app/components/**/*.client.tsx`: browser-only auto-imported components; `.client`
  does not change the component name.
- `app/composables/**/*.{ts,js}`: auto-imported composables.
- `app/preview/<Model>.json`: Runtime-managed Design Preview rows generated from model
  seeds. Do not add an index or schema metadata file.
- `app/stores/**/<name>.store.ts`: generated `store.<name>` state.
- `app/middleware/**/*.hook.ts`: client navigation hooks.
- `app/assets`: compiled assets and styles.
- `public`: copied public assets.

Use Cake20 View TSX, standard HTML attribute names, and `class` for styles. Do not
write React-specific `className`. Use Cake20 UI components without a prefix inside
website source.

## UI generation and migration checks

- Do not explicitly import a component from `app/components`. Nested folder and file
  names form its PascalCase auto-import name.
- Treat `.client` in `*.client.ts` and `*.client.tsx` as an execution marker. For
  example, call `ScrollMotion.client.tsx` as `<ScrollMotion />`.
- Use `map` only when the value is an array. Convert numeric repetition to
  `Array.from({ length: count }).map(...)`.
- Use `bindName` for a named two-way component value. The child must accept `name`
  and emit `onNameChange` or `onUpdate:name`. Multiple named binds are supported.
- Pass an event function directly or invoke it inside the callback. Never emit a
  callback such as `() => { save; }` that only references the function.
- Runtime globals, Cake20 View globals, and auto-imported components need no import.
  Import only explicit browser libraries and external packages used by the file.
- Use `RouterLink` for Cake20 View routing.
- `DragList` is built in for sorting, cross-list movement, Kanban layouts, and touch
  input. Use it without imports and persist reordered arrays from `onEnd`.
- Validate API response shapes before replacing initialized reactive arrays or objects.
  Do not erase useful Preview defaults with an empty or incompatible mock response.
- Do not reference `data` or another declaration before it is initialized.
- After migration, verify every route and key button, input, named bind, login restore,
  and API error path. A successful first render is not complete migration evidence.

## API and route contracts

- `server/api/users.get.ts` maps to `GET /api/users`.
- `server/api/users.post.ts` maps to `POST /api/users`.
- `server/routes/status.get.ts` maps to `GET /status`.
- A simple handler exports one default function. Do not wrap it in `defineApi` unless
  an installed typed handler signature specifically requires the helper.
- Use `z` and Runtime handler helpers when input validation or typed context is needed.

## Hook contracts

Client route hook:

- File: `app/middleware/<name>.hook.ts`.
- Optional static `config.active` and `config.path`.
- Default function returns nothing, `false` to cancel, or a route to redirect.
- Client hooks improve navigation UX; they do not replace server authorization.

HTTP hook:

- File: `server/hooks/<name>.hook.ts`.
- Default async function handles the request and optional next callback.

## Tasks and jobs

Scheduled task:

- File: `server/tasks/<name>.task.ts`.
- Exports task configuration and a default handler according to installed types.
- Runtime enforces a minimum actual interval of five seconds.

Queued job:

- File: `server/tasks/<name>.job.ts`.
- Exports one default function.
- Call as `job.<name>(input)` and inspect with `job.$get(id)`.
- Queue values must be JSON-compatible and no larger than 64 KB.
- Do not queue simple CRUD, immediate responses, or the first durable payment record.

## Database model rules

- Model: `server/db/<name>.db.ts` exports a plain object of `z` fields.
- View: use `z.view()` only when defining an actual Prisma view.
- Relation: use `z.ref()` across model files.
- Single-field index: `.index()`.
- Advanced model attribute: `.attr("@@index(...)")`.
- Nullable DB column: `.nullable()`; `.optional()` alone is not nullable.
- Timestamp precision zero: `.timestamp()` or `.timestampTz()`.
- Stored password: `z.password().hashFrom("<name>Text")` hashes a virtual plaintext
  field, removes that field from stored output, and is verified with
  `auth.password.verify(...)`. Never expose the hash or plaintext.
- Explicit migrations: `server/db/migrations`.
- Initial rows: `export const seed = async () => {}` in each `*.db.ts` model file.
  Return deterministic rows without calling `db`; use `server/db/seed.sql.ts` only for
  final idempotent initialization that coordinates multiple model seeds.

## Auth contract

- Put page and API access rules in `package.json` `auth`. Values are `true`, one Role,
  a Role array, or `false` for a more-specific public exception. `login` and `denied`
  override the default `/login` and `/403` destinations.
- `auth.login(...)` verifies credentials and returns a cookie to send.
- `auth.user(request)` returns nullable identity.
- `auth.require(request, role?)` returns identity or throws 401/403.
- `auth.logout(request)` returns a clearing cookie.
- Do not inspect or implement Runtime session internals.

## Storage contract

- Use `storage.put`, `get`, `has`, `list`, `browse`, `mkdir`, `rmdir`, `remove`, and
  `url` according to installed declarations.
- Store only website-relative paths.
- Use `storage.url(path)` instead of constructing `/files/` URLs manually.
- Local `files/<path>` objects are publicly routed, so never place private Secrets in
  storage intended for public delivery.

## Excel contract

- `excel.open(path)` reads the first sheet of a persisted XLSX file as rows.
- Rows support strings, numbers, booleans, dates, and empty cells. Workbook objects,
  styling, formulas, and multiple sheets are not supported.
- `excel.download(name, rows)` returns an XLSX download `Response` without writing
  to storage. Prefer it for downloads completed in the current API or route request.
- `name` for `excel.download` is an `.xlsx` file name, not a storage path.
- `excel.save(path, rows)` persists an XLSX file and returns its path, size, and an
  optional public URL. Use it only when the file must be reopened or shared later.
- Worker owns all XLSX parsing and serialization; Runtime retains only rows and paths.
- An asynchronous job cannot return a download to an HTTP request that has already
  ended. Save job output, then overwrite, expire, or remove temporary files according
  to an explicit retention policy.

## Integration constraints

- `telegram.send(text, options?)` sends only to the connected website owner.
- `gmail.send(message)` sends from and to the connected owner account.
- `mail.send(message)` uses configured SMTP and supports explicit recipients.
- `payment` calls require configured providers and encrypted provider Secrets.
- Keep integration calls in server code.
