3.8 KiB
Teable v2 agent guide
DDD/domain-model guidance has moved to the skill teable-ddd-domain-model in .codex/skills/teable-ddd-domain-model. Use that skill for any v2/core domain, specification, or aggregate changes.
Git hygiene
- Ignore git changes that you did not make by default; never revert unknown/unrelated modifications unless explicitly instructed.
v2 API contracts (HTTP)
For HTTP-ish integrations, keep framework-independent contracts/mappers in packages/v2/contract-http:
- Define API paths (e.g.
/tables) as constants. - Use action-style paths with camelCase action names (e.g.
/tables/create,/tables/get,/tables/rename); avoid RESTful nested resources like/bases/{baseId}/tables/{tableId}. - Re-export command input schemas (zod) for route-level validation if needed.
- Keep DTO types + domain-to-DTO mappers here.
- Router packages (e.g.
@teable/v2-contract-http-express,@teable/v2-contract-http-fastify) should be thin adapters that only:- parse JSON/body
- create a container
- resolve handlers
- call the endpoint executor/mappers from
@teable/v2-contract-http
- OpenAPI is generated from the ts-rest contract via
@teable/v2-contract-http-openapi.
UI components (frontend)
- In app UIs (e.g.
apps/playground), use shadcn wrappers fromapps/playground/src/components/ui/*(or@teable/ui-lib) instead of importing Radix primitives directly. - If a shadcn wrapper is missing, add it under
apps/playground/src/components/uibefore using the primitive.
Dependency injection (DI)
- Do not import
tsyringe/reflect-metadatadirectly anywhere; use@teable/v2-di. - Do not use DI inside
v2/core/src/domain/**; DI is only for application wiring (e.g.v2/core/src/commands/**). - Prefer constructor injection with explicit tokens for ports (interfaces).
- Provide environment-level composition roots as separate packages (e.g.
@teable/v2-container-node,@teable/v2-container-browser) that register all port implementations.
Build tooling (v2)
- v2 packages build with
tsdown(nottscemit).tscis used only fortypecheck(--noEmit). - Each v2 package has a local
tsdown.config.tsthat extends the shared base config from@teable/v2-tsdown-config. - Outputs are written to
dist/(ESM.js+.d.ts), and workspace deps (@teable/v2-*) are kept external (no bundling across packages).
Source visibility (v2 packages)
All v2 packages must support source visibility to allow consumers to reference TypeScript sources without building dist/ outputs. This is required for development workflows, testing, and tools like Vitest/Vite that can consume TypeScript directly.
Required configuration:
- In
package.json:- Set
typesfield to"src/index.ts"(not"dist/index.d.ts") - Set
exports["."].typesto"./src/index.ts"(not"./dist/index.d.ts") - Set
exports["."].importto"./src/index.ts"(not"./dist/index.js") to allow Vite/Vitest to use source files directly - Keep
exports["."].requirepointing to"./dist/index.cjs"for CommonJS compatibility - Include
"src"in thefilesarray (in addition to"dist")
- Set
- In
tsconfig.json:- Map workspace dependencies to their
srcpaths incompilerOptions.paths(e.g."@teable/v2-core": ["../core/src"]) - Include those source paths in the
includearray
- Map workspace dependencies to their
Example package.json configuration:
{
"types": "src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"import": "./src/index.ts",
"require": "./dist/index.cjs"
}
},
"files": ["dist", "src"]
}
Note: Since v2 packages are workspace-only ("private": true) and not published to npm, pointing import to source files is safe. Vite/Vitest can process TypeScript files directly, enabling faster development cycles without requiring dist/ to be built first.