| name | rule-naming-conventions |
| description | Naming standards — snake_case properties, kebab-case files, PascalCase types and exports |
Rule naming-conventions
Apply this rule whenever work touches:
Naming standards for the schemas package
Consistent naming across schemas, files, and exports is non-negotiable for a published package. Every consumer interacts with these names directly.
Schema property names — snake_case
All properties within Zod schemas use snake_case. This matches the JSON output format and the IPFS data conventions.
const LocationSchema = z.strictObject({
administrative_division_code: z.string().meta({ ... }),
country_code: CountryCodeSchema.meta({ ... }),
facility_type: FacilityTypeSchema.meta({ ... }),
total_distance_km: z.number().min(0).meta({ ... }),
created_at: IsoDateTimeSchema.meta({ ... }),
});
const LocationSchema = z.strictObject({
administrativeDivisionCode: z.string(),
countryCode: z.string(),
facilityType: z.string(),
});
This is a strict rule — there are no exceptions for "TypeScript convention". The schemas define data contracts, and those contracts use snake_case.
File and directory names — kebab-case
All files and directories use kebab-case:
GOOD:
src/mass-id/mass-id.data.schema.ts
src/shared/schemas/primitives/ids.schema.ts
src/test-utils/fixtures/mass-id-data.fixture.ts
BAD:
src/massId/MassIdData.schema.ts // PascalCase dir + file
src/shared/schemas/UUID.schema.ts // UPPERCASE
src/mass_id/mass_id_data.schema.ts // snake_case
File naming patterns by type:
- Schema files:
{entity}.schema.ts or {entity}.schemas.ts (plural when file contains multiple related schemas)
- Test files:
{entity}.schema.spec.ts (in __tests__/ directory)
- Fixture files:
{entity}.fixture.ts (in src/test-utils/fixtures/)
- Type files:
{entity}.types.ts
- Helper files:
{entity}.helpers.ts
- Constant files:
{entity}.constants.ts
- Index files:
index.ts (barrel exports)
Schema exports — PascalCase with Schema suffix
All exported Zod schema constants use PascalCase with a Schema suffix:
export const MassIDDataSchema = z.strictObject({ ... });
export const LocationSchema = z.strictObject({ ... });
export const ParticipantRoleSchema = z.enum([...]);
export const BlockchainReferenceSchema = z.strictObject({ ... });
export const WastePropertiesSchema = z.strictObject({ ... });
export const massIdData = z.strictObject({ ... });
export const MASS_ID_DATA_SCHEMA = z.strictObject({ ... });
export const massIDDataSchema = z.strictObject({ ... });
Type exports — PascalCase without Schema suffix
TypeScript types inferred from schemas drop the Schema suffix:
export type MassIDData = z.infer<typeof MassIDDataSchema>;
export type Location = z.infer<typeof LocationSchema>;
export type Participant = z.infer<typeof ParticipantSchema>;
export type MassIDDataSchema = z.infer<typeof MassIDDataSchema>;
export type LocationSchemaType = z.infer<typeof LocationSchema>;
ID field naming — _id suffix
Fields that hold identifiers always end with _id:
participant_id: UuidSchema.meta({ ... }),
location_id: UuidSchema.meta({ ... }),
external_id: ExternalIdSchema.meta({ ... }),
document_id: UuidSchema.meta({ ... }),
participant: UuidSchema.meta({ ... }),
participantId: UuidSchema.meta({ ... }),
The only exception is id itself (the primary identifier of an entity), which does not need the prefix.
Timestamp naming
Use descriptive names that indicate what the timestamp represents:
created_at: IsoDateTimeSchema.meta({ ... }),
updated_at: IsoDateTimeSchema.meta({ ... }),
pickup_date: IsoDateSchema.meta({ ... }),
recycling_date: IsoDateSchema.meta({ ... }),
minted_at: IsoDateTimeSchema.meta({ ... }),
date: IsoDateTimeSchema.meta({ ... }),
time: IsoDateTimeSchema.meta({ ... }),
timestamp: IsoDateTimeSchema.meta({ ... }),
Measurement naming — include unit
When a field represents a measurement, include the unit in the name:
distance_km: z.number().min(0).meta({ ... }),
weight_kg: z.number().min(0).meta({ ... }),
duration_hours: z.number().min(0).meta({ ... }),
area_hectares: z.number().min(0).meta({ ... }),
total_distance_km: z.number().min(0).meta({ ... }),
distance: z.number().min(0).meta({ ... }),
weight: z.number().min(0).meta({ ... }),
duration: z.number().min(0).meta({ ... }),
Code field naming — _code suffix
Fields holding standardized codes use the _code suffix:
country_code: CountryCodeSchema.meta({ ... }),
administrative_division_code: z.string().meta({ ... }),
currency_code: z.string().meta({ ... }),
country: z.string().meta({ ... }),
admin_division: z.string().meta({ ... }),
Variables and functions — camelCase
Internal variables and functions use standard TypeScript camelCase:
export function uniqueArrayItems<T>(schema: T, message: string) { ... }
const parsedResult = schema.safeParse(data);
const schemaVersion = getSchemaVersionOrDefault();
This is distinct from schema property names (which are snake_case). The distinction is clear: schema properties define data contracts, while variables and functions are TypeScript implementation details.