# AI Development Guide

This workspace is an Akan.js project. Keep business intent in source files and let `akan sync` regenerate the
repeated surfaces.

## Domain Module Shape

- `apps/<app>/lib/<model>` is for database-backed domain modules.
- `apps/<app>/lib/_<service>` is for service modules without their own database document.
- `apps/<app>/lib/__scalar/<scalar>` is for reusable embedded value shapes.
- Put model behavior in the local module before creating a parallel architecture.

## Data Flow

Follow this order for domain changes:

1. `constant` defines fields, enums, and model layers.
2. `document` defines queries, filters, and document state transitions.
3. `service` owns business workflows and orchestration.
4. `signal` exposes typed endpoints, slices, and internal jobs.
5. `store` owns reusable client workflow state and actions.
6. UI files render forms, lists, details, and actions.

## When To Run Sync

Run this after adding, deleting, or renaming module, UI, webkit, srvkit, or common files:

```bash
akan sync <%= appName %>
```

Sync regenerates barrels such as `cnst.ts`, `db.ts`, `srv.ts`, `sig.ts`, `st.ts`, `useClient.ts`, `useServer.ts`,
and module `index.ts` files. Without sync, imports can point at stale generated files.

## Generated Files

Do not hand-edit generated Akan files. Edit source files in the owning module and run sync or build instead.
See `docs/GENERATED.md` for the generated file list.

## Server And Client Boundary

- Keep server-only APIs such as `fs`, `Bun`, secrets, database adaptors, and server env access out of client code.
- Client surfaces include `ui/`, `webkit/`, `*.Template.tsx`, `*.Zone.tsx`, and `*.Util.tsx` files that use
  `"use client"`.
- Server-oriented surfaces include pages, `*.Unit.tsx`, `*.View.tsx`, `lib/`, `srvkit/`, and server entrypoints.
- Treat `AKAN_PUBLIC_*` values as public.

## House Style

`AGENTS.md` holds the full style guide, and `akan lint` enforces most of it. The four rules that surprise people,
because the failure is silent rather than an error:

- **Never hand-order Tailwind classes** — the linter sorts them, including inside `cn()`, and its output looks
  unnatural on purpose. Do not reorder it back.
- **Never use a colour outside the semantic vocabulary** — `bg-red-500`, `bg-[#3b82f6]` and `text-base-content`
  compile to no CSS at all, so the element renders unstyled with no error. Use `bg-primary`, `text-foreground/70`
  and the other tokens defined in `page/*/styles.css`.
- **`cond ? <X/> : null`, never `{cond && <X/>}`** — the latter renders the string `"false"` in a className context.
- **Never wrap a form setter in a pass-through arrow** — `onChange={st.do.setXOnY}` publishes the field to agents
  and E2E selectors; `onChange={(v) => st.do.setXOnY(v)}` runs identically and publishes nothing.

Two more that are hard errors: **never `throw new Error`** (throw `new Err("<module>.error.<key>")` with an
`[en, ko]` dictionary entry), and **never import a third-party package** from a page, a barrel, or a module file —
re-export it through a one-line shim in the lib's `common/`, `webkit/`, or `ui/` first.

## Abstract Documents

Update `*.abstract.md` when business invariants, workflows, user-visible behavior, cross-module relationships, or
agent guidance changes. Do not update it for purely mechanical formatting or regenerated file changes.
