create-forgeon 0.1.2 → 0.1.6

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 (143) hide show
  1. package/README.md +19 -17
  2. package/bin/create-forgeon.mjs +22 -22
  3. package/package.json +1 -1
  4. package/src/cli/add-help.mjs +12 -12
  5. package/src/cli/add-options.mjs +54 -54
  6. package/src/cli/add-options.test.mjs +24 -24
  7. package/src/cli/help.mjs +20 -20
  8. package/src/cli/options.mjs +121 -121
  9. package/src/cli/options.test.mjs +41 -41
  10. package/src/cli/prompt-select.mjs +94 -94
  11. package/src/cli/prompt-select.test.mjs +148 -148
  12. package/src/constants.mjs +13 -13
  13. package/src/core/docs.mjs +128 -128
  14. package/src/core/docs.test.mjs +91 -91
  15. package/src/core/install.mjs +14 -14
  16. package/src/core/scaffold.mjs +48 -45
  17. package/src/core/validate.mjs +12 -12
  18. package/src/core/validate.test.mjs +73 -73
  19. package/src/databases/index.mjs +26 -26
  20. package/src/frameworks/index.mjs +32 -32
  21. package/src/infrastructure/proxy.mjs +12 -12
  22. package/src/modules/docs.mjs +70 -70
  23. package/src/modules/executor.mjs +39 -21
  24. package/src/modules/executor.test.mjs +95 -45
  25. package/src/modules/i18n.mjs +283 -0
  26. package/src/modules/registry.mjs +43 -35
  27. package/src/presets/i18n.mjs +228 -180
  28. package/src/presets/index.mjs +2 -2
  29. package/src/presets/proxy.mjs +32 -32
  30. package/src/run-add-module.mjs +47 -47
  31. package/src/run-create-forgeon.mjs +72 -72
  32. package/src/utils/fs.mjs +26 -26
  33. package/src/utils/values.mjs +20 -20
  34. package/templates/base/.dockerignore +7 -7
  35. package/templates/base/.editorconfig +11 -11
  36. package/templates/base/README.md +46 -46
  37. package/templates/base/apps/api/Dockerfile +24 -24
  38. package/templates/base/apps/api/package.json +39 -39
  39. package/templates/base/apps/api/prisma/migrations/0001_init/migration.sql +11 -11
  40. package/templates/base/apps/api/prisma/schema.prisma +14 -14
  41. package/templates/base/apps/api/prisma/seed.ts +19 -19
  42. package/templates/base/apps/api/src/app.module.ts +32 -32
  43. package/templates/base/apps/api/src/common/dto/echo-query.dto.ts +5 -5
  44. package/templates/base/apps/api/src/common/filters/app-exception.filter.ts +129 -129
  45. package/templates/base/apps/api/src/config/app.config.ts +12 -12
  46. package/templates/base/apps/api/src/health/health.controller.ts +30 -30
  47. package/templates/base/apps/api/src/main.ts +25 -25
  48. package/templates/base/apps/api/src/prisma/prisma.module.ts +8 -8
  49. package/templates/base/apps/api/src/prisma/prisma.service.ts +26 -26
  50. package/templates/base/apps/api/tsconfig.build.json +8 -8
  51. package/templates/base/apps/api/tsconfig.json +8 -8
  52. package/templates/base/apps/web/Dockerfile +12 -12
  53. package/templates/base/apps/web/index.html +11 -11
  54. package/templates/base/apps/web/package.json +21 -21
  55. package/templates/base/apps/web/src/App.tsx +35 -35
  56. package/templates/base/apps/web/src/main.tsx +8 -8
  57. package/templates/base/apps/web/src/styles.css +32 -32
  58. package/templates/base/apps/web/tsconfig.json +17 -17
  59. package/templates/base/apps/web/vite.config.ts +14 -14
  60. package/templates/base/docs/AI/ARCHITECTURE.md +37 -37
  61. package/templates/base/docs/AI/MODULE_SPEC.md +56 -56
  62. package/templates/base/docs/AI/PROJECT.md +31 -31
  63. package/templates/base/docs/AI/TASKS.md +57 -57
  64. package/templates/base/docs/README.md +6 -6
  65. package/templates/base/infra/caddy/Caddyfile +15 -15
  66. package/templates/base/infra/docker/.env.example +9 -9
  67. package/templates/base/infra/docker/caddy.Dockerfile +15 -15
  68. package/templates/base/infra/docker/compose.caddy.yml +44 -44
  69. package/templates/base/infra/docker/compose.nginx.yml +44 -44
  70. package/templates/base/infra/docker/compose.none.yml +37 -37
  71. package/templates/base/infra/docker/compose.yml +44 -44
  72. package/templates/base/infra/docker/nginx.Dockerfile +15 -15
  73. package/templates/base/infra/nginx/nginx.conf +31 -31
  74. package/templates/base/package.json +23 -23
  75. package/templates/base/packages/core/README.md +2 -2
  76. package/templates/base/packages/core/package.json +13 -13
  77. package/templates/base/packages/core/tsconfig.json +7 -7
  78. package/templates/base/packages/i18n/package.json +18 -18
  79. package/templates/base/packages/i18n/src/forgeon-i18n.module.ts +45 -45
  80. package/templates/base/packages/i18n/tsconfig.json +8 -8
  81. package/templates/base/pnpm-workspace.yaml +2 -2
  82. package/templates/base/resources/i18n/en/common.json +4 -4
  83. package/templates/base/resources/i18n/en/validation.json +2 -2
  84. package/templates/base/resources/i18n/uk/common.json +4 -4
  85. package/templates/base/resources/i18n/uk/validation.json +2 -2
  86. package/templates/base/tsconfig.base.json +16 -16
  87. package/templates/docs-fragments/AI_ARCHITECTURE/00_title.md +1 -1
  88. package/templates/docs-fragments/AI_ARCHITECTURE/10_layout_base.md +6 -6
  89. package/templates/docs-fragments/AI_ARCHITECTURE/11_layout_infra.md +1 -1
  90. package/templates/docs-fragments/AI_ARCHITECTURE/12_layout_i18n_resources.md +1 -1
  91. package/templates/docs-fragments/AI_ARCHITECTURE/20_env_base.md +4 -4
  92. package/templates/docs-fragments/AI_ARCHITECTURE/21_env_i18n.md +3 -3
  93. package/templates/docs-fragments/AI_ARCHITECTURE/30_default_db.md +7 -7
  94. package/templates/docs-fragments/AI_ARCHITECTURE/31_docker_runtime.md +5 -5
  95. package/templates/docs-fragments/AI_ARCHITECTURE/32_scope_freeze.md +5 -5
  96. package/templates/docs-fragments/AI_ARCHITECTURE/40_docs_generation.md +9 -9
  97. package/templates/docs-fragments/AI_ARCHITECTURE/50_extension_points.md +8 -8
  98. package/templates/docs-fragments/AI_PROJECT/00_title.md +1 -1
  99. package/templates/docs-fragments/AI_PROJECT/10_what_is.md +3 -3
  100. package/templates/docs-fragments/AI_PROJECT/20_structure_base.md +5 -5
  101. package/templates/docs-fragments/AI_PROJECT/21_structure_i18n.md +2 -0
  102. package/templates/docs-fragments/AI_PROJECT/22_structure_docker.md +1 -1
  103. package/templates/docs-fragments/AI_PROJECT/23_structure_docs.md +1 -1
  104. package/templates/docs-fragments/AI_PROJECT/30_run_dev.md +8 -8
  105. package/templates/docs-fragments/AI_PROJECT/31_run_docker.md +5 -5
  106. package/templates/docs-fragments/AI_PROJECT/32_proxy_notes.md +5 -5
  107. package/templates/docs-fragments/AI_PROJECT/32_proxy_notes_none.md +5 -5
  108. package/templates/docs-fragments/AI_PROJECT/33_i18n_notes.md +2 -0
  109. package/templates/docs-fragments/AI_PROJECT/40_change_boundaries_base.md +3 -3
  110. package/templates/docs-fragments/AI_PROJECT/41_change_boundaries_docker.md +1 -1
  111. package/templates/docs-fragments/README/00_title.md +3 -3
  112. package/templates/docs-fragments/README/10_stack.md +8 -8
  113. package/templates/docs-fragments/README/20_quick_start_dev_intro.md +6 -6
  114. package/templates/docs-fragments/README/21_quick_start_dev_db_docker.md +4 -4
  115. package/templates/docs-fragments/README/21_quick_start_dev_db_local.md +1 -1
  116. package/templates/docs-fragments/README/22_quick_start_dev_outro.md +7 -7
  117. package/templates/docs-fragments/README/30_quick_start_docker.md +7 -7
  118. package/templates/docs-fragments/README/30_quick_start_docker_none.md +9 -9
  119. package/templates/docs-fragments/README/31_proxy_preset_caddy.md +9 -9
  120. package/templates/docs-fragments/README/31_proxy_preset_nginx.md +8 -8
  121. package/templates/docs-fragments/README/31_proxy_preset_none.md +6 -6
  122. package/templates/docs-fragments/README/32_prisma_container_start.md +5 -5
  123. package/templates/docs-fragments/README/40_i18n.md +14 -8
  124. package/templates/docs-fragments/README/90_next_steps.md +7 -7
  125. package/templates/module-fragments/i18n/00_title.md +5 -0
  126. package/templates/module-fragments/i18n/10_overview.md +9 -0
  127. package/templates/module-fragments/i18n/20_scope.md +7 -0
  128. package/templates/module-fragments/i18n/90_status_implemented.md +3 -0
  129. package/templates/module-fragments/jwt-auth/00_title.md +1 -1
  130. package/templates/module-fragments/jwt-auth/10_overview.md +6 -6
  131. package/templates/module-fragments/jwt-auth/20_scope.md +7 -7
  132. package/templates/module-fragments/jwt-auth/90_status_planned.md +3 -3
  133. package/templates/module-fragments/queue/00_title.md +1 -1
  134. package/templates/module-fragments/queue/10_overview.md +6 -6
  135. package/templates/module-fragments/queue/20_scope.md +7 -7
  136. package/templates/module-fragments/queue/90_status_planned.md +3 -3
  137. package/templates/module-presets/i18n/apps/web/src/App.tsx +61 -0
  138. package/templates/module-presets/i18n/packages/i18n-contracts/package.json +14 -0
  139. package/templates/module-presets/i18n/packages/i18n-contracts/src/index.ts +7 -0
  140. package/templates/module-presets/i18n/packages/i18n-contracts/tsconfig.json +8 -0
  141. package/templates/module-presets/i18n/packages/i18n-web/package.json +17 -0
  142. package/templates/module-presets/i18n/packages/i18n-web/src/index.ts +50 -0
  143. package/templates/module-presets/i18n/packages/i18n-web/tsconfig.json +8 -0
