create-forgeon 0.1.24 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/package.json +1 -1
  2. package/src/core/docs.test.mjs +8 -6
  3. package/src/modules/executor.test.mjs +8 -0
  4. package/src/modules/i18n.mjs +19 -1
  5. package/src/presets/i18n.mjs +76 -34
  6. package/templates/base/apps/api/Dockerfile +7 -4
  7. package/templates/base/apps/api/package.json +3 -2
  8. package/templates/base/apps/api/src/app.module.ts +4 -4
  9. package/templates/base/apps/api/src/health/health.controller.ts +41 -8
  10. package/templates/base/apps/api/src/main.ts +6 -8
  11. package/templates/base/apps/web/src/App.tsx +76 -35
  12. package/templates/base/apps/web/src/styles.css +29 -17
  13. package/templates/base/docs/AI/ARCHITECTURE.md +48 -32
  14. package/templates/base/docs/AI/MODULE_CHECKS.md +25 -0
  15. package/templates/base/docs/AI/MODULE_SPEC.md +1 -0
  16. package/templates/base/docs/AI/PROJECT.md +27 -16
  17. package/templates/base/docs/AI/TASKS.md +8 -7
  18. package/templates/base/docs/AI/VALIDATION.md +6 -1
  19. package/templates/base/docs/README.md +1 -0
  20. package/templates/base/packages/core/README.md +1 -0
  21. package/templates/base/packages/core/src/errors/core-exception.filter.ts +11 -3
  22. package/templates/base/packages/core/src/index.ts +1 -0
  23. package/templates/base/packages/core/src/validation/core-validation.pipe.ts +56 -0
  24. package/templates/base/packages/core/src/validation/index.ts +1 -0
  25. package/templates/base/packages/db-prisma/README.md +9 -0
  26. package/templates/base/packages/db-prisma/package.json +20 -0
  27. package/templates/base/packages/db-prisma/src/db-prisma-config.loader.ts +18 -0
  28. package/templates/base/packages/db-prisma/src/db-prisma-config.service.ts +12 -0
  29. package/templates/base/packages/db-prisma/src/db-prisma-env.schema.ts +17 -0
  30. package/templates/base/packages/db-prisma/src/db-prisma.module.ts +13 -0
  31. package/templates/base/packages/db-prisma/src/index.ts +5 -0
  32. package/templates/base/{apps/api/src/prisma → packages/db-prisma/src}/prisma.service.ts +24 -27
  33. package/templates/base/packages/db-prisma/tsconfig.json +9 -0
  34. package/templates/base/resources/i18n/en/common.json +3 -0
  35. package/templates/base/resources/i18n/uk/common.json +3 -0
  36. package/templates/docs-fragments/AI_ARCHITECTURE/20_env_base.md +1 -1
  37. package/templates/docs-fragments/AI_ARCHITECTURE/30_default_db.md +9 -7
  38. package/templates/docs-fragments/AI_ARCHITECTURE/32_scope_freeze.md +6 -5
  39. package/templates/docs-fragments/AI_PROJECT/20_structure_base.md +2 -1
  40. package/templates/module-presets/i18n/apps/web/src/App.tsx +63 -22
  41. package/templates/base/apps/api/src/prisma/prisma.module.ts +0 -9
@@ -1,11 +1,15 @@
1
- # ARCHITECTURE
2
-
3
- ## Monorepo Layout
4
-
5
- - `apps/*` - deployable apps
6
- - `packages/*` - reusable modules/presets
7
- - `infra/*` - runtime infrastructure
8
- - `resources/*` - static assets (translations)
1
+ # ARCHITECTURE
2
+
3
+ ## Monorepo Layout
4
+
5
+ - `apps/*` - deployable apps
6
+ - `packages/*` - reusable modules/presets
7
+ - `infra/*` - runtime infrastructure
8
+ - `resources/*` - static assets (translations)
9
+
10
+ Canonical stack is fixed in this stage:
11
+ - NestJS + React + Prisma/Postgres + Docker
12
+ - Proxy preset can be `caddy`, `nginx`, or `none`
9
13
 
10
14
  ## Environment Flags
11
15
 
@@ -17,36 +21,48 @@
17
21
 
18
22
  ## Config Strategy
19
23
 
20
- - `@forgeon/core` owns base runtime config (port, API prefix, node env).
24
+ - `@forgeon/core` owns base runtime config, global error envelope/filter, and validation pipe defaults.
21
25
  - Core config is validated with Zod and exposed through typed accessors.
