Skip to content

Latest commit

 

History

History
18 lines (13 loc) · 1.82 KB

File metadata and controls

18 lines (13 loc) · 1.82 KB

Code Standards

Conventions

  • Use kebab-case for filenames and directories. Where a filename carries a stereotype role suffix (enforced by .ls-lint.yml, or the port an adapter implements), separate the descriptive prefix from the suffix with a dot: create-user.command-handler.ts, postgres-user.repository.ts, pino.logger.ts, user.test-factory.ts. Files whose symbol is the bare entity (aggregates, value objects, scalars) stay plain: user.ts, watch-span.ts.
  • Use snake_case for database tables and columns.
  • Use full names for variables, functions, and types. Avoid abbreviations unless they are widely recognized.
  • Prefer if + return over else and switch statements when possible.
  • Prefer type over interface unless the use case specifically requires an interface.
  • Provide explicit return types for functions and methods.
  • Use const assertions for immutable data structures.

Imports

  • Consume every @yasha/* package as a namespace: import * as postgres from '@yasha/postgres', then postgres.eq, valkey.Batch, schema.string(). Never import a package's named symbols bare - the namespace keeps origin visible at the call site. Enforced by the require-namespace-import lint rule. The rule governs cross-package @yasha/* imports only; app-internal #shared / #<module> specifiers and raw third-party imports at their owning seam are out of scope.
  • Scalar vocabulary is the exception: branded domain primitives (Uuid, Url, MediaId, PrincipalId) are imported bare from #shared, never namespaced - a scalar carries its own meaning like string, and schema.Uuid would misread as "the Uuid schema".

The export-naming principle these rest on, and the rules for scoping and naming a package, are monorepo.md § Package surface and naming.