Toast
ContributorPatterns

Naming Conventions

Naming Conventions

Consistent naming patterns across the Toast codebase.

Files and Directories

TypeConventionExample
Directorieskebab-casemy-feature/
TypeScript fileskebab-casecontent.service.ts
Test fileskebab-casecontent.test.ts
React componentsPascalCaseLoginForm.tsx
Config fileskebab-casevitest.config.ts

File Suffixes

SuffixPurposeExample
.service.tsBusiness logic layercontent.service.ts
.repository.tsData access layercontent.repository.ts
.controller.tsHTTP handlerscontent.controller.ts
.test.tsTest filecontent.test.ts
.integration.test.tsIntegration testcontent.integration.test.ts

TypeScript

ElementConventionExample
VariablescamelCasecontentItems
FunctionscamelCasefindById()
ClassesPascalCaseContentService
InterfacesPascalCaseContentResponse
Type aliasesPascalCaseCreateContentInput
EnumsPascalCaseContentStatus
Enum valuesPascalCaseContentStatus.Published
ConstantsSCREAMING_SNAKE_CASEMAX_RETRIES

Type Naming Patterns

// Response types (returned from services)
interface ContentResponse { ... }

// Input types (received by services)
interface CreateContentInput { ... }

// Database row types (from Drizzle inference)
type ContentRow = typeof content.$inferSelect;
type CreateContentData = typeof content.$inferInsert;

// Zod schema types
type CreateContent = z.infer<typeof CreateContentSchema>;

Database

ElementConventionExample
Table namessnake_caseuser_sessions
Column namessnake_casecreated_at
Index namesidx_{table}_{column}idx_content_site_id
Enum type namessnake_casecontent_status
Enum valuessnake_case'draft', 'published'

Drizzle Schema

Column definitions use snake_case strings, TypeScript uses camelCase:

export const content = pgTable('content', {
  id: uuid('id').defaultRandom().primaryKey(),
  siteId: uuid('site_id').notNull(),        // DB: site_id, TS: siteId
  createdAt: timestamp('created_at', ...),  // DB: created_at, TS: createdAt
});

API

Endpoints

PatternExample
List resourcesGET /api/content
Get single resourceGET /api/content/:id
Create resourcePOST /api/content
Update resourcePUT /api/content/:id
Delete resourceDELETE /api/content/:id
Custom actionPOST /api/content/:id/publish

Response Fields

JSON responses use camelCase:

{
  "id": "uuid",
  "siteId": "uuid",
  "createdAt": "2024-01-01T00:00:00.000Z",
  "updatedAt": "2024-01-01T00:00:00.000Z"
}

Environment Variables

ConventionExample
SCREAMING_SNAKE_CASEDATABASE_URL
Prefixed by scopeVITE_API_URL (client)

Git

Branch Names

feature/123-add-user-auth
fix/456-content-validation
docs/update-readme
refactor/extract-service

Commit Messages

Use Conventional Commit format:

<type>(optional-scope): short summary

feat(api): add content publishing endpoint
fix(api): validate empty titles
docs: update API documentation
refactor(api): move persistence logic into repository

Pull Request Titles

Use the same Conventional Commit format as commits:

feat(admin): improve media library filtering
fix(ci): handle cache miss in Docker build
docs: clarify Railway setup prerequisites

See AGENTS.md for full commit message guidelines.

On this page