@@ -1,37 +1,37 @@
1
- import { useState } from 'react';
2
- import './styles.css';
3
-
4
- type HealthResponse = {
5
- status: string;
6
- message: string;
7
- };
8
-
9
- export default function App() {
10
- const [data, setData] = useState<HealthResponse | null>(null);
11
- const [error, setError] = useState<string | null>(null);
12
-
13
- const checkApi = async () => {
14
- setError(null);
15
- try {
16
- const response = await fetch('/api/health');
17
- if (!response.ok) {
18
- throw new Error(`HTTP ${response.status}`);
19
- }
20
- const payload = (await response.json()) as HealthResponse;
21
- setData(payload);
22
- } catch (err) {
23
- setError(err instanceof Error ? err.message : 'Unknown error');
24
- }
25
- };
26
-
27
- return (
28
- <main className="page">
29
- <h1>Forgeon Fullstack Scaffold</h1>
30
- <p>Default frontend preset: React + Vite + TypeScript.</p>
31
- <button onClick={checkApi}>Check API health</button>
32
- {data ? <pre>{JSON.stringify(data, null, 2)}</pre> : null}
33
- {error ? <p className="error">{error}</p> : null}
34
- </main>
35
- );
1
+ import { useState } from 'react';
2
+ import './styles.css';
3
+
4
+ type HealthResponse = {
5
+ status: string;
6
+ message: string;
7
+ };
8
+
9
+ export default function App() {
10
+ const [data, setData] = useState<HealthResponse | null>(null);
11
+ const [error, setError] = useState<string | null>(null);
12
+
13
+ const checkApi = async () => {
14
+ setError(null);
15
+ try {
16
+ const response = await fetch('/api/health');
17
+ if (!response.ok) {
18
+ throw new Error(`HTTP ${response.status}`);
19
+ }
20
+ const payload = (await response.json()) as HealthResponse;
21
+ setData(payload);
22
+ } catch (err) {
23
+ setError(err instanceof Error ? err.message : 'Unknown error');
24
+ }
25
+ };
26
+
27
+ return (
28
+ <main className="page">
29
+ <h1>Forgeon Fullstack Scaffold</h1>
30
+ <p>Default frontend preset: React + Vite + TypeScript.</p>
31
+ <button onClick={checkApi}>Check API health</button>
32
+ {data ? <pre>{JSON.stringify(data, null, 2)}</pre> : null}
33
+ {error ? <p className="error">{error}</p> : null}
34
+ </main>
35
+ );
36
36
  }
37
37
 
@@ -1,9 +1,9 @@
1
- import React from 'react';
2
- import ReactDOM from 'react-dom/client';
3
- import App from './App';
4
-
5
- ReactDOM.createRoot(document.getElementById('root')!).render(
6
- <React.StrictMode>
7
- <App />
8
- </React.StrictMode>,
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import App from './App';
4
+
5
+ ReactDOM.createRoot(document.getElementById('root')!).render(
6
+ <React.StrictMode>
7
+ <App />
8
+ </React.StrictMode>,
9
9
  );
@@ -1,33 +1,33 @@
1
- :root {
2
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
3
- }
4
-
5
- body {
6
- margin: 0;
7
- background: #f8fafc;
8
- color: #0f172a;
9
- }
10
-
11
- .page {
12
- max-width: 720px;
13
- margin: 3rem auto;
14
- padding: 0 1rem;
15
- }
16
-
17
- button {
18
- padding: 0.6rem 1rem;
19
- border: 0;
20
- border-radius: 0.5rem;
21
- cursor: pointer;
22
- }
23
-
24
- pre {
25
- background: #e2e8f0;
26
- padding: 1rem;
27
- border-radius: 0.5rem;
28
- overflow: auto;
29
- }
30
-
31
- .error {
32
- color: #b91c1c;
1
+ :root {
2
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
3
+ }
4
+
5
+ body {
6
+ margin: 0;
7
+ background: #f8fafc;
8
+ color: #0f172a;
9
+ }
10
+
11
+ .page {
12
+ max-width: 720px;
13
+ margin: 3rem auto;
14
+ padding: 0 1rem;
15
+ }
16
+
17
+ button {
18
+ padding: 0.6rem 1rem;
19
+ border: 0;
20
+ border-radius: 0.5rem;
21
+ cursor: pointer;
22
+ }
23
+
24
+ pre {
25
+ background: #e2e8f0;
26
+ padding: 1rem;
27
+ border-radius: 0.5rem;
28
+ overflow: auto;
29
+ }
30
+
31
+ .error {
32
+ color: #b91c1c;
33
33
  }
@@ -1,18 +1,18 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "useDefineForClassFields": true,
5
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
- "module": "ESNext",
7
- "skipLibCheck": true,
8
- "moduleResolution": "bundler",
9
- "allowImportingTsExtensions": false,
10
- "resolveJsonModule": true,
11
- "isolatedModules": true,
12
- "noEmit": true,
13
- "jsx": "react-jsx",
14
- "strict": true,
15
- "types": ["vite/client"]
16
- },
17
- "include": ["src"]
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+ "moduleResolution": "bundler",
9
+ "allowImportingTsExtensions": false,
10
+ "resolveJsonModule": true,
11
+ "isolatedModules": true,
12
+ "noEmit": true,
13
+ "jsx": "react-jsx",
14
+ "strict": true,
15
+ "types": ["vite/client"]
16
+ },
17
+ "include": ["src"]
18
18
  }