22
26
  - Add-modules own and validate only their module-specific env keys.
23
27
  - i18n is an add-module; when installed, it uses its own env keys.
24
-
25
- ## Default DB Stack
26
-
27
- Current default is Prisma + Postgres.
28
-
29
- - Prisma schema and migrations live in `apps/api/prisma`
30
- - DB access is encapsulated via `PrismaModule` (`apps/api/src/prisma`)
31
-
32
- ## Future DB Presets (Not Implemented Yet)
33
-
34
- A future preset can switch DB by:
35
- 1. Replacing `PrismaModule` with another DB module package (for example Mongo package).
36
- 2. Updating `infra/docker/compose.yml` DB service.
37
- 3. Updating `DATABASE_URL` and related env keys.
38
- 4. Keeping app-level services dependent only on repository/data-access abstractions.
39
-
40
- ## Future Feature Modules
41
28
 
42
- Reusable features should be added as workspace packages and imported by apps as needed:
29
+ ## Default DB Stack
30
+
31
+ Current default is Prisma + Postgres.
32
+
33
+ - Prisma schema and migrations live in `apps/api/prisma`
34
+ - DB access is encapsulated via `DbPrismaModule` in `@forgeon/db-prisma`
35
+ - `db-prisma` is treated as default-applied behavior in scaffold generation.
36
+ - Future direction: this default DB layer may be extracted to an explicit add-module/preset and optionally controlled by a CLI flag.
37
+ - Additional DB presets are out of scope for the current milestone.
38
+
39
+ ## Module Strategy
43
40
 
44
- - `packages/core` for shared backend primitives
45
- - Additional packages for auth presets, guards, queues, mailers, etc.
41
+ Reusable features should be added as fullstack add-modules:
42
+
43
+ - `contracts` package (shared DTO/routes/errors)
44
+ - `api` package (NestJS integration)
45
+ - `web` package (React integration)
46
+
47
+ Reference: `docs/AI/MODULE_SPEC.md`.
46
48
 
47
49
  ## TypeScript Module Format Policy
48
50
 
49
- - `apps/api`, `packages/core`, and backend runtime packages use `tsconfig.base.node.json`.
50
- - Frontend-consumed shared packages (contracts/web helpers) use `tsconfig.base.esm.json`.
51
- - Contracts packages are ESM-first and imported only via package entrypoints.
51
+ - `apps/api`, `packages/core`, and backend runtime packages use Node-oriented config:
52
+ - `tsconfig.base.node.json`
53
+ - Frontend-consumed shared packages (especially contracts/web helpers) use ESM config:
54
+ - `tsconfig.base.esm.json`
55
+ - Contracts packages are ESM-first and imported via package entrypoints only.
52
56
  - Cross-package imports from `/src/*` are disallowed.
57
+
58
+ ## Error Handling Strategy
59
+
60
+ - `@forgeon/core` owns the global HTTP error envelope and filter.
61
+ - API apps import `CoreErrorsModule` and register `CoreExceptionFilter` globally.
62
+ - Envelope fields:
63
+ - `error.code`
64
+ - `error.message`
65
+ - `error.status`
66
+ - `error.details` (optional)
67
+ - `error.requestId` (optional)
68
+ - `error.timestamp`
@@ -0,0 +1,25 @@
1
+ # MODULE CHECKS
2
+
3
+ ## Purpose
4
+
5
+ Define mandatory runtime verification hooks for Forgeon modules.
6
+
7
+ If a module can be validated through a safe API call, it must provide:
8
+
9
+ 1. A probe endpoint in API (`/api/health/*`).
10
+ 2. A probe trigger on default web page (`apps/web/src/App.tsx`).
11
+ 3. A visible result block in UI with HTTP status and JSON body.
12
+
13
+ ## Current Baseline Probes
14
+
15
+ - `core-errors`: `GET /api/health/error` (returns error envelope, expected `409`)
16
+ - `core-validation`: `GET /api/health/validation` without `value` (expected `400`)
17
+ - `db-prisma`: `POST /api/health/db` (creates probe user and returns it, expected `201`)
18
+
19
+ ## Rules For Future Modules
20
+
21
+ - Probe path should be explicit and feature-scoped (`/api/health/<feature>`).
22
+ - Probe must be deterministic and documented (expected status + payload shape).
23
+ - If probe writes data, it must use clearly marked probe/test records.
24
+ - Probe should not require hidden setup beyond documented env/dependencies.
25
+ - `create-forgeon add <module>` must wire both API probe and web probe UI when feasible.
@@ -63,3 +63,4 @@ Must contain:
63
63
  - Contracts package can be imported from both sides without circular dependencies.
