Summary
All TypeORM entity properties, domain type interfaces, and HTTP API responses currently use snake_case naming (e.g. realm_id, created_at). This should be migrated to camelCase (realmId, createdAt) to follow JavaScript/TypeScript conventions.
Snake_case should only exist in database column names (via TypeORM decorators) and migration files.
Motivation
- Consistent naming across all TypeScript code
- No mixed
snake_case/camelCase conventions leaking across layers
- Domain types serve as the single source of truth for both internal entity shape and external API contract — they must match the API wire format
Approach
Phase 0 — TypeORM naming strategy
Add a SnakeNamingStrategy to the DataSource config so TypeORM automatically maps camelCase entity properties to snake_case DB columns. Zero functional change — enables all subsequent work.
Phase 1 — Domain type interfaces
Rename shared domain interfaces (e.g. Permission, Role, User) to camelCase. One domain at a time, fixing all consumers before moving to the next.
Phase 2 — TypeORM entity classes
Rename entity properties to camelCase. With the naming strategy, most @Column() decorators need no name: override. Keep @JoinColumn({ name: '...' }) explicit.
Phase 3 — All consumers
Update query builders, repositories, services, controllers, subscribers, validators, and tests.
Phase 4 — HTTP API
Switch API responses and request bodies to camelCase. This is a breaking change — coordinate with a major version bump.
Phase 5 — Validators
Update validator field mounts from snake_case to camelCase.
Execution
Best done entity-by-entity alongside other refactoring work to avoid a single massive PR. Add the naming strategy first, then rename each entity incrementally.
Breaking change
This is a breaking change for API consumers. Provide a migration guide with the release.
Not in scope
- Database column names (stay
snake_case forever)
- Migration files (frozen, reference column names)
Reference
Same approach as authup/authup — see .agents/plans/camelcase-entity-properties.md for the detailed plan.
Summary
All TypeORM entity properties, domain type interfaces, and HTTP API responses currently use
snake_casenaming (e.g.realm_id,created_at). This should be migrated tocamelCase(realmId,createdAt) to follow JavaScript/TypeScript conventions.Snake_case should only exist in database column names (via TypeORM decorators) and migration files.
Motivation
snake_case/camelCaseconventions leaking across layersApproach
Phase 0 — TypeORM naming strategy
Add a
SnakeNamingStrategyto the DataSource config so TypeORM automatically mapscamelCaseentity properties tosnake_caseDB columns. Zero functional change — enables all subsequent work.Phase 1 — Domain type interfaces
Rename shared domain interfaces (e.g.
Permission,Role,User) to camelCase. One domain at a time, fixing all consumers before moving to the next.Phase 2 — TypeORM entity classes
Rename entity properties to camelCase. With the naming strategy, most
@Column()decorators need noname:override. Keep@JoinColumn({ name: '...' })explicit.Phase 3 — All consumers
Update query builders, repositories, services, controllers, subscribers, validators, and tests.
Phase 4 — HTTP API
Switch API responses and request bodies to camelCase. This is a breaking change — coordinate with a major version bump.
Phase 5 — Validators
Update validator field mounts from snake_case to camelCase.
Execution
Best done entity-by-entity alongside other refactoring work to avoid a single massive PR. Add the naming strategy first, then rename each entity incrementally.
Breaking change
This is a breaking change for API consumers. Provide a migration guide with the release.
Not in scope
snake_caseforever)Reference
Same approach as authup/authup — see
.agents/plans/camelcase-entity-properties.mdfor the detailed plan.