Skip to Content
Apso is in public beta. Get started

Project structure

A generated TypeScript service is a NestJS application. Apso owns the contents of src/autogen/; the rest of the repository is available for application code and deployment configuration.

Directory map

task-api/ |-- src/ | |-- autogen/ # Generated entity modules | | |-- Project/ | | | |-- Project.entity.ts | | | |-- Project.service.ts | | | |-- Project.controller.ts | | | |-- Project.module.ts | | | `-- dtos/ | | `-- index.ts | |-- config/ # Application configuration helpers | |-- healthCheck/ # Basic health route | |-- migrations/ # TypeORM migrations | |-- app.module.rest.ts # REST application composition | |-- main.ts # Local HTTP entry point | |-- lambda.ts # Lambda entry point | `-- orm.config.ts # TypeORM data source configuration |-- test/ # End-to-end and integration tests |-- .apsorc # Apso schema contract |-- package.json `-- tsconfig.json

The first scaffold can contain additional template utilities or sample test modules. Check the generated repository before assuming a path exists.

Generated entity modules

Each schema entity gets a directory under src/autogen/. For an entity named Project, Apso generates:

FileResponsibility
Project.entity.tsTypeORM columns and relationships
dtos/Project.dto.tsCreate and update request types
Project.service.tsRepository-backed CRUD service
Project.controller.tsPlural REST routes such as /Projects
Project.module.tsNestJS module and TypeORM registration

src/autogen/index.ts exports the generated modules. src/app.module.rest.ts imports that list and includes it when a database is configured.

Application composition

The REST root module configures environment values, the database connection, generated modules, and any custom modules you register.

src/app.module.rest.ts
import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; import moduleImports from './autogen'; import { typeOrmAsyncConfig, useNoDatabase } from './orm.config'; const imports = [ ConfigModule.forRoot({ isGlobal: true }), ...(useNoDatabase || !typeOrmAsyncConfig ? [] : [TypeOrmModule.forRootAsync(typeOrmAsyncConfig)]), ...(useNoDatabase ? [] : moduleImports), ]; @Module({ imports }) export class AppModule {}

Use this module as the explicit composition point for application code outside src/autogen/.

Add custom code

Create a directory such as src/extensions/ for product workflows, integrations, guards, and custom routes. Register its NestJS module in src/app.module.rest.ts.

src/extensions/ |-- billing/ | |-- billing.controller.ts | |-- billing.service.ts | `-- billing.module.ts `-- extensions.module.ts

Custom code can import a generated entity, DTO, module, or service. Regeneration may change those types, so run the build and tests after every schema change.

Runtime entry points

src/main.ts starts the local NestJS server and applies the shared Nest application configuration. The generated API reference is served at /_docs while the service runs.

apso dev

Open:

  • API: http://localhost:3100
  • API reference: http://localhost:3100/_docs
  • Health check: http://localhost:3100/health

src/lambda.ts creates the same application module for the hosted Lambda runtime.

Database files

src/orm.config.ts reads the current database configuration. Local development can use PGlite or PostgreSQL. TypeORM migrations are stored under src/migrations/.

Use the CLI migration workflow after changing .apsorc:

apso generate apso migrate

Regeneration rules

PathHow to treat it
.apsorcSource contract for generated data models
src/autogen/Replaced by apso generate
src/extensions/Application code you own
src/app.module.rest.tsApplication composition you own
src/migrations/Review and commit migration history

Commit before regenerating and inspect the diff afterward. Put schema changes in .apsorc and behavior changes in custom code.

Last updated on