64
64
  - Contracts package exports are stable from `dist/index` entrypoint.
65
65
  - Module has docs under `docs/AI/MODULES/<module-id>.md`.
66
+ - If module behavior can be runtime-checked, it also includes API+Web probe hooks (see `docs/AI/MODULE_CHECKS.md`).
@@ -4,15 +4,16 @@
4
4
 
5
5
  A canonical fullstack monorepo scaffold intended to be reused as a project starter.
6
6
 
7
- ## Structure
8
-
9
- - `apps/api` - NestJS backend
10
- - `apps/web` - frontend scaffold (default React + Vite + TS)
11
- - `packages/core` - shared backend core package with internal submodules (starting with `core-config`)
12
- - `packages/i18n` - reusable nestjs-i18n integration package
13
- - `infra` - Docker Compose + reverse proxy preset (nginx/caddy)
14
- - `resources/i18n` - translation dictionaries
15
- - `docs` - documentation and AI workflow prompts
7
+ ## Structure
8
+
9
+ - `apps/api` - NestJS backend
10
+ - `apps/web` - React frontend (fixed stack)
11
+ - `packages/core` - shared backend core package (`core-config`, `core-errors`, `core-validation`)
12
+ - `packages/db-prisma` - reusable Prisma/Postgres module (`DbPrismaModule`, `PrismaService`, config)
13
+ - `packages/i18n` - reusable nestjs-i18n integration package
14
+ - `infra` - Docker Compose + proxy preset (`caddy|nginx|none`)
15
+ - `resources/i18n` - translation dictionaries
16
+ - `docs` - documentation, AI prompts, and module contracts
16
17
 
17
18
  ## Run Modes
18
19
 
@@ -23,10 +24,20 @@ pnpm install
23
24
  pnpm dev
24
25
  ```
25
26
 
26
- ### Docker mode
27
-
28
- ```bash
29
- docker compose --env-file infra/docker/.env.example -f infra/docker/compose.yml up --build
30
- ```
31
-
32
- The API uses Prisma and expects `DATABASE_URL` from env.
27
+ ### Docker mode
28
+
29
+ ```bash
30
+ docker compose --env-file infra/docker/.env.example -f infra/docker/compose.yml up --build
31
+ ```
32
+
33
+ The API uses Prisma and expects `DATABASE_URL` from env.
34
+
35
+ If proxy preset is `none`, API is directly available on `localhost:3000`.
36
+
37
+ ## Error Handling
38
+
39
+ `core-errors` is enabled by default.
40
+
41
+ - `CoreErrorsModule` is imported in `apps/api/src/app.module.ts`.
42
+ - `CoreExceptionFilter` is registered globally in `apps/api/src/main.ts`.
43
+ - Throw standard Nest exceptions from controllers/services; the filter converts them to a stable envelope.
@@ -48,11 +48,12 @@ Create or update create-forgeon preset flow:
48
48
  ## Add Fullstack Module
49
49
 
50
50
  ```text