@@ -1,15 +1,15 @@
1
- import { defineConfig } from 'vite';
2
- import react from '@vitejs/plugin-react';
3
-
4
- export default defineConfig({
5
- plugins: [react()],
6
- server: {
7
- port: 5173,
8
- proxy: {
9
- '/api': {
10
- target: 'http://localhost:3000',
11
- changeOrigin: true,
12
- },
13
- },
14
- },
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ server: {
7
+ port: 5173,
8
+ proxy: {
9
+ '/api': {
10
+ target: 'http://localhost:3000',
11
+ changeOrigin: true,
12
+ },
13
+ },
14
+ },
15
15
  });
@@ -1,38 +1,38 @@
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
- ## Environment Flags
11
-
12
- - `PORT` - API port (default 3000)
13
- - `DATABASE_URL` - Prisma Postgres connection
14
- - `I18N_ENABLED` - toggles i18n package wiring
15
- - `I18N_DEFAULT_LANG` - default language
16
- - `I18N_FALLBACK_LANG` - fallback language
17
-
18
- ## Default DB Stack
19
-
20
- Current default is Prisma + Postgres.
21
-
22
- - Prisma schema and migrations live in `apps/api/prisma`
23
- - DB access is encapsulated via `PrismaModule` (`apps/api/src/prisma`)
24
-
25
- ## Future DB Presets (Not Implemented Yet)
26
-
27
- A future preset can switch DB by:
28
- 1. Replacing `PrismaModule` with another DB module package (for example Mongo package).
29
- 2. Updating `infra/docker/compose.yml` DB service.
30
- 3. Updating `DATABASE_URL` and related env keys.
31
- 4. Keeping app-level services dependent only on repository/data-access abstractions.
32
-
33
- ## Future Feature Modules
34
-
35
- Reusable features should be added as workspace packages and imported by apps as needed:
36
-
37
- - `packages/core` for shared backend primitives
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
+ ## Environment Flags
11
+
12
+ - `PORT` - API port (default 3000)
13
+ - `DATABASE_URL` - Prisma Postgres connection
14
+ - `I18N_ENABLED` - toggles i18n package wiring
15
+ - `I18N_DEFAULT_LANG` - default language
16
+ - `I18N_FALLBACK_LANG` - fallback language
17
+
18
+ ## Default DB Stack
19
+
20
+ Current default is Prisma + Postgres.
21
+
22
+ - Prisma schema and migrations live in `apps/api/prisma`
23
+ - DB access is encapsulated via `PrismaModule` (`apps/api/src/prisma`)
24
+
25
+ ## Future DB Presets (Not Implemented Yet)
26
+
27
+ A future preset can switch DB by:
28
+ 1. Replacing `PrismaModule` with another DB module package (for example Mongo package).
29
+ 2. Updating `infra/docker/compose.yml` DB service.
30
+ 3. Updating `DATABASE_URL` and related env keys.
31
+ 4. Keeping app-level services dependent only on repository/data-access abstractions.
32
+
33
+ ## Future Feature Modules
34
+
35
+ Reusable features should be added as workspace packages and imported by apps as needed:
36
+
37
+ - `packages/core` for shared backend primitives
38
38
  - Additional packages for auth presets, guards, queues, mailers, etc.
