Schema-Generated Types
Keeps database schema changes aligned with generated types and their consuming application code.
Scenario
You maintain an application where TypeScript types are generated from an authoritative schema.
For example:
database schema
↓
type generator
↓
generated TypeScript types
↓
application code
The generated types are committed so application code can consume them.
Agents should not manually modify generated types when the underlying schema changes.
Repository Structure
application/
├── src/
│ ├── generated/
│ │ └── database.types.ts
│ ├── repositories/
│ └── features/
├── supabase/
│ └── migrations/
├── scripts/
│ └── generate-db-types.ts
├── package.json
└── AGENTS.md
AGENTS.md
# Project Instructions
## Generated Types
- Treat `src/generated/database.types.ts` as generated output.
- Do not manually edit generated database types.
- Make database schema changes through the repository migration workflow.
- Regenerate types after applying relevant schema changes.
## Type Generation
Use:
- `pnpm generate:db-types`
Run generation against the repository's intended development/test schema according to the existing workflow.
## Application Types
- Use generated database types for database-shaped data where appropriate.
- Keep domain or UI-specific types outside the generated file.
- Do not modify generated types to represent application-only concepts.
## Validation
After schema/type generation changes:
- inspect the generated diff;
- run `pnpm typecheck`;
- run relevant repository tests;
- update application code affected by legitimate schema changes.
What This Does
This separates:
database representation
from:
application representation
Suppose generated types contain:
export type UserRow = {
id: string;
email: string;
created_at: string;
};
The UI needs:
type UserCardViewModel = {
displayName: string;
joinedAt: Date;
};
The correct response is not to add those fields manually to the generated database type.
Instead, application code can define its own type and transform database data into that representation.
What This Does NOT Do
The instructions do not say generated database types must be used everywhere.
A database row type and a domain type can have different purposes.
For example:
Database
created_at: string
Domain
createdAt: Date
UI
joinedLabel: string
Trying to make one generated type represent all three layers can create unnecessary coupling.
The instructions also do not prevent application-specific extension through normal TypeScript composition.
Why These Instructions Matter
Generated type files are especially tempting to edit because the compiler may be reporting an error.
Suppose application code expects:
user.avatar_url
but the generated schema type does not contain that field.
An agent might add:
avatar_url: string | null;
to the generated type.
The type error disappears.
But one of two problems probably exists:
The database schema is missing the field
or:
The application assumption is wrong
Editing the generated type hides the inconsistency rather than resolving it.
Key Decisions
Generated types describe their source
Database-generated types should reflect the database schema.
They should not be manually adjusted to satisfy unrelated application assumptions.
Domain types can differ
It is healthy for application/domain types to represent concepts differently from raw persistence types.
Regenerate after schema changes
A schema migration can legitimately cause generated types to change.
That diff should then guide required application updates.
Type errors can reveal schema drift
Do not automatically silence them.
Investigate whether source schema and application expectations have diverged.
When to Use This Pattern
Use this pattern when:
- database or API schemas generate TypeScript types;
- generated types are committed;
- schema evolution affects application code;
- developers sometimes need richer domain types;
- generated output can be mistaken for normal source.
The key distinction is:
generated types describe a source system; application types describe application concepts.