Skip to content

Vortexnav: Drizzle + Neon repository layout

Engagement-specific reference for vortexnav-platform (source skill at .agents/skills/repository-pattern/). The generic rules live in ../SKILL.md.

Product rule (vortex-api)

Services under src/services/ must never import drizzle-orm or db/schema. Implementations use Neon<Domain>Repository classes under src/repositories/<domain>/.

Directory layout

src/repositories/<domain>/
  IFooRepository.ts
  NeonFooRepository.ts

src/services/
  fooService.ts

Routes wire repositories:

const db = getDb(c.env.DATABASE_URL);
const fooService = new FooService(new NeonFooRepository(db));

Naming convention

Layer Pattern Example
Interface I<Domain>Repository IDeviceRepository
Implementation Neon<Domain>Repository or neon<domain>Repository.ts NeonSubscriptionRepository.ts

Domain inventory (as of source import)

Domain Interface Implementation
Device IDeviceRepository neonDeviceRepository.ts
User IUserRepository neonUserRepository.ts
Subscription ISubscriptionRepository NeonSubscriptionRepository.ts
Package IPackageRepository NeonPackageRepository.ts
Order IOrderRepository NeonOrderRepository.ts
Entitlement IEntitlementRepository NeonEntitlementRepository.ts
Sync ISyncRepository NeonSyncRepository.ts
Telemetry ITelemetryRepository NeonTelemetryRepository.ts
Command ICommandRepository NeonCommandRepository.ts
Invoice IInvoiceRepository NeonInvoiceRepository.ts
Pack IPackRepository NeonPackRepository.ts
Organization IOrganizationRepository NeonOrganizationRepository.ts
Notification INotificationRepository NeonNotificationRepository.ts
Esri IEsriRepository NeonEsriRepository.ts

PR grep checks (vortex-api)

# Should return no matches in services
rg "from 'drizzle-orm'" src/services/
rg "from ['\"].*db/schema" src/services/

Cross-domain example

DeviceService accepts ISubscriptionRepository for subscription lookups — not a raw Database and not direct subscriptions table access from the service.