Skip to content

Commit 5b7e7ac

Browse files
committed
feat: refactor for ai first development
1 parent bcfaef0 commit 5b7e7ac

68 files changed

Lines changed: 6623 additions & 1434 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CLAUDE.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,16 @@ NEVER use `synchronize: true` in production.
154154

155155
All private pages: `SectionContainer` + `PageHeader` + `<div className="p-4 lg:p-12">`
156156

157+
### Routes & i18n (typed)
158+
159+
- **NEVER hardcode internal route strings.** Use the typed `routes` from `~/lib/routes`
160+
in every `href` / `router.push` / `redirect``routes.adminUsers`, `routes.adminUser(id)`.
161+
A renamed/removed route then becomes a compile error at every call site, not a dead link.
162+
Add new routes to `~/lib/routes.ts`.
163+
- **Translation keys are typed** (next-intl `AppConfig` augmentation in `src/global.ts`).
164+
`useTranslations('ns')` + `t('key')` are checked against the real messages — a missing
165+
key is a compile error. Add keys to `messages/<locale>/<ns>.json` (same key in every locale).
166+
157167
### Server Actions
158168

159169
- Call orval-generated functions (e.g. `usersQueryControllerFindAll(params, cfg)`)
@@ -166,6 +176,24 @@ All private pages: `SectionContainer` + `PageHeader` + `<div className="p-4 lg:p
166176
- Place in `_actions/` folders (excluded from routing); `revalidatePath()` after a
167177
successful mutation.
168178

179+
### Runtime Validation (boundary)
180+
181+
Validate API responses at the boundary on **data-bearing** endpoints — the ones
182+
whose `.data` you actually read in a component. That's where malformed data crashes
183+
the UI, and those schemas are accurate.
184+
185+
- **Server Actions**: pass the generated `*Response` schema as `safeAction`'s 2nd arg
186+
`safeAction(fn, UsersCommandControllerUpdateResponse)`. On drift it returns a 502
187+
envelope (never throws).
188+
- **Server Component page fetches**: `SchemaResponse.parse(response)` right after the
189+
call → a drift throws and is caught by `error.tsx`.
190+
- Schemas come from `@myorg/api-client/zod` (generated — never hand-write them).
191+
- **Do NOT validate no-data endpoints** (delete, logout, change-password): nothing to
192+
dereference (no UI-crash risk) and their `null`/void `data` would false-positive.
193+
- If a real, valid response ever fails validation, the backend `@ApiProperty` is
194+
wrong (e.g. missing `type`/`nullable`) — **fix the DTO so the schema is accurate
195+
and regenerate; never disable the check.**
196+
169197
### Testing
170198

171199
- **Vitest** for unit/component tests (`*.spec.ts` backend, `*.test.tsx` web),
@@ -249,3 +277,5 @@ app/[locale]/(main)/
249277
---
250278

251279
**Reference Module:** `apps/backend/src/modules/users/`
280+
281+
**Design system:** all generated UI MUST follow `docs/design-system.md` (tokens + component rules, generated by `/studio`).

apps/backend/src/modules/users/dto/user-response.dto.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export class UserResponseDto {
3232
emailVerified!: boolean;
3333

3434
@ApiPropertyOptional({
35+
type: String,
36+
nullable: true,
3537
example: '2024-01-15T10:30:00.000Z',
3638
description: 'Last login timestamp',
3739
})

apps/web/scripts/studio-init.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// One-off: migrate globals.css (add studio markers + status tokens) and write the
2+
// initial docs/design-system.md + CLAUDE.md pointer using the real Studio engine.
3+
import { readFileSync, writeFileSync } from 'node:fs';
4+
import { join } from 'node:path';
5+
import { parseGlobalsCss } from '../src/lib/studio/parse-globals';
6+
import { applyTokensToCss } from '../src/lib/studio/serialize-tokens';
7+
import {
8+
generateDesignRules,
9+
DESIGN_RULES_POINTER,
10+
} from '../src/lib/studio/generate-rules';
11+
import { withStatusDefaults } from '../src/lib/studio/theme-config';
12+
13+
const root = join(process.cwd(), '..', '..');
14+
const globalsPath = join(root, 'packages/design/src/styles/globals.css');
15+
16+
const css = readFileSync(globalsPath, 'utf-8');
17+
const config = withStatusDefaults(parseGlobalsCss(css));
18+
19+
writeFileSync(globalsPath, applyTokensToCss(css, config), 'utf-8');
20+
writeFileSync(
21+
join(root, 'docs/design-system.md'),
22+
generateDesignRules(config),
23+
'utf-8',
24+
);
25+
26+
const claudePath = join(root, 'CLAUDE.md');
27+
const claude = readFileSync(claudePath, 'utf-8');
28+
if (!claude.includes('docs/design-system.md')) {
29+
writeFileSync(
30+
claudePath,
31+
`${claude.trimEnd()}\n\n${DESIGN_RULES_POINTER}\n`,
32+
'utf-8',
33+
);
34+
}
35+
36+
console.log(
37+
'Studio init complete: globals.css migrated, design-system.md + CLAUDE pointer written.',
38+
);

apps/web/src/app/[locale]/(main)/(private)/admin/add-user-client/_components/add-user-form.tsx

Lines changed: 0 additions & 140 deletions
This file was deleted.

apps/web/src/app/[locale]/(main)/(private)/admin/add-user-client/page.tsx

Lines changed: 0 additions & 56 deletions
This file was deleted.

apps/web/src/app/[locale]/(main)/(private)/admin/add-user-server/_actions/create-user.ts

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)