51
- Implement `create-forgeon add <module-id>` for a fullstack feature.
52
- Requirements:
53
- - split module into contracts/api/web packages
54
- - contracts is source of truth for routes, DTOs, errors
55
- - add docs note under docs/AI/MODULES/<module-id>.md
56
- - keep backward compatibility
57
- ```
51
+ Implement `create-forgeon add <module-id>` for a fullstack feature.
52
+ Requirements:
53
+ - split module into contracts/api/web packages
54
+ - contracts is source of truth for routes, DTOs, errors
55
+ - if feasible, add module probe hooks in API (`/api/health/*`) and web diagnostics UI
56
+ - add docs note under docs/AI/MODULES/<module-id>.md
57
+ - keep backward compatibility
58
+ ```
58
59
 
@@ -3,9 +3,12 @@
3
3
  ## Backend DTO Validation Standard
4
4
 
5
5
  - Use `class-validator` decorators on DTO classes.
6
- - Global validation is done by Nest `ValidationPipe` with:
6
+ - Global validation is centralized in `@forgeon/core` via `createValidationPipe()`.
7
+ - Current defaults:
7
8
  - `whitelist: true`
8
9
  - `transform: true`
10
+ - `validationError.target: false`
11
+ - `validationError.value: false`
9
12
  - Keep DTO validation messages stable and explicit.
10
13
  - For required values, use a consistent key or message pattern.
11
14
 
@@ -24,3 +27,5 @@
24
27
  - `error.status`
25
28
  - optional `error.details`
26
29
  - Validation details should be structured (not `any`).
30
+ - `core-validation` formats validation details as:
31
+ - `{ field?: string, message: string }[]`
@@ -3,5 +3,6 @@
3
3
  - `AI/PROJECT.md` - project overview and run modes
4
4
  - `AI/ARCHITECTURE.md` - monorepo design and extension model
5
5
  - `AI/MODULE_SPEC.md` - fullstack module contract (`contracts/api/web`)
6
+ - `AI/MODULE_CHECKS.md` - required runtime probe hooks for modules
6
7
  - `AI/VALIDATION.md` - DTO/env validation standards
7
8
  - `AI/TASKS.md` - ready-to-use Codex prompts
@@ -6,4 +6,5 @@ Current submodules:
6
6
 
7
7
  - `core-config` - Zod-validated env config + typed accessors for API runtime.
8
8
  - `core-errors` - global exception filter + stable error envelope shape.
9
+ - `core-validation` - shared ValidationPipe factory with normalized validation details.
9
10
 
@@ -88,15 +88,23 @@ export class CoreExceptionFilter implements ExceptionFilter {
88
88
  }
89
89
 
90
90
  private resolveDetails(payload: unknown, status: number): AppErrorDetails | undefined {
91
- if (status !== HttpStatus.BAD_REQUEST) {
91
+ if (typeof payload !== 'object' || payload === null) {
92
92
  return undefined;
93
93
  }
94
94
 
95
- if (typeof payload !== 'object' || payload === null) {
95
+ const obj = payload as { message?: unknown; details?: unknown };
96
+
97
+ if (Array.isArray(obj.details)) {
98
+ return obj.details as AppErrorDetails;
99
+ }
100
+ if (obj.details && typeof obj.details === 'object') {
101
+ return obj.details as AppErrorDetails;
102
+ }
103
+
104
+ if (status !== HttpStatus.BAD_REQUEST) {
96
105
  return undefined;
97
106
  }
98
107
 
99
- const obj = payload as { message?: unknown };
100
108
  const messages = Array.isArray(obj.message)
101
109
  ? obj.message.filter((item): item is string => typeof item === 'string')
102
110
  : typeof obj.message === 'string'
@@ -1,2 +1,3 @@
1
1
  export * from './config';
2
2
  export * from './errors';
3
+ export * from './validation';
@@ -0,0 +1,56 @@
1
+ import { BadRequestException, ValidationPipe } from '@nestjs/common';
2
+ import type { ValidationErrorDetail } from '../errors';
3
+
4
+ type ValidationNode = {
5
+ property?: string;
6
+ constraints?: Record<string, string>;
7
+ children?: ValidationNode[];
8
+ };
9
+
10
+ function toPath(parentPath: string, property: string | undefined): string {
11
+ if (!property || property.length === 0) {
12
+ return parentPath;
13
+ }
14
+ return parentPath.length > 0 ? `${parentPath}.${property}` : property;
15
+ }
16
+
17
+ function collectValidationDetails(
18
+ errors: ValidationNode[],
19
+ parentPath = '',
20
+ ): ValidationErrorDetail[] {
21
+ const details: ValidationErrorDetail[] = [];
22
+
23
+ for (const error of errors) {
24
+ const field = toPath(parentPath, error.property);
25
+ const constraints = error.constraints ? Object.values(error.constraints) : [];
26
+
27
+ for (const message of constraints) {
28
+ details.push(field.length > 0 ? { field, message } : { message });
29
+ }
30
+
31
+ if (Array.isArray(error.children) && error.children.length > 0) {
32
+ details.push(...collectValidationDetails(error.children, field));
33
+ }
34
+ }
35
+
36
+ return details;
37
+ }
38
+
39
+ export function createValidationPipe(): ValidationPipe {
40
+ return new ValidationPipe({
41
+ whitelist: true,
42
+ transform: true,
43
+ validationError: {
44
+ target: false,
45
+ value: false,
46
+ },
47
+ exceptionFactory: (errors) => {
48
+ const details = collectValidationDetails(errors as ValidationNode[]);
49
+ const firstMessage = details[0]?.message ?? 'Validation failed';
50
+ return new BadRequestException({
51
+ message: firstMessage,
52
+ details,
53
+ });
54
+ },
55
+ });
56
+ }
@@ -0,0 +1 @@
1
+ export * from './core-validation.pipe';
@@ -0,0 +1,9 @@
1
+ # @forgeon/db-prisma
2
+
3
+ Reusable Prisma/Postgres backend module.
4
+
5
+ Includes:
6
+
7
+ - `DbPrismaModule`
8
+ - `PrismaService`
9
+ - module-local config loader/service and env schema validation
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@forgeon/db-prisma",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc -p tsconfig.json"
9
+ },
10
+ "dependencies": {
11
+ "@nestjs/common": "^11.0.1",
12
+ "@nestjs/config": "^4.0.2",
13
+ "@prisma/client": "^6.18.0",
14
+ "zod": "^3.23.8"
15
+ },
16
+ "devDependencies": {
17
+ "@types/node": "^22.10.7",
18
+ "typescript": "^5.7.3"
19
+ }
20
+ }
@@ -0,0 +1,18 @@
1
+ import { registerAs } from '@nestjs/config';
2
+ import { parseDbPrismaEnv } from './db-prisma-env.schema';
3
+
4
+ export const DB_PRISMA_CONFIG_NAMESPACE = 'dbPrisma';
5
+
6
+ export interface DbPrismaConfigValues {
7
+ databaseUrl: string;
8
+ }
9
+
10
+ export const dbPrismaConfig = registerAs(
11
+ DB_PRISMA_CONFIG_NAMESPACE,
12
+ (): DbPrismaConfigValues => {
13
+ const env = parseDbPrismaEnv(process.env);
14
+ return {
15
+ databaseUrl: env.DATABASE_URL,
16
+ };
17
+ },
18
+ );
@@ -0,0 +1,12 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { ConfigService } from '@nestjs/config';
3
+ import { DB_PRISMA_CONFIG_NAMESPACE } from './db-prisma-config.loader';
4
+
5
+ @Injectable()
6
+ export class DbPrismaConfigService {
7
+ constructor(private readonly configService: ConfigService) {}
8
+
9
+ get databaseUrl(): string {
10
+ return this.configService.getOrThrow<string>(`${DB_PRISMA_CONFIG_NAMESPACE}.databaseUrl`);
11
+ }
12
+ }
@@ -0,0 +1,17 @@
1
+ import { z } from 'zod';
2
+
3
+ export const dbPrismaEnvSchema = z
4
+ .object({
5
+ DATABASE_URL: z
6
+ .string()
7
+ .trim()
8
+ .min(1)
9
+ .default('postgresql://postgres:postgres@localhost:5432/app?schema=public'),
10
+ })
11
+ .passthrough();
12
+
13
+ export type DbPrismaEnv = z.infer<typeof dbPrismaEnvSchema>;
14
+
15
+ export function parseDbPrismaEnv(input: Record<string, unknown>): DbPrismaEnv {
16
+ return dbPrismaEnvSchema.parse(input);
17
+ }
@@ -0,0 +1,13 @@
1
+ import { Global, Module } from '@nestjs/common';
2
+ import { ConfigModule } from '@nestjs/config';
3
+ import { dbPrismaConfig } from './db-prisma-config.loader';
4
+ import { DbPrismaConfigService } from './db-prisma-config.service';
5
+ import { PrismaService } from './prisma.service';
6
+
7
+ @Global()
8
+ @Module({
9
+ imports: [ConfigModule.forFeature(dbPrismaConfig)],
10
+ providers: [DbPrismaConfigService, PrismaService],
11
+ exports: [DbPrismaConfigService, PrismaService],
12
+ })
13
+ export class DbPrismaModule {}
@@ -0,0 +1,5 @@
1
+ export * from './db-prisma-env.schema';
2
+ export * from './db-prisma-config.loader';
3
+ export * from './db-prisma-config.service';
4
+ export * from './db-prisma.module';
5
+ export * from './prisma.service';
@@ -1,27 +1,24 @@
1
- import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
2
- import { PrismaClient } from '@prisma/client';
3
-
4
- @Injectable()
5
- export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
6
- constructor() {
7
- const databaseUrl =
8
- process.env.DATABASE_URL ??
9
- 'postgresql://postgres:postgres@localhost:5432/app?schema=public';
10
-
11
- super({
12
- datasources: {
13
- db: {
14
- url: databaseUrl,
15
- },
16
- },
17
- });
18
- }
19
-
20
- async onModuleInit(): Promise<void> {
21
- await this.$connect();
22
- }
23
-
24
- async onModuleDestroy(): Promise<void> {
25
- await this.$disconnect();
26
- }
27
- }
1
+ import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
2
+ import { PrismaClient } from '@prisma/client';
3
+ import { DbPrismaConfigService } from './db-prisma-config.service';
4
+
5
+ @Injectable()
6
+ export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
7
+ constructor(configService: DbPrismaConfigService) {
8
+ super({
9
+ datasources: {
10
+ db: {
11
+ url: configService.databaseUrl,
12
+ },
13
+ },
14
+ });
15
+ }
16
+
17
+ async onModuleInit(): Promise<void> {
18
+ await this.$connect();
19
+ }
20
+
21
+ async onModuleDestroy(): Promise<void> {
22
+ await this.$disconnect();
23
+ }
24
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.base.node.json",
3
+ "compilerOptions": {
4
+ "rootDir": "src",
5
+ "outDir": "dist",
6
+ "types": ["node"]
7
+ },
8
+ "include": ["src/**/*.ts"]
9
+ }
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "ok": "OK",
3
3
  "checkApiHealth": "Check API health",
