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.jsonThe 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:
| File | Responsibility |
|---|---|
Project.entity.ts | TypeORM columns and relationships |
dtos/Project.dto.ts | Create and update request types |
Project.service.ts | Repository-backed CRUD service |
Project.controller.ts | Plural REST routes such as /Projects |
Project.module.ts | NestJS 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.
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.tsCustom 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 devOpen:
- 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 migrateRegeneration rules
| Path | How to treat it |
|---|---|
.apsorc | Source contract for generated data models |
src/autogen/ | Replaced by apso generate |
src/extensions/ | Application code you own |
src/app.module.rest.ts | Application 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.