proteum 1.0.3 → 2.0.0-1
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.
- package/AGENTS.md +92 -0
- package/agents/codex/AGENTS.md +95 -0
- package/agents/codex/CODING_STYLE.md +71 -0
- package/agents/codex/agents.md.zip +0 -0
- package/agents/codex/client/AGENTS.md +102 -0
- package/agents/codex/client/pages/AGENTS.md +35 -0
- package/agents/codex/server/routes/AGENTS.md +12 -0
- package/agents/codex/server/services/AGENTS.md +137 -0
- package/agents/codex/tests/AGENTS.md +8 -0
- package/cli/app/config.ts +12 -17
- package/cli/app/index.ts +59 -99
- package/cli/bin.js +1 -1
- package/cli/commands/build.ts +23 -12
- package/cli/commands/check.ts +19 -0
- package/cli/commands/deploy/app.ts +4 -8
- package/cli/commands/deploy/web.ts +16 -20
- package/cli/commands/dev.ts +185 -75
- package/cli/commands/devEvents.ts +106 -0
- package/cli/commands/init.ts +63 -57
- package/cli/commands/lint.ts +21 -0
- package/cli/commands/refresh.ts +6 -6
- package/cli/commands/typecheck.ts +18 -0
- package/cli/compiler/client/identite.ts +79 -49
- package/cli/compiler/client/index.ts +132 -214
- package/cli/compiler/common/bundleAnalysis.ts +94 -0
- package/cli/compiler/common/clientManifest.ts +67 -0
- package/cli/compiler/common/controllers.ts +288 -0
- package/cli/compiler/common/files/autres.ts +7 -18
- package/cli/compiler/common/files/images.ts +40 -37
- package/cli/compiler/common/files/style.ts +12 -25
- package/cli/compiler/common/generatedRouteModules.ts +368 -0
- package/cli/compiler/common/index.ts +29 -68
- package/cli/compiler/common/loaders/forbid-ssr-import.js +13 -0
- package/cli/compiler/common/rspackAliases.ts +13 -0
- package/cli/compiler/common/scripts.ts +37 -0
- package/cli/compiler/index.ts +764 -234
- package/cli/compiler/server/index.ts +52 -77
- package/cli/compiler/writeIfChanged.ts +21 -0
- package/cli/index.ts +65 -90
- package/cli/paths.ts +51 -57
- package/cli/print.ts +17 -11
- package/cli/tsconfig.json +5 -4
- package/cli/utils/agents.ts +100 -0
- package/cli/utils/check.ts +71 -0
- package/cli/utils/index.ts +1 -3
- package/cli/utils/keyboard.ts +8 -25
- package/cli/utils/runProcess.ts +30 -0
- package/client/app/component.tsx +29 -29
- package/client/app/index.ts +36 -57
- package/client/app/service.ts +7 -12
- package/client/app.tsconfig.json +2 -2
- package/client/components/Dialog/Manager.ssr.tsx +40 -0
- package/client/components/Dialog/Manager.tsx +119 -150
- package/client/components/Dialog/status.tsx +3 -3
- package/client/components/index.ts +1 -1
- package/client/components/types.d.ts +1 -3
- package/client/dev/hmr.ts +65 -0
- package/client/global.d.ts +2 -2
- package/client/hooks.ts +6 -9
- package/client/index.ts +2 -1
- package/client/islands/index.ts +7 -0
- package/client/islands/useDeferredModule.ts +199 -0
- package/client/pages/_layout/index.tsx +4 -12
- package/client/pages/useHeader.tsx +14 -21
- package/client/router.ts +27 -0
- package/client/services/router/components/Link.tsx +34 -27
- package/client/services/router/components/Page.tsx +6 -14
- package/client/services/router/components/router.ssr.tsx +36 -0
- package/client/services/router/components/router.tsx +63 -83
- package/client/services/router/index.tsx +185 -220
- package/client/services/router/request/api.ts +97 -119
- package/client/services/router/request/history.ts +2 -2
- package/client/services/router/request/index.ts +13 -12
- package/client/services/router/request/multipart.ts +72 -62
- package/client/services/router/response/index.tsx +68 -61
- package/client/services/router/response/page.ts +28 -32
- package/client/utils/dom.ts +17 -33
- package/common/app/index.ts +3 -3
- package/common/data/chaines/index.ts +22 -23
- package/common/data/dates.ts +35 -70
- package/common/data/markdown.ts +42 -39
- package/common/dev/serverHotReload.ts +26 -0
- package/common/errors/index.tsx +110 -142
- package/common/router/contracts.ts +29 -0
- package/common/router/index.ts +89 -108
- package/common/router/layouts.ts +34 -47
- package/common/router/pageSetup.ts +50 -0
- package/common/router/register.ts +53 -24
- package/common/router/request/api.ts +30 -36
- package/common/router/request/index.ts +2 -8
- package/common/router/response/index.ts +8 -15
- package/common/router/response/page.ts +70 -58
- package/common/utils.ts +1 -1
- package/eslint.js +62 -0
- package/package.json +14 -47
- package/prettier.config.cjs +9 -0
- package/scripts/cleanup-generated-controllers.ts +62 -0
- package/scripts/fix-reference-app-typing.ts +490 -0
- package/scripts/refactor-client-app-imports.ts +244 -0
- package/scripts/refactor-client-pages.ts +587 -0
- package/scripts/refactor-server-controllers.ts +470 -0
- package/scripts/refactor-server-runtime-aliases.ts +360 -0
- package/scripts/restore-client-app-import-files.ts +41 -0
- package/scripts/restore-files-from-git-head.ts +20 -0
- package/scripts/update-codex-agents.ts +35 -0
- package/server/app/commands.ts +35 -64
- package/server/app/container/config.ts +39 -69
- package/server/app/container/console/index.ts +202 -248
- package/server/app/container/index.ts +33 -71
- package/server/app/controller/index.ts +61 -0
- package/server/app/index.ts +39 -105
- package/server/app/service/container.ts +41 -42
- package/server/app/service/index.ts +120 -147
- package/server/context.ts +1 -1
- package/server/index.ts +25 -1
- package/server/services/auth/index.ts +75 -115
- package/server/services/auth/router/index.ts +31 -32
- package/server/services/auth/router/request.ts +14 -16
- package/server/services/cron/CronTask.ts +13 -26
- package/server/services/cron/index.ts +14 -36
- package/server/services/disks/driver.ts +40 -58
- package/server/services/disks/drivers/local/index.ts +79 -90
- package/server/services/disks/drivers/s3/index.ts +116 -163
- package/server/services/disks/index.ts +23 -38
- package/server/services/email/index.ts +45 -104
- package/server/services/email/utils.ts +14 -27
- package/server/services/fetch/index.ts +53 -85
- package/server/services/prisma/Facet.ts +39 -91
- package/server/services/prisma/index.ts +74 -110
- package/server/services/router/generatedRuntime.ts +29 -0
- package/server/services/router/http/index.ts +77 -72
- package/server/services/router/http/multipart.ts +19 -42
- package/server/services/router/index.ts +378 -365
- package/server/services/router/request/api.ts +26 -25
- package/server/services/router/request/index.ts +44 -51
- package/server/services/router/request/service.ts +7 -11
- package/server/services/router/request/validation/zod.ts +111 -148
- package/server/services/router/response/index.ts +110 -125
- package/server/services/router/response/mask/Filter.ts +31 -72
- package/server/services/router/response/mask/index.ts +8 -15
- package/server/services/router/response/mask/selecteurs.ts +11 -25
- package/server/services/router/response/page/clientManifest.ts +25 -0
- package/server/services/router/response/page/document.tsx +199 -127
- package/server/services/router/response/page/index.tsx +89 -94
- package/server/services/router/service.ts +13 -15
- package/server/services/schema/index.ts +17 -26
- package/server/services/schema/request.ts +19 -33
- package/server/services/schema/router/index.ts +8 -11
- package/server/services/security/encrypt/aes/index.ts +15 -35
- package/server/utils/slug.ts +29 -32
- package/skills/clean-project-code/SKILL.md +63 -0
- package/skills/clean-project-code/agents/openai.yaml +4 -0
- package/tsconfig.common.json +4 -3
- package/tsconfig.json +4 -1
- package/types/aliases.d.ts +17 -21
- package/types/controller-input.test.ts +48 -0
- package/types/express-extra.d.ts +6 -0
- package/types/global/constants.d.ts +1 -0
- package/types/global/express-extra.d.ts +6 -0
- package/types/global/modules.d.ts +13 -16
- package/types/global/utils.d.ts +17 -49
- package/types/global/vendors.d.ts +62 -0
- package/types/icons.d.ts +65 -1
- package/types/uuid.d.ts +3 -0
- package/types/vendors.d.ts +62 -0
- package/cli/compiler/common/babel/index.ts +0 -173
- package/cli/compiler/common/babel/plugins/index.ts +0 -0
- package/cli/compiler/common/babel/plugins/services.ts +0 -586
- package/cli/compiler/common/babel/routes/imports.ts +0 -127
- package/cli/compiler/common/babel/routes/routes.ts +0 -1170
- package/client/services/captcha/index.ts +0 -67
- package/client/services/socket/index.ts +0 -147
- package/common/data/rte/nodes.ts +0 -83
- package/common/data/stats.ts +0 -90
- package/common/utils/rte.ts +0 -183
- package/server/services/auth/old.ts +0 -277
- package/server/services/cache/commands.ts +0 -41
- package/server/services/cache/index.ts +0 -297
- package/server/services/cache/service.json +0 -6
- package/server/services/socket/index.ts +0 -162
- package/server/services/socket/scope.ts +0 -226
- package/server/services/socket/service.json +0 -6
- package/server/services_old/SocketClient.ts +0 -92
- package/server/services_old/Token.old.ts +0 -97
package/AGENTS.md
CHANGED
|
@@ -1,3 +1,35 @@
|
|
|
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
|
+
|
|
1
33
|
# Workflow
|
|
2
34
|
|
|
3
35
|
- Everytime I input error messages without any instructions, don't implement fixes.
|
|
@@ -7,3 +39,63 @@ Instead, ivestigate the potential causes of the errors, and for each:
|
|
|
7
39
|
3. Suggest how to fix it
|
|
8
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.
|
|
9
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,16 +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
26
|
public envName?: string,
|
|
28
|
-
public routerPortOverride?: number
|
|
29
|
-
) {
|
|
30
|
-
|
|
31
|
-
}
|
|
27
|
+
public routerPortOverride?: number,
|
|
28
|
+
) {}
|
|
32
29
|
|
|
33
|
-
private loadYaml(
|
|
30
|
+
private loadYaml(filepath: string) {
|
|
34
31
|
console.info(`Loading config ${filepath}`);
|
|
35
32
|
const rawConfig = fs.readFileSync(filepath, 'utf-8');
|
|
36
33
|
return yaml.parse(rawConfig);
|
|
@@ -39,23 +36,21 @@ export default class ConfigParser {
|
|
|
39
36
|
public env(): TEnvConfig {
|
|
40
37
|
// We assume that when we run 5htp dev, we're in local
|
|
41
38
|
// Otherwise, we're in production environment (docker)
|
|
42
|
-
console.log(
|
|
39
|
+
console.log('[app] Using environment:', process.env.NODE_ENV);
|
|
43
40
|
const envFileName = this.appDir + '/env.yaml';
|
|
44
|
-
const envFile = this.loadYaml(
|
|
41
|
+
const envFile = this.loadYaml(envFileName);
|
|
45
42
|
return {
|
|
46
43
|
...envFile,
|
|
47
|
-
router:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
...envFile.router,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
version: 'CLI'
|
|
54
|
-
}
|
|
44
|
+
router:
|
|
45
|
+
this.routerPortOverride === undefined
|
|
46
|
+
? envFile.router
|
|
47
|
+
: { ...envFile.router, port: this.routerPortOverride },
|
|
48
|
+
version: 'CLI',
|
|
49
|
+
};
|
|
55
50
|
}
|
|
56
51
|
|
|
57
52
|
public identity() {
|
|
58
53
|
const identityFile = this.appDir + '/identity.yaml';
|
|
59
|
-
return this.loadYaml(
|
|
54
|
+
return this.loadYaml(identityFile);
|
|
60
55
|
}
|
|
61
56
|
}
|