@@ -1,56 +1,56 @@
1
- # MODULE SPEC
2
-
3
- ## Goal
4
-
5
- Define one repeatable fullstack pattern for Forgeon add-modules.
6
-
7
- Each feature module should be split into:
8
-
9
- 1. `@forgeon/<feature>-contracts`
10
- 2. `@forgeon/<feature>-api`
11
- 3. `@forgeon/<feature>-web`
12
-
13
- ## 1) Contracts Package
14
-
15
- Single source of truth shared by backend and frontend.
16
-
17
- Must contain:
18
-
19
- - DTO/request/response types
20
- - route constants (`API.<feature>.*`)
21
- - error codes (`<FEATURE>_*`)
22
- - shared constants (header/cookie names)
23
-
24
- Should contain:
25
-
26
- - zod schemas + inferred TS types
27
-
28
- ## 2) API Package
29
-
30
- NestJS module integrating contracts into backend runtime.
31
-
32
- Must contain:
33
-
34
- - module/service/controller
35
- - guards/strategies (if auth/security related)
36
- - config keys
37
- - minimal e2e test path
38
- - integration with `@forgeon/core` errors/logging
39
-
40
- ## 3) Web Package
41
-
42
- React integration layer for the same feature.
43
-
44
- Must contain:
45
-
46
- - provider/hooks/store
47
- - route guard (if feature requires auth/access)
48
- - API client helpers using contracts route constants/types
49
- - token/header/cookie wiring where relevant
50
-
51
- ## Acceptance Criteria
52
-
53
- - No duplicate route strings across api/web.
54
- - No duplicate error-code enums across api/web.
55
- - Contracts package can be imported from both sides without circular dependencies.
56
- - Module has docs under `docs/AI/MODULES/<module-id>.md`.
1
+ # MODULE SPEC
2
+
3
+ ## Goal
4
+
5
+ Define one repeatable fullstack pattern for Forgeon add-modules.
6
+
7
+ Each feature module should be split into:
8
+
9
+ 1. `@forgeon/<feature>-contracts`
10
+ 2. `@forgeon/<feature>-api`
11
+ 3. `@forgeon/<feature>-web`
12
+
13
+ ## 1) Contracts Package
14
+
15
+ Single source of truth shared by backend and frontend.
16
+
17
+ Must contain:
18
+
19
+ - DTO/request/response types
20
+ - route constants (`API.<feature>.*`)
21
+ - error codes (`<FEATURE>_*`)
22
+ - shared constants (header/cookie names)
23
+
24
+ Should contain:
25
+
26
+ - zod schemas + inferred TS types
27
+
28
+ ## 2) API Package
29
+
30
+ NestJS module integrating contracts into backend runtime.
31
+
32
+ Must contain:
33
+
34
+ - module/service/controller
35
+ - guards/strategies (if auth/security related)
36
+ - config keys
37
+ - minimal e2e test path
38
+ - integration with `@forgeon/core` errors/logging
39
+
40
+ ## 3) Web Package
41
+
42
+ React integration layer for the same feature.
43
+
44
+ Must contain:
45
+
46
+ - provider/hooks/store
47
+ - route guard (if feature requires auth/access)
48
+ - API client helpers using contracts route constants/types
49
+ - token/header/cookie wiring where relevant
50
+
51
+ ## Acceptance Criteria
52
+
53
+ - No duplicate route strings across api/web.
54
+ - No duplicate error-code enums across api/web.
55
+ - Contracts package can be imported from both sides without circular dependencies.
56
+ - Module has docs under `docs/AI/MODULES/<module-id>.md`.
@@ -1,32 +1,32 @@
1
- # PROJECT
2
-
3
- ## What This Repository Is
4
-
5
- A canonical fullstack monorepo scaffold intended to be reused as a project starter.
6
-
7
- ## Structure
8
-
9
- - `apps/api` - NestJS backend
10
- - `apps/web` - frontend scaffold (default React + Vite + TS)
11
- - `packages/core` - shared backend core placeholder
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
16
-
17
- ## Run Modes
18
-
19
- ### Dev mode
20
-
21
- ```bash
22
- pnpm install
23
- pnpm dev
24
- ```
25
-
26
- ### Docker mode
27
-
28
- ```bash
29
- docker compose --env-file infra/docker/.env.example -f infra/docker/compose.yml up --build
30
- ```
31
-
1
+ # PROJECT
2
+
3
+ ## What This Repository Is
4
+
5
+ A canonical fullstack monorepo scaffold intended to be reused as a project starter.
6
+
7
+ ## Structure
8
+
9
+ - `apps/api` - NestJS backend
10
+ - `apps/web` - frontend scaffold (default React + Vite + TS)
11
+ - `packages/core` - shared backend core placeholder
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
16
+
17
+ ## Run Modes
18
+
19
+ ### Dev mode
20
+
21
+ ```bash
22
+ pnpm install
23
+ pnpm dev
24
+ ```
25
+
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
32
  The API uses Prisma and expects `DATABASE_URL` from env.