4
+ "checkErrorEnvelope": "Check error envelope",
5
+ "checkValidation": "Check validation (expect 400)",
6
+ "checkDatabase": "Check database (create user)",
4
7
  "language": "Language",
5
8
  "languages": {
6
9
  "english": "English",
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "ok": "OK",
3
3
  "checkApiHealth": "Перевірити API health",
4
+ "checkErrorEnvelope": "Перевірити error envelope",
5
+ "checkValidation": "Перевірити валідацію (очікуємо 400)",
6
+ "checkDatabase": "Перевірити базу даних (створити користувача)",
4
7
  "language": "Мова",
5
8
  "languages": {
6
9
  "english": "Англійська",
@@ -6,6 +6,6 @@
6
6
 
7
7
  ## Config Strategy
8
8
 
9
- - `@forgeon/core` owns base runtime config (port, API prefix, node env).
9
+ - `@forgeon/core` owns base runtime config, global error envelope/filter, and validation pipe defaults.
10
10
  - Core config is validated with Zod and exposed through typed accessors.
11
11
  - Add-modules own and validate only their module-specific env keys.
@@ -1,7 +1,9 @@
1
- ## Default DB Stack
2
-
3
- Current default stack is `{{DB_LABEL}}`.
4
-
5
- - Prisma schema and migrations live in `apps/api/prisma`
6
- - DB access is encapsulated via `PrismaModule` (`apps/api/src/prisma`)
7
- - Additional DB presets are intentionally out of scope for the current milestone.
1
+ ## Default DB Stack
2
+
3
+ Current default stack is `{{DB_LABEL}}`.
4
+
5
+ - Prisma schema and migrations live in `apps/api/prisma`
6
+ - DB access is encapsulated via `DbPrismaModule` in `@forgeon/db-prisma`
7
+ - `db-prisma` is currently default-applied during scaffold generation.
8
+ - Future direction: this DB layer may be extracted into an explicit add-module/preset and optionally exposed via CLI flag(s).
9
+ - Additional DB presets are intentionally out of scope for the current milestone.
@@ -1,5 +1,6 @@
1
- ## Scope Freeze (Current)
2
-
3
- - Frontend preset selection is disabled (React is fixed).
4
- - DB preset selection is disabled (Prisma/Postgres is fixed).
5
- - Docker is always generated; runtime proxy is selectable (`caddy|nginx|none`).
1
+ ## Scope Freeze (Current)
2
+
3
+ - Frontend preset selection is disabled (React is fixed).
4
+ - DB preset selection is disabled (Prisma/Postgres is fixed).
5
+ - Docker is always generated; runtime proxy is selectable (`caddy|nginx|none`).
6
+ - DB preset flags may return in a future milestone after `db-prisma` is separated into an explicit preset/module flow.
@@ -2,4 +2,5 @@
2
2
 
3
3
  - `apps/api` - NestJS backend
4
4
  - `apps/web` - React frontend (`{{FRONTEND_LABEL}}`, fixed)
5
- - `packages/core` - shared backend core package (`core-config` and future core submodules)
5
+ - `packages/core` - shared backend core package (`core-config`, `core-errors`, `core-validation`)
6
+ - `packages/db-prisma` - default DB module (`DbPrismaModule`, Prisma service + config)