proteum 1.0.2 → 2.0.0

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 (185) hide show
  1. package/AGENTS.md +101 -0
  2. package/agents/codex/AGENTS.md +95 -0
  3. package/agents/codex/CODING_STYLE.md +71 -0
  4. package/agents/codex/agents.md.zip +0 -0
  5. package/agents/codex/client/AGENTS.md +102 -0
  6. package/agents/codex/client/pages/AGENTS.md +35 -0
  7. package/agents/codex/server/routes/AGENTS.md +12 -0
  8. package/agents/codex/server/services/AGENTS.md +137 -0
  9. package/agents/codex/tests/AGENTS.md +8 -0
  10. package/cli/app/config.ts +13 -11
  11. package/cli/app/index.ts +74 -82
  12. package/cli/bin.js +1 -1
  13. package/cli/commands/build.ts +51 -14
  14. package/cli/commands/check.ts +19 -0
  15. package/cli/commands/deploy/app.ts +4 -8
  16. package/cli/commands/deploy/web.ts +16 -20
  17. package/cli/commands/dev.ts +189 -64
  18. package/cli/commands/devEvents.ts +106 -0
  19. package/cli/commands/init.ts +63 -57
  20. package/cli/commands/lint.ts +21 -0
  21. package/cli/commands/refresh.ts +18 -0
  22. package/cli/commands/typecheck.ts +18 -0
  23. package/cli/compiler/client/identite.ts +80 -53
  24. package/cli/compiler/client/index.ts +139 -213
  25. package/cli/compiler/common/bundleAnalysis.ts +94 -0
  26. package/cli/compiler/common/clientManifest.ts +67 -0
  27. package/cli/compiler/common/controllers.ts +288 -0
  28. package/cli/compiler/common/files/autres.ts +7 -18
  29. package/cli/compiler/common/files/images.ts +40 -37
  30. package/cli/compiler/common/files/style.ts +11 -22
  31. package/cli/compiler/common/generatedRouteModules.ts +368 -0
  32. package/cli/compiler/common/index.ts +31 -65
  33. package/cli/compiler/common/loaders/forbid-ssr-import.js +13 -0
  34. package/cli/compiler/common/rspackAliases.ts +13 -0
  35. package/cli/compiler/common/scripts.ts +37 -0
  36. package/cli/compiler/index.ts +781 -230
  37. package/cli/compiler/server/index.ts +59 -75
  38. package/cli/compiler/writeIfChanged.ts +21 -0
  39. package/cli/index.ts +71 -72
  40. package/cli/paths.ts +51 -57
  41. package/cli/print.ts +17 -11
  42. package/cli/tsconfig.json +5 -4
  43. package/cli/utils/agents.ts +100 -0
  44. package/cli/utils/check.ts +71 -0
  45. package/cli/utils/index.ts +1 -3
  46. package/cli/utils/keyboard.ts +8 -25
  47. package/cli/utils/runProcess.ts +30 -0
  48. package/client/app/component.tsx +29 -29
  49. package/client/app/index.ts +36 -57
  50. package/client/app/service.ts +7 -12
  51. package/client/app.tsconfig.json +2 -2
  52. package/client/components/Dialog/Manager.ssr.tsx +40 -0
  53. package/client/components/Dialog/Manager.tsx +119 -150
  54. package/client/components/Dialog/status.tsx +3 -3
  55. package/client/components/index.ts +1 -1
  56. package/client/components/types.d.ts +1 -3
  57. package/client/dev/hmr.ts +65 -0
  58. package/client/global.d.ts +2 -2
  59. package/client/hooks.ts +6 -9
  60. package/client/index.ts +2 -1
  61. package/client/islands/index.ts +7 -0
  62. package/client/islands/useDeferredModule.ts +199 -0
  63. package/client/pages/_layout/index.tsx +4 -12
  64. package/client/pages/useHeader.tsx +14 -21
  65. package/client/router.ts +27 -0
  66. package/client/services/router/components/Link.tsx +34 -27
  67. package/client/services/router/components/Page.tsx +6 -14
  68. package/client/services/router/components/router.ssr.tsx +36 -0
  69. package/client/services/router/components/router.tsx +63 -83
  70. package/client/services/router/index.tsx +185 -220
  71. package/client/services/router/request/api.ts +97 -119
  72. package/client/services/router/request/history.ts +2 -2
  73. package/client/services/router/request/index.ts +13 -12
  74. package/client/services/router/request/multipart.ts +72 -62
  75. package/client/services/router/response/index.tsx +68 -61
  76. package/client/services/router/response/page.ts +28 -32
  77. package/client/utils/dom.ts +17 -33
  78. package/common/app/index.ts +3 -3
  79. package/common/data/chaines/index.ts +22 -23
  80. package/common/data/dates.ts +35 -70
  81. package/common/data/markdown.ts +42 -39
  82. package/common/dev/serverHotReload.ts +26 -0
  83. package/common/errors/index.tsx +110 -142
  84. package/common/router/contracts.ts +29 -0
  85. package/common/router/index.ts +89 -108
  86. package/common/router/layouts.ts +34 -47
  87. package/common/router/pageSetup.ts +50 -0
  88. package/common/router/register.ts +53 -24
  89. package/common/router/request/api.ts +30 -36
  90. package/common/router/request/index.ts +2 -8
  91. package/common/router/response/index.ts +8 -15
  92. package/common/router/response/page.ts +70 -58
  93. package/common/utils.ts +1 -1
  94. package/doc/TODO.md +1 -1
  95. package/eslint.js +62 -0
  96. package/package.json +12 -47
  97. package/prettier.config.cjs +9 -0
  98. package/scripts/cleanup-generated-controllers.ts +62 -0
  99. package/scripts/fix-reference-app-typing.ts +490 -0
  100. package/scripts/refactor-client-app-imports.ts +244 -0
  101. package/scripts/refactor-client-pages.ts +587 -0
  102. package/scripts/refactor-server-controllers.ts +470 -0
  103. package/scripts/refactor-server-runtime-aliases.ts +360 -0
  104. package/scripts/restore-client-app-import-files.ts +41 -0
  105. package/scripts/restore-files-from-git-head.ts +20 -0
  106. package/scripts/update-codex-agents.ts +35 -0
  107. package/server/app/commands.ts +35 -64
  108. package/server/app/container/config.ts +48 -59
  109. package/server/app/container/console/index.ts +202 -248
  110. package/server/app/container/index.ts +33 -71
  111. package/server/app/controller/index.ts +61 -0
  112. package/server/app/index.ts +39 -105
  113. package/server/app/service/container.ts +41 -42
  114. package/server/app/service/index.ts +120 -147
  115. package/server/context.ts +1 -1
  116. package/server/index.ts +25 -1
  117. package/server/services/auth/index.ts +75 -115
  118. package/server/services/auth/router/index.ts +31 -32
  119. package/server/services/auth/router/request.ts +14 -16
  120. package/server/services/cron/CronTask.ts +13 -26
  121. package/server/services/cron/index.ts +14 -36
  122. package/server/services/disks/driver.ts +40 -58
  123. package/server/services/disks/drivers/local/index.ts +79 -90
  124. package/server/services/disks/drivers/s3/index.ts +116 -163
  125. package/server/services/disks/index.ts +23 -38
  126. package/server/services/email/index.ts +45 -104
  127. package/server/services/email/utils.ts +14 -27
  128. package/server/services/fetch/index.ts +53 -85
  129. package/server/services/prisma/Facet.ts +39 -91
  130. package/server/services/prisma/index.ts +74 -110
  131. package/server/services/router/generatedRuntime.ts +29 -0
  132. package/server/services/router/http/index.ts +78 -73
  133. package/server/services/router/http/multipart.ts +19 -42
  134. package/server/services/router/index.ts +378 -365
  135. package/server/services/router/request/api.ts +26 -25
  136. package/server/services/router/request/index.ts +44 -51
  137. package/server/services/router/request/service.ts +7 -11
  138. package/server/services/router/request/validation/zod.ts +111 -148
  139. package/server/services/router/response/index.ts +110 -125
  140. package/server/services/router/response/mask/Filter.ts +31 -72
  141. package/server/services/router/response/mask/index.ts +8 -15
  142. package/server/services/router/response/mask/selecteurs.ts +11 -25
  143. package/server/services/router/response/page/clientManifest.ts +25 -0
  144. package/server/services/router/response/page/document.tsx +199 -127
  145. package/server/services/router/response/page/index.tsx +89 -94
  146. package/server/services/router/service.ts +13 -15
  147. package/server/services/schema/index.ts +17 -26
  148. package/server/services/schema/request.ts +19 -33
  149. package/server/services/schema/router/index.ts +8 -11
  150. package/server/services/security/encrypt/aes/index.ts +15 -35
  151. package/server/utils/slug.ts +29 -35
  152. package/skills/clean-project-code/SKILL.md +63 -0
  153. package/skills/clean-project-code/agents/openai.yaml +4 -0
  154. package/tsconfig.common.json +4 -3
  155. package/tsconfig.json +4 -1
  156. package/types/aliases.d.ts +17 -21
  157. package/types/controller-input.test.ts +48 -0
  158. package/types/express-extra.d.ts +6 -0
  159. package/types/global/constants.d.ts +13 -0
  160. package/types/global/express-extra.d.ts +6 -0
  161. package/types/global/modules.d.ts +13 -16
  162. package/types/global/utils.d.ts +17 -49
  163. package/types/global/vendors.d.ts +62 -0
  164. package/types/icons.d.ts +65 -1
  165. package/types/uuid.d.ts +3 -0
  166. package/types/vendors.d.ts +62 -0
  167. package/cli/compiler/common/babel/index.ts +0 -170
  168. package/cli/compiler/common/babel/plugins/index.ts +0 -0
  169. package/cli/compiler/common/babel/plugins/services.ts +0 -586
  170. package/cli/compiler/common/babel/routes/imports.ts +0 -127
  171. package/cli/compiler/common/babel/routes/routes.ts +0 -1130
  172. package/client/services/captcha/index.ts +0 -67
  173. package/client/services/socket/index.ts +0 -147
  174. package/common/data/rte/nodes.ts +0 -83
  175. package/common/data/stats.ts +0 -90
  176. package/common/utils/rte.ts +0 -183
  177. package/server/services/auth/old.ts +0 -277
  178. package/server/services/cache/commands.ts +0 -41
  179. package/server/services/cache/index.ts +0 -297
  180. package/server/services/cache/service.json +0 -6
  181. package/server/services/socket/index.ts +0 -162
  182. package/server/services/socket/scope.ts +0 -226
  183. package/server/services/socket/service.json +0 -6
  184. package/server/services_old/SocketClient.ts +0 -92
  185. package/server/services_old/Token.old.ts +0 -97
