@jaimevalasek/aioson 1.3.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.
- package/CHANGELOG.md +456 -0
- package/CODE_OF_CONDUCT.md +12 -0
- package/CONTRIBUTING.md +13 -0
- package/LICENSE +21 -0
- package/README.md +254 -0
- package/bin/aioson.js +4 -0
- package/docs/en/cli-reference.md +398 -0
- package/docs/en/i18n.md +52 -0
- package/docs/en/json-schemas.md +41 -0
- package/docs/en/mcp.md +56 -0
- package/docs/en/parallel.md +82 -0
- package/docs/en/qa-browser.md +339 -0
- package/docs/en/release-flow.md +22 -0
- package/docs/en/release-notes-template.md +41 -0
- package/docs/en/release.md +28 -0
- package/docs/en/schemas/agent-prompt.schema.json +17 -0
- package/docs/en/schemas/agents.schema.json +32 -0
- package/docs/en/schemas/context-validate.schema.json +36 -0
- package/docs/en/schemas/doctor.schema.json +89 -0
- package/docs/en/schemas/error.schema.json +24 -0
- package/docs/en/schemas/i18n-add.schema.json +15 -0
- package/docs/en/schemas/index.json +116 -0
- package/docs/en/schemas/info.schema.json +39 -0
- package/docs/en/schemas/init.schema.json +48 -0
- package/docs/en/schemas/install.schema.json +60 -0
- package/docs/en/schemas/locale-apply.schema.json +30 -0
- package/docs/en/schemas/mcp-doctor.schema.json +95 -0
- package/docs/en/schemas/mcp-init.schema.json +122 -0
- package/docs/en/schemas/package-test.schema.json +24 -0
- package/docs/en/schemas/parallel-assign.schema.json +57 -0
- package/docs/en/schemas/parallel-doctor.schema.json +86 -0
- package/docs/en/schemas/parallel-init.schema.json +53 -0
- package/docs/en/schemas/parallel-status.schema.json +94 -0
- package/docs/en/schemas/setup-context.schema.json +39 -0
- package/docs/en/schemas/smoke.schema.json +23 -0
- package/docs/en/schemas/update.schema.json +48 -0
- package/docs/en/schemas/workflow-plan.schema.json +30 -0
- package/docs/en/web3.md +54 -0
- package/docs/pt/README.md +46 -0
- package/docs/pt/advisor-spec.md +335 -0
- package/docs/pt/agentes.md +453 -0
- package/docs/pt/cenarios.md +1230 -0
- package/docs/pt/clientes-ai.md +224 -0
- package/docs/pt/comandos-cli.md +511 -0
- package/docs/pt/genome-3.0-spec.md +296 -0
- package/docs/pt/guia-engineer.md +226 -0
- package/docs/pt/inicio-rapido.md +138 -0
- package/docs/pt/profiler-system.md +214 -0
- package/docs/pt/runtime-observability.md +72 -0
- package/docs/pt/squad-genoma.md +777 -0
- package/docs/pt/web3.md +797 -0
- package/docs/testing/genome-2.0-manual-regression.md +23 -0
- package/docs/testing/genome-2.0-matrix.md +36 -0
- package/docs/testing/genome-2.0-rollout.md +184 -0
- package/package.json +50 -0
- package/src/agents.js +56 -0
- package/src/cli.js +497 -0
- package/src/commands/agents.js +142 -0
- package/src/commands/cloud.js +1767 -0
- package/src/commands/config.js +90 -0
- package/src/commands/context-validate.js +91 -0
- package/src/commands/doctor.js +123 -0
- package/src/commands/genome-doctor.js +41 -0
- package/src/commands/genome-migrate.js +49 -0
- package/src/commands/i18n-add.js +56 -0
- package/src/commands/info.js +41 -0
- package/src/commands/init.js +75 -0
- package/src/commands/install.js +68 -0
- package/src/commands/locale-apply.js +51 -0
- package/src/commands/locale-diff.js +126 -0
- package/src/commands/mcp-doctor.js +406 -0
- package/src/commands/mcp-init.js +379 -0
- package/src/commands/package-e2e.js +273 -0
- package/src/commands/parallel-assign.js +403 -0
- package/src/commands/parallel-doctor.js +437 -0
- package/src/commands/parallel-init.js +249 -0
- package/src/commands/parallel-status.js +290 -0
- package/src/commands/qa-doctor.js +185 -0
- package/src/commands/qa-init.js +161 -0
- package/src/commands/qa-report.js +58 -0
- package/src/commands/qa-run.js +873 -0
- package/src/commands/qa-scan.js +337 -0
- package/src/commands/runtime.js +948 -0
- package/src/commands/scan-project.js +1107 -0
- package/src/commands/setup-context.js +650 -0
- package/src/commands/smoke.js +426 -0
- package/src/commands/squad-doctor.js +358 -0
- package/src/commands/squad-export.js +46 -0
- package/src/commands/squad-pipeline.js +97 -0
- package/src/commands/squad-repair-genomes.js +39 -0
- package/src/commands/squad-status.js +424 -0
- package/src/commands/squad-validate.js +230 -0
- package/src/commands/test-agents.js +194 -0
- package/src/commands/update.js +55 -0
- package/src/commands/workflow-next.js +594 -0
- package/src/commands/workflow-plan.js +108 -0
- package/src/constants.js +314 -0
- package/src/context-parse-reason.js +22 -0
- package/src/context-writer.js +150 -0
- package/src/context.js +217 -0
- package/src/detector.js +261 -0
- package/src/doctor.js +289 -0
- package/src/execution-gateway.js +461 -0
- package/src/genome-files.js +198 -0
- package/src/genome-format.js +442 -0
- package/src/genome-schema.js +215 -0
- package/src/genomes/bindings.js +281 -0
- package/src/genomes.js +467 -0
- package/src/i18n/index.js +103 -0
- package/src/i18n/messages/en.js +784 -0
- package/src/i18n/messages/es.js +718 -0
- package/src/i18n/messages/fr.js +725 -0
- package/src/i18n/messages/pt-BR.js +818 -0
- package/src/i18n/scaffold.js +64 -0
- package/src/installer.js +232 -0
- package/src/lib/genomes/compat.js +206 -0
- package/src/lib/genomes/migrate.js +90 -0
- package/src/lib/squads/genome-repair.js +49 -0
- package/src/locales.js +84 -0
- package/src/onboarding.js +305 -0
- package/src/parser.js +53 -0
- package/src/prompt-tool.js +20 -0
- package/src/qa-html-report.js +472 -0
- package/src/runtime-store.js +1527 -0
- package/src/squads/apply-genome.js +21 -0
- package/src/squads/genome-binding-service.js +154 -0
- package/src/updater.js +32 -0
- package/src/utils.js +46 -0
- package/src/version.js +50 -0
- package/template/.aioson/advisors/.gitkeep +1 -0
- package/template/.aioson/agents/analyst.md +225 -0
- package/template/.aioson/agents/architect.md +221 -0
- package/template/.aioson/agents/dev.md +201 -0
- package/template/.aioson/agents/discovery-design-doc.md +196 -0
- package/template/.aioson/agents/genoma.md +300 -0
- package/template/.aioson/agents/orchestrator.md +107 -0
- package/template/.aioson/agents/pm.md +89 -0
- package/template/.aioson/agents/product.md +361 -0
- package/template/.aioson/agents/profiler-enricher.md +266 -0
- package/template/.aioson/agents/profiler-forge.md +188 -0
- package/template/.aioson/agents/profiler-researcher.md +245 -0
- package/template/.aioson/agents/qa.md +344 -0
- package/template/.aioson/agents/setup.md +381 -0
- package/template/.aioson/agents/squad.md +837 -0
- package/template/.aioson/agents/ux-ui.md +416 -0
- package/template/.aioson/config.md +56 -0
- package/template/.aioson/context/.gitkeep +0 -0
- package/template/.aioson/context/parallel/.gitkeep +0 -0
- package/template/.aioson/context/spec.md.template +37 -0
- package/template/.aioson/genomas/.gitkeep +0 -0
- package/template/.aioson/locales/en/agents/analyst.md +214 -0
- package/template/.aioson/locales/en/agents/architect.md +210 -0
- package/template/.aioson/locales/en/agents/dev.md +187 -0
- package/template/.aioson/locales/en/agents/discovery-design-doc.md +27 -0
- package/template/.aioson/locales/en/agents/genoma.md +212 -0
- package/template/.aioson/locales/en/agents/orchestrator.md +105 -0
- package/template/.aioson/locales/en/agents/pm.md +77 -0
- package/template/.aioson/locales/en/agents/product.md +310 -0
- package/template/.aioson/locales/en/agents/profiler-enricher.md +5 -0
- package/template/.aioson/locales/en/agents/profiler-forge.md +5 -0
- package/template/.aioson/locales/en/agents/profiler-researcher.md +5 -0
- package/template/.aioson/locales/en/agents/qa.md +214 -0
- package/template/.aioson/locales/en/agents/setup.md +342 -0
- package/template/.aioson/locales/en/agents/squad.md +247 -0
- package/template/.aioson/locales/en/agents/ux-ui.md +320 -0
- package/template/.aioson/locales/es/agents/analyst.md +203 -0
- package/template/.aioson/locales/es/agents/architect.md +208 -0
- package/template/.aioson/locales/es/agents/dev.md +183 -0
- package/template/.aioson/locales/es/agents/discovery-design-doc.md +19 -0
- package/template/.aioson/locales/es/agents/genoma.md +102 -0
- package/template/.aioson/locales/es/agents/orchestrator.md +108 -0
- package/template/.aioson/locales/es/agents/pm.md +81 -0
- package/template/.aioson/locales/es/agents/product.md +310 -0
- package/template/.aioson/locales/es/agents/profiler-enricher.md +5 -0
- package/template/.aioson/locales/es/agents/profiler-forge.md +5 -0
- package/template/.aioson/locales/es/agents/profiler-researcher.md +5 -0
- package/template/.aioson/locales/es/agents/qa.md +163 -0
- package/template/.aioson/locales/es/agents/setup.md +347 -0
- package/template/.aioson/locales/es/agents/squad.md +247 -0
- package/template/.aioson/locales/es/agents/ux-ui.md +201 -0
- package/template/.aioson/locales/fr/agents/analyst.md +203 -0
- package/template/.aioson/locales/fr/agents/architect.md +208 -0
- package/template/.aioson/locales/fr/agents/dev.md +183 -0
- package/template/.aioson/locales/fr/agents/discovery-design-doc.md +19 -0
- package/template/.aioson/locales/fr/agents/genoma.md +102 -0
- package/template/.aioson/locales/fr/agents/orchestrator.md +108 -0
- package/template/.aioson/locales/fr/agents/pm.md +81 -0
- package/template/.aioson/locales/fr/agents/product.md +310 -0
- package/template/.aioson/locales/fr/agents/profiler-enricher.md +5 -0
- package/template/.aioson/locales/fr/agents/profiler-forge.md +5 -0
- package/template/.aioson/locales/fr/agents/profiler-researcher.md +5 -0
- package/template/.aioson/locales/fr/agents/qa.md +163 -0
- package/template/.aioson/locales/fr/agents/setup.md +347 -0
- package/template/.aioson/locales/fr/agents/squad.md +247 -0
- package/template/.aioson/locales/fr/agents/ux-ui.md +201 -0
- package/template/.aioson/locales/pt-BR/agents/analyst.md +217 -0
- package/template/.aioson/locales/pt-BR/agents/architect.md +213 -0
- package/template/.aioson/locales/pt-BR/agents/dev.md +198 -0
- package/template/.aioson/locales/pt-BR/agents/discovery-design-doc.md +198 -0
- package/template/.aioson/locales/pt-BR/agents/genoma.md +297 -0
- package/template/.aioson/locales/pt-BR/agents/orchestrator.md +108 -0
- package/template/.aioson/locales/pt-BR/agents/pm.md +81 -0
- package/template/.aioson/locales/pt-BR/agents/product.md +316 -0
- package/template/.aioson/locales/pt-BR/agents/profiler-enricher.md +5 -0
- package/template/.aioson/locales/pt-BR/agents/profiler-forge.md +5 -0
- package/template/.aioson/locales/pt-BR/agents/profiler-researcher.md +5 -0
- package/template/.aioson/locales/pt-BR/agents/qa.md +217 -0
- package/template/.aioson/locales/pt-BR/agents/setup.md +371 -0
- package/template/.aioson/locales/pt-BR/agents/squad.md +772 -0
- package/template/.aioson/locales/pt-BR/agents/ux-ui.md +322 -0
- package/template/.aioson/mcp/servers.md +24 -0
- package/template/.aioson/profiler-reports/.gitkeep +1 -0
- package/template/.aioson/schemas/content-blueprint.schema.json +30 -0
- package/template/.aioson/schemas/genome-meta.schema.json +150 -0
- package/template/.aioson/schemas/genome.schema.json +115 -0
- package/template/.aioson/schemas/readiness.schema.json +27 -0
- package/template/.aioson/schemas/squad-blueprint.schema.json +172 -0
- package/template/.aioson/schemas/squad-manifest.schema.json +276 -0
- package/template/.aioson/skills/dynamic/README.md +30 -0
- package/template/.aioson/skills/dynamic/cardano-docs.md +16 -0
- package/template/.aioson/skills/dynamic/ethereum-docs.md +17 -0
- package/template/.aioson/skills/dynamic/flux-ui-docs.md +13 -0
- package/template/.aioson/skills/dynamic/laravel-docs.md +41 -0
- package/template/.aioson/skills/dynamic/npm-packages.md +16 -0
- package/template/.aioson/skills/dynamic/solana-docs.md +16 -0
- package/template/.aioson/skills/references/premium-command-center-ui/master-application-prompt.md +79 -0
- package/template/.aioson/skills/references/premium-command-center-ui/operational-ux-playbook.md +253 -0
- package/template/.aioson/skills/references/premium-command-center-ui/quality-validation-checklist.md +82 -0
- package/template/.aioson/skills/references/premium-command-center-ui/visual-system-and-component-patterns.md +270 -0
- package/template/.aioson/skills/static/django-patterns.md +342 -0
- package/template/.aioson/skills/static/fastapi-patterns.md +344 -0
- package/template/.aioson/skills/static/filament-patterns.md +267 -0
- package/template/.aioson/skills/static/flux-ui-components.md +262 -0
- package/template/.aioson/skills/static/git-conventions.md +227 -0
- package/template/.aioson/skills/static/interface-design.md +372 -0
- package/template/.aioson/skills/static/jetstream-setup.md +200 -0
- package/template/.aioson/skills/static/laravel-conventions.md +491 -0
- package/template/.aioson/skills/static/nextjs-patterns.md +321 -0
- package/template/.aioson/skills/static/node-express-patterns.md +317 -0
- package/template/.aioson/skills/static/node-typescript-patterns.md +282 -0
- package/template/.aioson/skills/static/premium-command-center-ui.md +190 -0
- package/template/.aioson/skills/static/rails-conventions.md +307 -0
- package/template/.aioson/skills/static/react-motion-patterns.md +577 -0
- package/template/.aioson/skills/static/static-html-patterns.md +1935 -0
- package/template/.aioson/skills/static/tall-stack-patterns.md +286 -0
- package/template/.aioson/skills/static/ui-ux-modern.md +75 -0
- package/template/.aioson/skills/static/web3-cardano-patterns.md +337 -0
- package/template/.aioson/skills/static/web3-ethereum-patterns.md +310 -0
- package/template/.aioson/skills/static/web3-security-checklist.md +284 -0
- package/template/.aioson/skills/static/web3-solana-patterns.md +324 -0
- package/template/.aioson/squads/.artisan/.gitkeep +0 -0
- package/template/.aioson/squads/.gitkeep +0 -0
- package/template/.aioson/squads/memory.md +5 -0
- package/template/.aioson/tasks/squad-analyze.md +83 -0
- package/template/.aioson/tasks/squad-create.md +99 -0
- package/template/.aioson/tasks/squad-design.md +100 -0
- package/template/.aioson/tasks/squad-export.md +20 -0
- package/template/.aioson/tasks/squad-extend.md +68 -0
- package/template/.aioson/tasks/squad-pipeline.md +122 -0
- package/template/.aioson/tasks/squad-repair.md +85 -0
- package/template/.aioson/tasks/squad-validate.md +58 -0
- package/template/.aioson/templates/squads/content-basic/template.json +21 -0
- package/template/.aioson/templates/squads/media-channel/template.json +24 -0
- package/template/.aioson/templates/squads/research-analysis/template.json +22 -0
- package/template/.aioson/templates/squads/software-delivery/template.json +21 -0
- package/template/.claude/commands/aioson/analyst.md +5 -0
- package/template/.claude/commands/aioson/architect.md +5 -0
- package/template/.claude/commands/aioson/dev.md +5 -0
- package/template/.claude/commands/aioson/orchestrator.md +5 -0
- package/template/.claude/commands/aioson/pm.md +5 -0
- package/template/.claude/commands/aioson/qa.md +5 -0
- package/template/.claude/commands/aioson/setup.md +5 -0
- package/template/.claude/commands/aioson/ux-ui.md +5 -0
- package/template/.gemini/GEMINI.md +10 -0
- package/template/.gemini/commands/aios-analyst.toml +4 -0
- package/template/.gemini/commands/aios-architect.toml +7 -0
- package/template/.gemini/commands/aios-dev.toml +8 -0
- package/template/.gemini/commands/aios-discovery-design-doc.toml +4 -0
- package/template/.gemini/commands/aios-orchestrator.toml +8 -0
- package/template/.gemini/commands/aios-pm.toml +8 -0
- package/template/.gemini/commands/aios-product.toml +4 -0
- package/template/.gemini/commands/aios-qa.toml +6 -0
- package/template/.gemini/commands/aios-setup.toml +3 -0
- package/template/.gemini/commands/aios-ux-ui.toml +8 -0
- package/template/AGENTS.md +67 -0
- package/template/CLAUDE.md +31 -0
- package/template/OPENCODE.md +24 -0
- package/template/aioson-models.json +40 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# Node + TypeScript Patterns
|
|
2
|
+
|
|
3
|
+
> Strict TypeScript, zero `any`, runtime validation at boundaries. Type safety as architecture.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## tsconfig.json — strict baseline
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"compilerOptions": {
|
|
12
|
+
"target": "ES2022",
|
|
13
|
+
"module": "NodeNext",
|
|
14
|
+
"moduleResolution": "NodeNext",
|
|
15
|
+
"strict": true,
|
|
16
|
+
"noUncheckedIndexedAccess": true,
|
|
17
|
+
"noImplicitReturns": true,
|
|
18
|
+
"exactOptionalPropertyTypes": true,
|
|
19
|
+
"outDir": "dist",
|
|
20
|
+
"rootDir": "src",
|
|
21
|
+
"paths": {
|
|
22
|
+
"@/*": ["./src/*"]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"include": ["src"],
|
|
26
|
+
"exclude": ["node_modules", "dist"]
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`strict: true` enables: `strictNullChecks`, `strictFunctionTypes`, `strictPropertyInitialization`, `noImplicitAny`.
|
|
31
|
+
`noUncheckedIndexedAccess` makes array/object index access return `T | undefined` — forces null checks.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Runtime validation with Zod (API boundaries)
|
|
36
|
+
|
|
37
|
+
TypeScript types are erased at runtime. Use Zod at every external boundary.
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { z } from 'zod';
|
|
41
|
+
|
|
42
|
+
// Define schema once — derive type from it
|
|
43
|
+
export const createAppointmentSchema = z.object({
|
|
44
|
+
doctorId: z.string().uuid(),
|
|
45
|
+
date: z.string().datetime(),
|
|
46
|
+
notes: z.string().max(500).optional(),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export type CreateAppointmentInput = z.infer<typeof createAppointmentSchema>;
|
|
50
|
+
|
|
51
|
+
// Parse at boundary — throws ZodError on invalid input
|
|
52
|
+
export function parseCreateAppointment(raw: unknown): CreateAppointmentInput {
|
|
53
|
+
return createAppointmentSchema.parse(raw);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Safe parse — returns result object instead of throwing
|
|
57
|
+
export function safeParseAppointment(raw: unknown) {
|
|
58
|
+
return createAppointmentSchema.safeParse(raw);
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Validate at:
|
|
63
|
+
- HTTP request bodies (before controllers)
|
|
64
|
+
- Environment variables (at startup)
|
|
65
|
+
- External API responses (after fetch)
|
|
66
|
+
- File/config parsing
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Environment variables — validate at startup
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
// src/lib/env.ts
|
|
74
|
+
import { z } from 'zod';
|
|
75
|
+
|
|
76
|
+
const envSchema = z.object({
|
|
77
|
+
NODE_ENV: z.enum(['development', 'test', 'production']),
|
|
78
|
+
PORT: z.coerce.number().default(3000),
|
|
79
|
+
DATABASE_URL: z.string().url(),
|
|
80
|
+
JWT_SECRET: z.string().min(32, 'JWT_SECRET must be at least 32 chars'),
|
|
81
|
+
STRIPE_SECRET: z.string().startsWith('sk_'),
|
|
82
|
+
ALLOWED_ORIGINS: z.string().default('http://localhost:3000'),
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
export const env = envSchema.parse(process.env);
|
|
86
|
+
|
|
87
|
+
// Usage — always typed, never undefined
|
|
88
|
+
import { env } from '@/lib/env';
|
|
89
|
+
jwt.verify(token, env.JWT_SECRET);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Domain types — explicit over inferred
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
// types/appointment.ts
|
|
98
|
+
|
|
99
|
+
// Branded types prevent ID mix-ups
|
|
100
|
+
type Brand<T, Name extends string> = T & { readonly _brand: Name };
|
|
101
|
+
export type UserId = Brand<string, 'UserId'>;
|
|
102
|
+
export type DoctorId = Brand<string, 'DoctorId'>;
|
|
103
|
+
export type AppointmentId = Brand<string, 'AppointmentId'>;
|
|
104
|
+
|
|
105
|
+
// Domain entity — explicit shape
|
|
106
|
+
export type Appointment = {
|
|
107
|
+
id: AppointmentId;
|
|
108
|
+
userId: UserId;
|
|
109
|
+
doctorId: DoctorId;
|
|
110
|
+
date: Date;
|
|
111
|
+
status: AppointmentStatus;
|
|
112
|
+
notes: string | null;
|
|
113
|
+
createdAt: Date;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// Enum-like const objects instead of TypeScript enums
|
|
117
|
+
export const AppointmentStatus = {
|
|
118
|
+
PENDING: 'pending',
|
|
119
|
+
CONFIRMED: 'confirmed',
|
|
120
|
+
CANCELLED: 'cancelled',
|
|
121
|
+
} as const;
|
|
122
|
+
export type AppointmentStatus = typeof AppointmentStatus[keyof typeof AppointmentStatus];
|
|
123
|
+
|
|
124
|
+
// DTOs — separate from domain entities
|
|
125
|
+
export type CreateAppointmentDto = {
|
|
126
|
+
doctorId: DoctorId;
|
|
127
|
+
date: Date;
|
|
128
|
+
notes?: string;
|
|
129
|
+
};
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Repository pattern — typed data access
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
// src/repositories/appointment.repository.ts
|
|
138
|
+
import type { Appointment, CreateAppointmentDto, AppointmentId } from '@/types';
|
|
139
|
+
import { db } from '@/lib/db';
|
|
140
|
+
|
|
141
|
+
export interface AppointmentRepository {
|
|
142
|
+
findById(id: AppointmentId): Promise<Appointment | null>;
|
|
143
|
+
findByUserAndDate(userId: UserId, date: Date): Promise<Appointment[]>;
|
|
144
|
+
create(data: CreateAppointmentDto & { userId: UserId }): Promise<Appointment>;
|
|
145
|
+
cancel(id: AppointmentId): Promise<Appointment>;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export const appointmentRepository: AppointmentRepository = {
|
|
149
|
+
findById: async (id) =>
|
|
150
|
+
db.appointment.findUnique({ where: { id } }) as Promise<Appointment | null>,
|
|
151
|
+
|
|
152
|
+
create: async (data) =>
|
|
153
|
+
db.appointment.create({ data }) as Promise<Appointment>,
|
|
154
|
+
|
|
155
|
+
cancel: async (id) =>
|
|
156
|
+
db.appointment.update({
|
|
157
|
+
where: { id },
|
|
158
|
+
data: { status: 'cancelled', cancelledAt: new Date() },
|
|
159
|
+
}) as Promise<Appointment>,
|
|
160
|
+
};
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Service layer — explicit return types
|
|
166
|
+
|
|
167
|
+
Always declare return types on public functions. Helps catch refactoring errors and documents the contract.
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
// src/services/appointment.service.ts
|
|
171
|
+
import type { Appointment, CreateAppointmentDto, UserId } from '@/types';
|
|
172
|
+
import { appointmentRepository } from '@/repositories/appointment.repository';
|
|
173
|
+
import { ConflictError } from '@/lib/errors';
|
|
174
|
+
|
|
175
|
+
export async function createAppointment(
|
|
176
|
+
userId: UserId,
|
|
177
|
+
dto: CreateAppointmentDto
|
|
178
|
+
): Promise<Appointment> {
|
|
179
|
+
const conflict = await appointmentRepository.findConflict(dto.doctorId, dto.date);
|
|
180
|
+
if (conflict) throw new ConflictError('This time slot is already booked.');
|
|
181
|
+
return appointmentRepository.create({ ...dto, userId });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export async function cancelAppointment(
|
|
185
|
+
id: AppointmentId,
|
|
186
|
+
requestingUserId: UserId
|
|
187
|
+
): Promise<Appointment> {
|
|
188
|
+
const appointment = await appointmentRepository.findById(id);
|
|
189
|
+
if (!appointment) throw new NotFoundError('Appointment not found.');
|
|
190
|
+
if (appointment.userId !== requestingUserId) throw new ForbiddenError();
|
|
191
|
+
return appointmentRepository.cancel(id);
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Avoiding `any` — common patterns
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
// WRONG
|
|
201
|
+
function processWebhook(payload: any) { ... }
|
|
202
|
+
|
|
203
|
+
// RIGHT — use unknown and narrow
|
|
204
|
+
function processWebhook(payload: unknown): void {
|
|
205
|
+
if (!isStripeEvent(payload)) throw new Error('Invalid webhook payload');
|
|
206
|
+
// payload is now StripeEvent
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function isStripeEvent(value: unknown): value is Stripe.Event {
|
|
210
|
+
return typeof value === 'object'
|
|
211
|
+
&& value !== null
|
|
212
|
+
&& 'type' in value
|
|
213
|
+
&& typeof (value as any).type === 'string';
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// WRONG — type assertion without safety
|
|
217
|
+
const user = response.data as User;
|
|
218
|
+
|
|
219
|
+
// RIGHT — parse and validate
|
|
220
|
+
const user = userSchema.parse(response.data);
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Async error handling
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
// Wrap async route handlers to avoid try/catch boilerplate
|
|
229
|
+
export const asyncHandler =
|
|
230
|
+
(fn: (req: Request, res: Response, next: NextFunction) => Promise<void>) =>
|
|
231
|
+
(req: Request, res: Response, next: NextFunction) =>
|
|
232
|
+
Promise.resolve(fn(req, res, next)).catch(next);
|
|
233
|
+
|
|
234
|
+
// Usage
|
|
235
|
+
router.post('/', asyncHandler(async (req, res) => {
|
|
236
|
+
const appointment = await createAppointment(req.user!.id, req.body);
|
|
237
|
+
res.status(201).json({ data: appointment });
|
|
238
|
+
}));
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Testing with types
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
// Use satisfies for test fixtures
|
|
247
|
+
const mockAppointment = {
|
|
248
|
+
id: 'apt_123' as AppointmentId,
|
|
249
|
+
userId: 'usr_456' as UserId,
|
|
250
|
+
doctorId: 'doc_789' as DoctorId,
|
|
251
|
+
date: new Date('2026-03-15T10:00:00Z'),
|
|
252
|
+
status: 'pending',
|
|
253
|
+
notes: null,
|
|
254
|
+
createdAt: new Date(),
|
|
255
|
+
} satisfies Appointment;
|
|
256
|
+
|
|
257
|
+
// Mock repository with type safety
|
|
258
|
+
const mockRepo: AppointmentRepository = {
|
|
259
|
+
findById: jest.fn().mockResolvedValue(mockAppointment),
|
|
260
|
+
create: jest.fn().mockResolvedValue(mockAppointment),
|
|
261
|
+
cancel: jest.fn().mockResolvedValue({ ...mockAppointment, status: 'cancelled' }),
|
|
262
|
+
findByUserAndDate: jest.fn().mockResolvedValue([]),
|
|
263
|
+
findConflict: jest.fn().mockResolvedValue(null),
|
|
264
|
+
};
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## ALWAYS
|
|
270
|
+
- `strict: true` in tsconfig — no exceptions
|
|
271
|
+
- Zod validation at all external boundaries (HTTP, env, external APIs)
|
|
272
|
+
- Explicit return types on public service and repository functions
|
|
273
|
+
- Branded types for domain IDs to prevent mix-ups
|
|
274
|
+
- Interface definitions for repositories (enables mocking)
|
|
275
|
+
- `unknown` over `any` when type is genuinely unknown
|
|
276
|
+
|
|
277
|
+
## NEVER
|
|
278
|
+
- `any` in service or domain code
|
|
279
|
+
- Type assertions (`as SomeType`) without preceding validation
|
|
280
|
+
- `!` non-null assertion without a runtime check nearby
|
|
281
|
+
- Importing `process.env.X` directly — always go through validated env module
|
|
282
|
+
- Enum (TypeScript enums have runtime quirks) — use `const` objects with `as const`
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Premium Command Center UI
|
|
2
|
+
|
|
3
|
+
> Use this skill when the product is a dashboard, admin panel, control tower, command center, or internal operating surface that must feel premium without becoming bloated.
|
|
4
|
+
> This skill was extracted from the real AIOS Dashboard implementation: tri-rail shell, aurora-glass surfaces, compact density, search-first navigation, grouped operational cards, and data-aware page hierarchy.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## What this skill captures
|
|
9
|
+
|
|
10
|
+
This is not a generic "modern dashboard" guide. It captures the concrete moves that created the premium feel in the AIOS Dashboard:
|
|
11
|
+
|
|
12
|
+
- tri-rail shell: left navigation, center workspace, right activity rail
|
|
13
|
+
- aurora-glass visual system with strong contrast and restrained semantic color
|
|
14
|
+
- compact density tuned for operational reading, not marketing whitespace
|
|
15
|
+
- search-first interaction via top search bar + command palette
|
|
16
|
+
- contextual right rail with status/history/metrics tabs
|
|
17
|
+
- page archetypes built around runtime priority, not equal-weight card walls
|
|
18
|
+
- UI view-model aggregation (`workflow lanes`, `task queue`, `memory assets`) instead of rendering raw backend shapes directly
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## When to use this skill
|
|
23
|
+
|
|
24
|
+
Apply this skill when:
|
|
25
|
+
|
|
26
|
+
- the product is an operational dashboard or internal tool
|
|
27
|
+
- the user asks for a premium, high-contrast, high-trust interface
|
|
28
|
+
- the current UI feels washed out, generic, or too expanded
|
|
29
|
+
- the app has multiple modules that need one shared shell and consistent hierarchy
|
|
30
|
+
- the interface must surface live signals, queue state, history, and deep links
|
|
31
|
+
- the stack supports custom UI work (React, Next.js, TALL, Blade, Vue, custom HTML/CSS, etc.)
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## When not to use this skill
|
|
36
|
+
|
|
37
|
+
Do not apply this skill blindly when:
|
|
38
|
+
|
|
39
|
+
- the project is a landing page or campaign site
|
|
40
|
+
- the product is intentionally minimal, calm, editorial, or consumer-soft
|
|
41
|
+
- the existing brand system is already strong and conflicts with aurora-glass language
|
|
42
|
+
- the screen is simple CRUD that should remain utilitarian and low-chrome
|
|
43
|
+
- the domain demands conventional enterprise neutrality over expressiveness
|
|
44
|
+
|
|
45
|
+
In those cases, borrow only the pieces that fit: density control, hierarchy discipline, grouped operational cards, or contextual rails.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Read order
|
|
50
|
+
|
|
51
|
+
1. Read this file fully.
|
|
52
|
+
2. Read [visual-system-and-component-patterns](../references/premium-command-center-ui/visual-system-and-component-patterns.md) before choosing tokens or components.
|
|
53
|
+
3. Read [operational-ux-playbook](../references/premium-command-center-ui/operational-ux-playbook.md) before defining page hierarchy, navigation, or grouping.
|
|
54
|
+
4. If another agent will apply the system, give it [master-application-prompt](../references/premium-command-center-ui/master-application-prompt.md).
|
|
55
|
+
5. Before shipping, run [quality-validation-checklist](../references/premium-command-center-ui/quality-validation-checklist.md).
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Application flow
|
|
60
|
+
|
|
61
|
+
### 1. Inspect the product before drawing anything
|
|
62
|
+
|
|
63
|
+
Identify the real operational nouns and verbs first:
|
|
64
|
+
|
|
65
|
+
- What is the live signal?
|
|
66
|
+
- What is the queue?
|
|
67
|
+
- What is the grouped catalog?
|
|
68
|
+
- What deserves persistent navigation?
|
|
69
|
+
- What belongs in context, not in the primary column?
|
|
70
|
+
|
|
71
|
+
Do not start from components. Start from operational pressure.
|
|
72
|
+
|
|
73
|
+
### 2. Translate raw data into UI-native objects
|
|
74
|
+
|
|
75
|
+
The AIOS Dashboard improved dramatically when raw backend records were converted into UI view models such as:
|
|
76
|
+
|
|
77
|
+
- `GlobalTaskRecord`
|
|
78
|
+
- `WorkflowRecord`
|
|
79
|
+
- `MemoryAssetRecord`
|
|
80
|
+
|
|
81
|
+
Follow the same principle in new projects. Do not render tables straight from storage shape when the user actually needs lanes, signals, grouped cards, or contextual summaries.
|
|
82
|
+
|
|
83
|
+
### 3. Choose the shell intentionally
|
|
84
|
+
|
|
85
|
+
Use the tri-rail shell when the product has:
|
|
86
|
+
|
|
87
|
+
- 5+ first-class modules
|
|
88
|
+
- live or near-live context
|
|
89
|
+
- a need for persistent navigation + persistent context
|
|
90
|
+
- enough desktop usage to justify a right rail
|
|
91
|
+
|
|
92
|
+
Collapse progressively below the desktop breakpoint instead of building a separate mobile design system.
|
|
93
|
+
|
|
94
|
+
### 4. Choose the page archetype
|
|
95
|
+
|
|
96
|
+
Reuse the patterns that actually shipped in the dashboard:
|
|
97
|
+
|
|
98
|
+
- command center overview
|
|
99
|
+
- queue / control tower
|
|
100
|
+
- workflow catalog
|
|
101
|
+
- grouped registry
|
|
102
|
+
- knowledge explorer
|
|
103
|
+
|
|
104
|
+
Use the UX playbook to decide which archetype fits each route.
|
|
105
|
+
|
|
106
|
+
### 5. Apply the visual language without diluting it
|
|
107
|
+
|
|
108
|
+
Preserve these moves together:
|
|
109
|
+
|
|
110
|
+
- dark graphite or cool mist foundation
|
|
111
|
+
- aurora background fields on the page and shell, not everywhere
|
|
112
|
+
- borders-first depth with one shadow family only
|
|
113
|
+
- 3 surface levels max
|
|
114
|
+
- compact spacing and short helper copy
|
|
115
|
+
- semantic badges and gradient fills tied to meaning, not decoration
|
|
116
|
+
|
|
117
|
+
### 6. Build direct next actions into the UI
|
|
118
|
+
|
|
119
|
+
Every major card should expose the next useful step:
|
|
120
|
+
|
|
121
|
+
- open the squad
|
|
122
|
+
- inspect the task
|
|
123
|
+
- view logs
|
|
124
|
+
- switch workspace
|
|
125
|
+
- drill into workflow or memory source
|
|
126
|
+
|
|
127
|
+
Premium feel comes from reduced friction, not only from color.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## How to adapt this skill to new projects
|
|
132
|
+
|
|
133
|
+
Adapt the system structurally, not literally.
|
|
134
|
+
|
|
135
|
+
- Replace `squads` with the domain grouping that matters in the new product.
|
|
136
|
+
- Replace `tasks` with the domain queue or active work item.
|
|
137
|
+
- Replace `memories` with the project’s knowledge layer, asset layer, or context layer.
|
|
138
|
+
- Replace `activity rail` content with the three slices that matter most: current state, history, metrics.
|
|
139
|
+
- Keep the same visual grammar and density discipline even when labels and data change.
|
|
140
|
+
|
|
141
|
+
If the new project already has a design system:
|
|
142
|
+
|
|
143
|
+
- port the hierarchy rules first
|
|
144
|
+
- port the page archetypes second
|
|
145
|
+
- port the shell behaviors third
|
|
146
|
+
- port colors only if they do not violate brand or accessibility
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## How to preserve the same level of visual quality
|
|
151
|
+
|
|
152
|
+
The quality bar is preserved when all of the following remain true:
|
|
153
|
+
|
|
154
|
+
- runtime or primary operations appear above infrastructure or metadata
|
|
155
|
+
- every screen has one obvious focal block
|
|
156
|
+
- cards are grouped by operational meaning, not just by data type
|
|
157
|
+
- the shell behaves like a product operating surface
|
|
158
|
+
- semantic colors are limited and consistent
|
|
159
|
+
- empty states are styled and intentional
|
|
160
|
+
- search, navigation, and context work together instead of competing
|
|
161
|
+
- density is compact but never cramped
|
|
162
|
+
|
|
163
|
+
If the result looks like a generic dark dashboard with random gradients, the skill was not applied correctly.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Non-negotiable quality bar
|
|
168
|
+
|
|
169
|
+
- No flat, washed-out backgrounds.
|
|
170
|
+
- No equal-emphasis card grids for every section.
|
|
171
|
+
- No giant padding values that make the product feel empty.
|
|
172
|
+
- No rainbow status colors without semantic meaning.
|
|
173
|
+
- No shadow-heavy cards mixed with border-heavy cards.
|
|
174
|
+
- No hidden next step after a user reads a card.
|
|
175
|
+
- No infrastructure-first hierarchy.
|
|
176
|
+
- No top-level page without a clear route back to the operating workflow.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Expected output when using this skill
|
|
181
|
+
|
|
182
|
+
When you apply this skill to a new product, deliver:
|
|
183
|
+
|
|
184
|
+
1. explicit visual direction and density choice
|
|
185
|
+
2. shell structure and route hierarchy
|
|
186
|
+
3. page archetype selection per major screen
|
|
187
|
+
4. reusable component set
|
|
188
|
+
5. state handling (default / hover / active / empty / loading / error)
|
|
189
|
+
6. responsive behavior notes
|
|
190
|
+
7. validation against the checklist before handoff
|