@@ -1,58 +1,58 @@
1
- # TASKS
2
-
3
- ## Feature Discovery Matrix
4
-
5
- ```text
6
- Scan this monorepo and build a backend feature matrix by app/package.
7
- Use only evidence from code and dependencies.
8
- Output:
9
- 1) taxonomy by category
10
- 2) feature comparison table
11
- 3) common core
12
- 4) unique features
13
- 5) architectural inconsistencies
14
- Include file references for every feature.
15
- ```
16
-
17
- ## Add Module Package
18
-
19
- ```text
20
- Create a new reusable package under packages/ for <feature-name>.
21
- Requirements:
22
- - minimal API
23
- - NestJS-compatible module
24
- - docs in package README
25
- - wire into apps/api conditionally via env flag
26
- - keep backward compatibility
27
- ```
28
-
29
- ## Refactor Core
30
-
31
- ```text
32
- Move shared backend logic from apps/api into packages/core.
33
- Do not change behavior.
34
- Update imports, package dependencies, and docs.
35
- Run build checks and show changed files.
36
- ```
37
-
38
- ## Generate Preset
39
-
40
- ```text
41
- Create or update create-forgeon preset flow:
42
- - keep canonical stack fixed: NestJS + React + Prisma/Postgres + Docker
43
- - allow only runtime proxy choice: caddy/nginx/none
44
- - update generated docs fragments
45
- - update docs/AI/ARCHITECTURE.md and docs/AI/MODULE_SPEC.md when scope changes
46
- ```
47
-
48
- ## Add Fullstack Module
49
-
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
- ```
1
+ # TASKS
2
+
3
+ ## Feature Discovery Matrix
4
+
5
+ ```text
6
+ Scan this monorepo and build a backend feature matrix by app/package.
7
+ Use only evidence from code and dependencies.
8
+ Output:
9
+ 1) taxonomy by category
10
+ 2) feature comparison table
11
+ 3) common core
12
+ 4) unique features
13
+ 5) architectural inconsistencies
14
+ Include file references for every feature.
15
+ ```
16
+
17
+ ## Add Module Package
18
+
19
+ ```text
20
+ Create a new reusable package under packages/ for <feature-name>.
21
+ Requirements:
22
+ - minimal API
23
+ - NestJS-compatible module
24
+ - docs in package README
25
+ - wire into apps/api conditionally via env flag
26
+ - keep backward compatibility
27
+ ```
28
+
29
+ ## Refactor Core
30
+
31
+ ```text
32
+ Move shared backend logic from apps/api into packages/core.
33
+ Do not change behavior.
34
+ Update imports, package dependencies, and docs.
35
+ Run build checks and show changed files.
36
+ ```
37
+
38
+ ## Generate Preset
39
+
40
+ ```text
41
+ Create or update create-forgeon preset flow:
42
+ - keep canonical stack fixed: NestJS + React + Prisma/Postgres + Docker
43
+ - allow only runtime proxy choice: caddy/nginx/none
44
+ - update generated docs fragments
45
+ - update docs/AI/ARCHITECTURE.md and docs/AI/MODULE_SPEC.md when scope changes
46
+ ```
47
+
48
+ ## Add Fullstack Module
49
+
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
+ ```
58
58
 