package/AGENTS.md ADDED
@@ -0,0 +1,101 @@
1
+ # Proteum Framework
2
+
3
+ ## Vision
4
+
5
+ Proteum aims to become the first SSR / SEO / TypeScript framework built primarily for non-human developers and AI agents.
6
+
7
+ The framework should maximize LLM efficiency, correctness, determinism, and performance when building Proteum-based projects.
8
+
9
+ When tradeoffs exist, prioritize framework decisions in this order:
10
+
11
+ 1. Reduce shipped client bundle size and unnecessary runtime code.
12
+ 2. Increase build-time, server-time, and browser-time performance.
13
+ 3. Improve SEO output and LLM-friendly, crawlable, semantic HTML.
14
+ 4. Preserve explicit, typed, machine-readable contracts for agents.
15
+
16
+ When working on Proteum itself, optimize for agent ergonomics first:
17
+
18
+ - Prefer explicit, typed, machine-readable contracts over implicit runtime magic, hidden conventions, ambient globals, or tribal knowledge.
19
+ - Make routes, data loading, server actions / controllers, services, SEO metadata, sitemap generation, static generation, and environment contracts easy to discover, inspect, and explain.
20
+ - Treat SSR and SEO as first-class framework primitives, not app-level patchwork.
21
+ - Prefer server-first designs that avoid shipping client JavaScript unless it is required for user-facing behavior.
22
+ - Favor small, single-purpose files and modules that reduce context load and make edits easier for agents to scope safely.
23
+ - Generated code should improve traceability and type safety, not obscure behavior. It should be deterministic, auditable, and easy for agents to map back to source files.
24
+ - Prefer exact end-to-end contracts for inputs, outputs, errors, side effects, and caching behavior.
25
+ - Prefer framework features that make impact analysis, verification, and debugging easier for agents.
26
+ - Prefer output that is fast to render, easy to crawl, semantically rich, and easy for LLMs to parse reliably.
27
+ - Avoid introducing abstractions that require broad codebase memory to use correctly.
28
+
29
+ When proposing or implementing a core change, evaluate it against this question:
30
+
31
+ - Does this make Proteum easier for an AI agent to understand, modify, verify, and operate with high confidence?
32
+
33
+ # Workflow
34
+
35
+ - Everytime I input error messages without any instructions, don't implement fixes.
36
+ Instead, ivestigate the potential causes of the errors, and for each:
37
+ 1. Evaluate / quantify the probabiliies
38
+ 2. Give why and
39
+ 3. Suggest how to fix it
40
+ - When you have finished your work, summarize in one top-level short sentence ALL the changes you made since the beginning of the WHOLE conversation. Output as "Commit message". Max 90 characters.
41
+
42
+ ## Framework Workflow
43
+
44
+ When changing Proteum itself, always ground the work in the real apps that use it.
45
+
46
+ - Treat these two projects as the reference surface for current Proteum usage and needs:
47
+ - `/Users/gaetan/Desktop/Projets/crosspath/platform`
48
+ - `/Users/gaetan/Desktop/Projets/unique.domains/website`
49
+ - Before proposing a framework change, inspect how both apps currently use the feature, runtime, API, compiler behavior, or generated files involved.
50
+ - Prefer removing framework magic when the same result can be expressed with explicit runtime contracts, generated code, or typed context.
51
+ - If a webpack plugin, Babel plugin, alias, helper, runtime service, or npm package is not meaningfully used by both reference apps, challenge its existence and prefer deleting it.
52
+
53
+ ## Current Proteum Direction
54
+
55
+ Future changes should preserve and extend the current explicit model instead of reintroducing runtime magic.
56
+
57
+ - Server route entrypoints live in `*.controller.ts` files.
58
+ - Controllers extend `Controller` and read request-scoped values from `this.request`.
59
+ - Controllers validate request input via `this.input(schema)` inside the method body. Do not use decorators for validation metadata.
60
+ - Normal services extend `Service` and should use `this.services`, `this.models`, and `this.app` instead of implicit globals or magic imports.
61
+ - Do not reintroduce runtime server imports or globals such as `@request`, `@models`, or `@app`.
62
+ - Client pages use `Router.page(path, render)` or `Router.page(path, setup, render)`.
63
+ - SSR data loading belongs in the `setup` function returned object, not in `api.fetch(...)`.
64
+ - Client-side controller access should come from the generated controller tree and client context, not from fake runtime imports.
65
+
66
+ ## Solution Proposals
67
+
68
+ When presenting a framework solution, make it easy to judge against the real apps.
69
+
70
+ - Start from the actual mismatch or risk seen in the apps, not from abstract framework theory.
71
+ - Show the target API with concrete client and server usage examples that match current Proteum conventions.
72
+ - Distinguish:
73
+ - the ideal end-state API
74
+ - any transitional migration rule or guardrail
75
+ - Call out what becomes impossible or safer after the change.
76
+ - If the change affects generated code, explain what source files drive generation and what artifacts are produced.
77
+ - If the change removes older behavior, explicitly name what is being deleted and why it is obsolete.
78
+
79
+ ## Implementation Rules
80
+
81
+ - Keep framework changes aligned with the explicit controller/page architecture already adopted in the reference apps.
82
+ - Prefer deleting client-side code, dependencies, and emitted assets when the same capability can stay on the server or be generated statically.
83
+ - Prefer deleting obsolete branches, compatibility layers, plugins, and dependencies over keeping dead paths around.
84
+ - Prefer compiler logic that is deterministic, auditable, and easy for another agent to trace from source to generated output.
85
+ - Reject changes that increase bundle size, runtime cost, or crawlability risk unless the benefit is concrete and validated in both reference apps.
86
+ - When removing old behavior, also remove the related packages, config flags, typings, docs, and dead helper files in the same pass when safe.
87
+ - If a core change breaks one of the reference apps, keep iterating until the framework and the affected app usage are both corrected.
88
+
89
+ ## Real-World Validation
90
+
91
+ Do not stop at static analysis or isolated core compilation when the change affects runtime behavior.
92
+
93
+ - Validate framework changes against the two reference apps whenever the change touches routing, controllers, generated code, SSR, client runtime, services, webpack, Babel, or emitted assets.
94
+ - Preferred runtime validation:
95
+ - run `npx proteum dev --no-cache -port 3xxx` in both apps on explicit ports
96
+ - open the real pages with Playwright
97
+ - inspect browser console errors and warnings
98
+ - inspect server startup and runtime errors
99
+ - Build-only checks are not sufficient for runtime/compiler changes. Use them as supplements, not as the final proof.
100
+ - Keep fixing regressions exposed by the dev-server and browser pass until both apps boot and the browser console shows no new real errors.
101
+ - Treat external/local-environment warnings separately from framework regressions, and say clearly when something is unrelated to the current change.
@@ -0,0 +1,95 @@
1
+ # Architecture
2
+
3
+ This is a full stack monolith project using Typescript, NodeJS, Preact, and Proteum.
4
+
5
+ `/client`: frontend
6
+ `/assets`: CSS, images and other frontend assets
7
+ `/components`: reusable components
8
+ `/pages`: page route files and page-local UI
9
+ `/hooks`
10
+ `/common`: shared functions, constants and typings
11
+ `/server`: backend
12
+ `/config`: service configuration
13
+ `/services`: backend services and controllers
14
+ `/routes`: explicit non-controller routes
15
+ `/lib`: helper functions
16
+ `/tests`
17
+
18
+ # Coding style
19
+
20
+ See `CODING_STYLE.md`.
21
+ This file is the source of truth for formatting, section-comment structure, and general coding style.
22
+
23
+ # Files organization
24
+
25
+ - Always keep one class / react component per file
26
+ - Prefer a deep tree structure that groups files by business concern instead of long file names
27
+ - The default `*.ts` / `*.tsx` file is the browser implementation; use `*.ssr.ts` / `*.ssr.tsx` only for SSR-safe fallbacks
28
+
29
+ ## Centralize feature catalogs (Single Source of Truth)
30
+
31
+ When implementing a feature that relies on a **curated list of items**, keep **one canonical catalog/registry file** and make all other code import it.
32
+
33
+ ## Runtime access rules
34
+
35
+ - `@models/types`: Prisma typings only. Can be imported anywhere.
36
+ - Never use runtime value imports from `@request` or `@models`.
37
+ - Never expose request-scoped state through imports.
38
+
39
+ ## Client runtime access
40
+
41
+ - Page route files use `Router.page(...)`.
42
+ - `Router.page(path, render)` for pages without SSR setup.
43
+ - `Router.page(path, setup, render)` for pages with SSR config/data.
44
+ - `setup` receives the normal page context plus the generated controller tree spread into it.
45
+ - `render` receives the normal page context plus the resolved setup data and the same controller tree spread into it.
46
+ - Components and hooks use `useContext()` to access controller instances and client runtime services.
47
+
48
+ ## Server runtime access
49
+
50
+ - Normal business logic lives in `/server/services/**/index.ts` classes that extend `Service`.
51
+ - Route entrypoints live in `*.controller.ts` classes that extend `Controller`.
52
+ - Only controller files are indexed as callable API endpoints.
53
+ - Controller methods validate input with `this.input(schema)` and access request scope through `this.request`.
54
+ - Service classes access other services via `this.services` and prisma models via `this.models`.
55
+ - Never use request-scoped state directly inside normal service methods.
56
+
57
+ # Agent behavior
58
+
59
+ **Make sure the code you generate integrates perfectly with the current codebase by avoiding repetition and centralizing each purpose.**
60
+
61
+ ## Typings
62
+
63
+ - Fix typing issues only on the code you wrote.
64
+ - Never cast with `as any` or `as unknown`; fix the type contract or introduce an explicit typed adapter instead. If you find no other solution, tell me in the output.
65
+
66
+ ## Workflow
67
+
68
+ - Everytime I input error messages without any instructions, don't implement fixes.
69
+ Instead, ivestigate the potential causes of the errors, and for each:
70
+ 1. Evaluate / quantify the probabiliies
71
+ 2. Give why and
72
+ 3. Suggest how to fix it
73
+ - When you have finished your work, summarize in one top-level short sentence the changes you made since the beginning of the conversation. Output as "Commit message".
74
+
75
+ ## Never edit the following files
76
+
77
+ - Prisma files (except schema.prisma)
78
+ - tsconfigs
79
+ - env
80
+ - Any file / folder that is a symbolic link
81
+
82
+ If you need to edit them, just suggest it in the chat.
83
+
84
+ ## Don't run any of these commands
85
+
86
+ ```
87
+ git restore
88
+ git reset
89
+ prisma *
90
+ And any git command in the write mode.
91
+ ```
92
+
93
+ # Copy and UX
94
+
95
+ Before making UX/copy decisions, read `docs/PERSONAS.md`, `docs/PRODUCT.md`, `docs/MARKETING.md`.
@@ -0,0 +1,71 @@
1
+ # Coding style
2
+
3
+ This file is the source of truth for codex coding style instructions in Proteum-based projects.
4
+
5
+ ## Baseline
6
+
7
+ - **The code should be at the highest level of industry, as the product will be used by GAFAMs and will be maintained by a team of 10 developers.**
8
+ - Write clean, consistent, readable code with a tab size of 4.
9
+ - Keep functions and methods short.
10
+ - Everytime possible, create reusable functions and components instead of repeating.
11
+
12
+ ## Formatting
13
+
14
+ - Optimize for human readability while keeping the code vertically compact when horizontal space is available.
15
+ - Preserve the high-level shape of function calls instead of exploding arguments too early.
16
+ - Keep short arrow functions and short returned object literals compact when they are easy to scan.
17
+ - Keep JSX multiline only when it is clearly more readable; otherwise keep short JSX compact.
18
+ - Avoid staircase formatting and unnecessary blank lines inside short callbacks.
19
+
20
+ ## File organization
21
+
22
+ - Always keep one class or react component per file.
23
+ - Prefer a deep tree structure that groups files by business concern instead of long file names.
24
+ - The default `*.ts` / `*.tsx` file is the browser implementation; use `*.ssr.ts` / `*.ssr.tsx` only for SSR-safe fallbacks.
25
+ - When implementing a feature that relies on a curated list of items, keep one canonical catalog or registry file and make all other code import it.
26
+
27
+ ## Section comments and simple comments
28
+
29
+ - Organize files with explicit banner comments:
30
+
31
+ ```typescript
32
+ /*----------------------------------
33
+ - SECTION NAME
34
+ ----------------------------------*/
35
+ ```
36
+
37
+ - Reuse project-native section names when possible, especially:
38
+ - `DEPENDANCES`
39
+ - `TYPES`
40
+ - `HELPERS`
41
+ - `CONSTANTS`
42
+ - `COMPONENT`
43
+ - `SERVICE`
44
+ - `CONTROLEUR`
45
+ - `ROUTES`
46
+ - `PAGE`
47
+ - `CONFIG`
48
+ - `PUBLIC API`
49
+ - `API`
50
+ - `HOOKS`
51
+ - `LAYOUT`
52
+ - `CLASS`
53
+ - `MODULE`
54
+ - `STATE`
55
+ - `CONTEXT`
56
+ - `QUERIES`
57
+ - `SCHEMA`
58
+ - `SCHEMAS`
59
+ - `ROUTING`
60
+ - `RENDER`
61
+ - `EXPORTS`
62
+ - `UTILS`
63
+ - `CONTENT`
64
+ - `FILTERS`
65
+ - `STATS`
66
+ - `BUILDERS`
67
+ - `CATALOG`
68
+ - `CATALOG (SSOT)`
69
+ - File-specific section names are allowed when they improve navigation, for example `ROUTE: ...`, `COMPONENT: ...`, or `VIEW: ...`.
70
+ - Add short, useful comments that explain grouping, intent, lifecycle, or why a block exists.
71
+ - Do not add noisy comments that simply restate obvious code.
Binary file
@@ -0,0 +1,102 @@
1
+ # Frontend designing
2
+
3
+ UI components are defined in `/client/pages` and `/client/components`.
4
+
5
+ ## Stack
6
+
7
+ - Typescript strict
8
+ - Preact with SSR
9
+ - Base UI
10
+ - `@/client/components/Motion`
11
+ - Tailwind CSS 4
12
+
13
+ Don't use React.useCallback unless strictly necessary.
14
+
15
+ ## Communicate with the server
16
+
17
+ ### Pages
18
+
19
+ Pages use `Router.page(...)`.
20
+
21
+ Use `Router.page(path, render)` when there is no SSR setup.
22
+
23
+ Use `Router.page(path, setup, render)` when the page needs SSR config or SSR data:
24
+
25
+ ```typescript
26
+ Router.page('/dashboard/example', ({ Missions }) => ({
27
+ _auth: 'USER',
28
+ missions: Missions.Get(),
29
+ }), ({ request, missions, Missions }) => {
30
+ return <Page missions={missions} />;
31
+ });
32
+ ```
33
+
34
+ - `setup` returns one flat object
35
+ - keys like `_auth`, `_layout`, `_priority` are route config
36
+ - all other keys are SSR data fetchers
37
+ - never use `api.fetch(...)` in page files
38
+
39
+ ### Components and hooks
40
+
41
+ Components and hooks access controllers through `useContext()`:
42
+
43
+ ```typescript
44
+ const { Auth, Domains } = useContext();
45
+ ```
46
+
47
+ Then call controller methods directly:
48
+
49
+ ```typescript
50
+ Auth.Signup(data).then((result) => {
51
+ ...
52
+ });
53
+ ```
54
+
55
+ ### Async calls
56
+
57
+ - Prefer direct controller calls from the context or page render args
58
+ - The thrown errors will automatically be displayed to the user, so don't silent them
59
+ - Never depend on legacy `@app` imports on the client
60
+
61
+ ## Errors handling
62
+
63
+ Errors catched from controller calls should never be silented.
64
+ If a catch is needed, rethrow or surface the failure clearly.
65
+
66
+ ## Design
67
+
68
+ - Beautiful, modern, minimalist and intuitive design
69
+ - Responsive layout
70
+ - Enhance the UX with meaningful animations
71
+
72
+ ## Rules
73
+
74
+ - Always import React in react files (`.tsx`)
75
+ - Don't use any component from `@client/components` unless the codebase already does in that area
76
+ - To create a link / button, always use the `Link` component when the codebase expects navigation links
77
+
78
+ ## Keep the code organized
79
+
80
+ - Split big components (more than 1000 lines) into smaller components
81
+ - Always use one component per file
82
+ - Everytime possible, load data and define action handlers in the directly concerned component instead of passing everything from the parent
83
+
84
+ ## Split the page by sections via comments
85
+
86
+ Use:
87
+
88
+ ```typescript
89
+ /*----------------------------------
90
+ - SECTION NAME
91
+ ----------------------------------*/
92
+ ```
93
+
94
+ File sections:
95
+ - DEPENDENCIES
96
+ - TYPES
97
+ - COMPONENT / PAGE
98
+
99
+ Component / page sections:
100
+ - INIT
101
+ - ACTIONS
102
+ - RENDER
@@ -0,0 +1,35 @@
1
+ # Page files
2
+
3
+ Page files are located in `/client/pages/**/*.tsx`.
4
+
5
+ ## Router.page contract
6
+
7
+ Use one of these forms:
8
+
9
+ ```typescript
10
+ Router.page('/path', ({ request, ServiceName }) => {
11
+ return <Page />;
12
+ });
13
+ ```
14
+
15
+ ```typescript
16
+ Router.page('/path', ({ ServiceName }) => ({
17
+ _auth: 'USER',
18
+ dataKey: ServiceName.MethodName({ param1: 'value' }),
19
+ }), ({ request, dataKey, ServiceName }) => {
20
+ return <Page data={dataKey} />;
21
+ });
22
+ ```
23
+
24
+ - `setup` is the second `Router.page` argument
25
+ - `render` is the last `Router.page` argument
26
+ - `setup` receives the page context plus generated controller instances
27
+ - `render` receives the page context, resolved setup data, and generated controller instances
28
+ - Never use `api.fetch(...)` in page files
29
+ - Never import client service values from `@app`
30
+
31
+ ## Typings
32
+
33
+ - Treat generated controller method typings as the source of truth
34
+ - Never cast controller methods, their parameters, or their return types
35
+ - If a page needs route data, return it from `setup` and consume it from `render`
@@ -0,0 +1,12 @@
1
+ # Server routes
2
+
3
+ Use `/server/routes/**` only for explicit custom routes that should not be generated from controllers.
4
+
5
+ - Callable app APIs belong in `*.controller.ts` files under `/server/services`
6
+ - `/server/routes/**` is for manual `Router.get/post/...` routes, redirects, resources, OAuth callbacks, etc.
7
+
8
+ ## Generate absolute urls
9
+
10
+ The absolute urls are generated via `Router.url()`:
11
+
12
+ `const absoluteUrl = Router.url('/relative/path')`
@@ -0,0 +1,137 @@
1
+ # Server Services
2
+
3
+ Stack:
4
+ - Typescript with strict mode
5
+ - NodeJS
6
+ - Prisma 7 ORM
7
+
8
+ ## 1. Create the service file in `/server/services/<service name>/index.ts`
9
+
10
+ Template:
11
+
12
+ ```typescript
13
+ /*----------------------------------
14
+ - DEPENDANCE
15
+ ----------------------------------*/
16
+
17
+ // Core libs
18
+ import Service from '@server/app/service';
19
+
20
+ /*----------------------------------
21
+ - TYPES
22
+ ----------------------------------*/
23
+
24
+ export type Config = <ServiceConfig>;
25
+
26
+ /*----------------------------------
27
+ - SERVICE
28
+ ----------------------------------*/
29
+
30
+ export default class ServiceName extends Service<Config, {}, CrossPath, CrossPath> {
31
+
32
+ public async MethodName(data: { param1: string }) {
33
+ const { OtherService } = this.services;
34
+
35
+ return OtherService.OtherMethod(data);
36
+ }
37
+ }
38
+ ```
39
+
40
+ `<ServiceConfig>` is an object containing api keys and other variables we can adjust in the future.
41
+
42
+ ## 2. Create the controller file in `/server/services/<service name>/<ServiceName>.controller.ts`
43
+
44
+ Template:
45
+
46
+ ```typescript
47
+ import Controller, { schema } from '@server/app/controller';
48
+ import type { TMethodInput } from './index';
49
+
50
+ const MethodInput = schema.object({
51
+ param1: schema.string(),
52
+ });
53
+
54
+ export default class ServiceNameController extends Controller {
55
+
56
+ public async MethodName() {
57
+ const data = this.input(MethodInput);
58
+ const { ServiceName } = this.services;
59
+ const { auth, request, user } = this.request;
60
+
61
+ return ServiceName.MethodName(data);
62
+ }
63
+ }
64
+ ```
65
+
66
+ Rules:
67
+ - Only `*.controller.ts` files are indexed as callable API endpoints
68
+ - Route path is derived from the controller file path and the method name
69
+ - `this.input(schema)` is the only validation entrypoint
70
+ - Call `this.input(...)` at most once per controller method
71
+ - Request-scoped state exists only on `this.request`
72
+
73
+ ## 3. Create the service metas file in `/server/services/<service name>/service.json`
74
+
75
+ ```json
76
+ {
77
+ "id": "CrossPath/ServiceName",
78
+ "name": "CrossPathServiceName",
79
+ "parent": "app",
80
+ "dependences": []
81
+ }
82
+ ```
83
+
84
+ ## 4. Register the service in `/server/config/<app>.ts`
85
+
86
+ ```typescript
87
+ app.setup('ServiceName', 'CrossPath/ServiceName', <ServiceConfig>);
88
+ ```
89
+
90
+ ## 5. Keep classes clean
91
+
92
+ If the class grows too large, split business concerns into subservices.
93
+
94
+ ## 6. Use request-aware features only in controllers
95
+
96
+ Use:
97
+
98
+ ```typescript
99
+ const { auth, request, user, response } = this.request;
100
+ ```
101
+
102
+ - Never import runtime request state from `@request`
103
+ - Never access request-scoped state inside normal service methods unless the controller passes the minimal values explicitly
104
+
105
+ ## 7. Fetch and return data from the database
106
+
107
+ Use runtime models through `this.models`:
108
+
109
+ ```typescript
110
+ const users = await this.models.user.findMany({
111
+ select: {
112
+ id: true,
113
+ },
114
+ });
115
+ ```
116
+
117
+ Use prisma typings through `@models/types` only:
118
+
119
+ ```typescript
120
+ import type * as Models from '@models/types';
121
+ ```
122
+
123
+ Rules:
124
+ - Never edit prisma files, except the schema
125
+ - Never use runtime `@models` imports
126
+ - In all queries and joins, always specify what fields to select
127
+
128
+ ## DTO and typing rules
129
+
130
+ - Prefer inferred return types:
131
+ `export type TResult = Awaited<ReturnType<MyService["MethodName"]>>;`
132
+ - Never create manual DTO types when the exact return type can be inferred
133
+
134
+ ## Errors handling
135
+
136
+ Unhandled errors are passed to the `bug` app hook.
137
+ Never silent caught errors. Throw `Anomaly` with enough detail and the original error when needed.
@@ -0,0 +1,8 @@
1
+ # Codex guidance for writing E2E tests
2
+
3
+ - Understand the typical user flow and the main feature branches
4
+ - Favor as many tests as possible to cover real usage
5
+ - Always locate elements via their `data-testid` attribute
6
+ - Add `data-testid` where needed
7
+ - Keep test files clean, organized and structured
8
+ - Test the current controller/page runtime model, not legacy `@Route` or `api.fetch` behavior
package/cli/app/config.ts CHANGED
@@ -21,15 +21,13 @@ import type { TEnvConfig } from '../../server/app/container/config';
21
21
  - LOADE
22
22
  ----------------------------------*/
23
23
  export default class ConfigParser {
24
-
25
24
  public constructor(
26
25
  public appDir: string,
27
- public envName?: string
28
- ) {
29
-
30
- }
26
+ public envName?: string,
27
+ public routerPortOverride?: number,
28
+ ) {}
31
29
 
32
- private loadYaml( filepath: string ) {
30
+ private loadYaml(filepath: string) {
33
31
  console.info(`Loading config ${filepath}`);
34
32
  const rawConfig = fs.readFileSync(filepath, 'utf-8');
35
33
  return yaml.parse(rawConfig);
@@ -38,17 +36,21 @@ export default class ConfigParser {
38
36
  public env(): TEnvConfig {
39
37
  // We assume that when we run 5htp dev, we're in local
40
38
  // Otherwise, we're in production environment (docker)
41
- console.log("[app] Using environment:", process.env.NODE_ENV);
39
+ console.log('[app] Using environment:', process.env.NODE_ENV);
42
40
  const envFileName = this.appDir + '/env.yaml';
43
- const envFile = this.loadYaml( envFileName );
41
+ const envFile = this.loadYaml(envFileName);
44
42
  return {
45
43
  ...envFile,
46
- version: 'CLI'
47
- }
44
+ router:
45
+ this.routerPortOverride === undefined
46
+ ? envFile.router
47
+ : { ...envFile.router, port: this.routerPortOverride },
48
+ version: 'CLI',
49
+ };
48
50
  }
49
51
 
50
52
  public identity() {
51
53
  const identityFile = this.appDir + '/identity.yaml';
52
- return this.loadYaml( identityFile );
54
+ return this.loadYaml(identityFile);
53
55
  }
54
56
  }