@@ -1,6 +1,6 @@
1
- # Documentation Index
2
-
3
- - `AI/PROJECT.md` - project overview and run modes
4
- - `AI/ARCHITECTURE.md` - monorepo design and extension model
5
- - `AI/MODULE_SPEC.md` - fullstack module contract (`contracts/api/web`)
6
- - `AI/TASKS.md` - ready-to-use Codex prompts
1
+ # Documentation Index
2
+
3
+ - `AI/PROJECT.md` - project overview and run modes
4
+ - `AI/ARCHITECTURE.md` - monorepo design and extension model
5
+ - `AI/MODULE_SPEC.md` - fullstack module contract (`contracts/api/web`)
6
+ - `AI/TASKS.md` - ready-to-use Codex prompts
@@ -1,15 +1,15 @@
1
- :80 {
2
- encode gzip zstd
3
-
4
- route {
5
- handle /api/* {
6
- reverse_proxy api:3000
7
- }
8
-
9
- handle {
10
- root * /srv
11
- try_files {path} /index.html
12
- file_server
13
- }
14
- }
15
- }
1
+ :80 {
2
+ encode gzip zstd
3
+
4
+ route {
5
+ handle /api/* {
6
+ reverse_proxy api:3000
7
+ }
8
+
9
+ handle {
10
+ root * /srv
11
+ try_files {path} /index.html
12
+ file_server
13
+ }
14
+ }
15
+ }
@@ -1,10 +1,10 @@
1
- POSTGRES_USER=postgres
2
- POSTGRES_PASSWORD=postgres
3
- POSTGRES_DB=app
4
-
5
- PORT=3000
6
- DATABASE_URL=postgresql://postgres:postgres@db:5432/app?schema=public
7
-
8
- I18N_ENABLED=true
9
- I18N_DEFAULT_LANG=en
1
+ POSTGRES_USER=postgres
2
+ POSTGRES_PASSWORD=postgres
3
+ POSTGRES_DB=app
4
+
5
+ PORT=3000
6
+ DATABASE_URL=postgresql://postgres:postgres@db:5432/app?schema=public
7
+
8
+ I18N_ENABLED=true
9
+ I18N_DEFAULT_LANG=en
10
10
  I18N_FALLBACK_LANG=en