@geraldmaron/construct 1.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 (352) hide show
  1. package/.env.example +69 -0
  2. package/LICENSE +21 -0
  3. package/README.md +344 -0
  4. package/agents/prompts/cx-accessibility.md +29 -0
  5. package/agents/prompts/cx-ai-engineer.md +31 -0
  6. package/agents/prompts/cx-architect.md +40 -0
  7. package/agents/prompts/cx-business-strategist.md +25 -0
  8. package/agents/prompts/cx-data-analyst.md +30 -0
  9. package/agents/prompts/cx-data-engineer.md +32 -0
  10. package/agents/prompts/cx-debugger.md +27 -0
  11. package/agents/prompts/cx-designer.md +33 -0
  12. package/agents/prompts/cx-devil-advocate.md +36 -0
  13. package/agents/prompts/cx-docs-keeper.md +50 -0
  14. package/agents/prompts/cx-engineer.md +36 -0
  15. package/agents/prompts/cx-evaluator.md +26 -0
  16. package/agents/prompts/cx-explorer.md +38 -0
  17. package/agents/prompts/cx-legal-compliance.md +25 -0
  18. package/agents/prompts/cx-operations.md +28 -0
  19. package/agents/prompts/cx-orchestrator.md +30 -0
  20. package/agents/prompts/cx-platform-engineer.md +25 -0
  21. package/agents/prompts/cx-product-manager.md +30 -0
  22. package/agents/prompts/cx-qa.md +42 -0
  23. package/agents/prompts/cx-rd-lead.md +25 -0
  24. package/agents/prompts/cx-release-manager.md +31 -0
  25. package/agents/prompts/cx-researcher.md +31 -0
  26. package/agents/prompts/cx-reviewer.md +36 -0
  27. package/agents/prompts/cx-security.md +37 -0
  28. package/agents/prompts/cx-sre.md +26 -0
  29. package/agents/prompts/cx-test-automation.md +35 -0
  30. package/agents/prompts/cx-trace-reviewer.md +76 -0
  31. package/agents/prompts/cx-ux-researcher.md +30 -0
  32. package/agents/registry.json +879 -0
  33. package/agents/teams.json +94 -0
  34. package/bin/construct +613 -0
  35. package/commands/build/feature.md +21 -0
  36. package/commands/build/fix.md +20 -0
  37. package/commands/design/access.md +19 -0
  38. package/commands/design/flow.md +16 -0
  39. package/commands/design/ui.md +18 -0
  40. package/commands/measure/experiment.md +18 -0
  41. package/commands/measure/metrics.md +18 -0
  42. package/commands/measure/results.md +18 -0
  43. package/commands/plan/api.md +19 -0
  44. package/commands/plan/challenge.md +18 -0
  45. package/commands/plan/decide.md +20 -0
  46. package/commands/plan/feature.md +49 -0
  47. package/commands/plan/requirements.md +24 -0
  48. package/commands/remember/context.md +26 -0
  49. package/commands/remember/handoff.md +19 -0
  50. package/commands/remember/runbook.md +20 -0
  51. package/commands/review/code.md +21 -0
  52. package/commands/review/quality.md +19 -0
  53. package/commands/review/security.md +16 -0
  54. package/commands/ship/ready.md +19 -0
  55. package/commands/ship/release.md +19 -0
  56. package/commands/ship/status.md +18 -0
  57. package/commands/understand/docs.md +22 -0
  58. package/commands/understand/research.md +22 -0
  59. package/commands/understand/this.md +23 -0
  60. package/commands/understand/why.md +18 -0
  61. package/commands/work/clean.md +32 -0
  62. package/commands/work/drive.md +69 -0
  63. package/commands/work/optimize-prompts.md +46 -0
  64. package/commands/work/parallel-review.md +40 -0
  65. package/db/migrations/001_init.sql +38 -0
  66. package/langfuse/docker-compose.yml +82 -0
  67. package/lib/audit-skills.mjs +118 -0
  68. package/lib/auto-docs.mjs +293 -0
  69. package/lib/cli-commands.mjs +409 -0
  70. package/lib/codex-config.mjs +114 -0
  71. package/lib/comment-lint.mjs +191 -0
  72. package/lib/completions.mjs +170 -0
  73. package/lib/context-state.mjs +99 -0
  74. package/lib/cost.mjs +213 -0
  75. package/lib/distill.mjs +403 -0
  76. package/lib/efficiency.mjs +139 -0
  77. package/lib/env-config.mjs +53 -0
  78. package/lib/eval-harness.mjs +59 -0
  79. package/lib/features.mjs +209 -0
  80. package/lib/headhunt.mjs +597 -0
  81. package/lib/hooks/adaptive-lint.mjs +112 -0
  82. package/lib/hooks/agent-tracker.mjs +50 -0
  83. package/lib/hooks/bootstrap-guard.mjs +90 -0
  84. package/lib/hooks/comment-lint.mjs +26 -0
  85. package/lib/hooks/config-protection.mjs +52 -0
  86. package/lib/hooks/console-warn.mjs +43 -0
  87. package/lib/hooks/context-window-recovery.mjs +90 -0
  88. package/lib/hooks/continuation-enforcer.mjs +72 -0
  89. package/lib/hooks/dep-audit.mjs +155 -0
  90. package/lib/hooks/drive-guard.mjs +89 -0
  91. package/lib/hooks/edit-accumulator.mjs +36 -0
  92. package/lib/hooks/edit-error-recovery.mjs +46 -0
  93. package/lib/hooks/edit-guard.mjs +109 -0
  94. package/lib/hooks/env-check.mjs +80 -0
  95. package/lib/hooks/guard-bash.mjs +83 -0
  96. package/lib/hooks/mcp-audit.mjs +57 -0
  97. package/lib/hooks/mcp-health-check.mjs +51 -0
  98. package/lib/hooks/mcp-task-scope.mjs +47 -0
  99. package/lib/hooks/model-fallback.mjs +105 -0
  100. package/lib/hooks/pre-compact.mjs +212 -0
  101. package/lib/hooks/pre-push-gate.mjs +129 -0
  102. package/lib/hooks/read-tracker.mjs +129 -0
  103. package/lib/hooks/registry-sync.mjs +23 -0
  104. package/lib/hooks/scan-secrets.mjs +76 -0
  105. package/lib/hooks/session-start.mjs +95 -0
  106. package/lib/hooks/stop-notify.mjs +191 -0
  107. package/lib/hooks/stop-typecheck.mjs +83 -0
  108. package/lib/hooks/task-completed-guard.mjs +43 -0
  109. package/lib/hooks/teammate-idle-guard.mjs +54 -0
  110. package/lib/hooks/workflow-guard.mjs +62 -0
  111. package/lib/host-capabilities.mjs +123 -0
  112. package/lib/init-docs.mjs +382 -0
  113. package/lib/mcp/server.mjs +1123 -0
  114. package/lib/mcp-catalog.json +243 -0
  115. package/lib/mcp-manager.mjs +433 -0
  116. package/lib/mcp-platform-config.mjs +104 -0
  117. package/lib/model-router.mjs +810 -0
  118. package/lib/opencode-config.mjs +44 -0
  119. package/lib/opencode-runtime-plugin.mjs +909 -0
  120. package/lib/opencode-telemetry.mjs +433 -0
  121. package/lib/orchestration-policy.mjs +258 -0
  122. package/lib/prompt-composer.mjs +196 -0
  123. package/lib/prompt-metadata.mjs +68 -0
  124. package/lib/review.mjs +429 -0
  125. package/lib/role-preload.mjs +52 -0
  126. package/lib/schemas/decision.json +50 -0
  127. package/lib/schemas/implementation.json +51 -0
  128. package/lib/schemas/review-report.json +32 -0
  129. package/lib/schemas/test-report.json +43 -0
  130. package/lib/server/index.mjs +334 -0
  131. package/lib/server/static/app.js +841 -0
  132. package/lib/server/static/index.html +820 -0
  133. package/lib/service-manager.mjs +225 -0
  134. package/lib/setup.mjs +319 -0
  135. package/lib/status.mjs +707 -0
  136. package/lib/storage/backend.mjs +44 -0
  137. package/lib/storage/embeddings.mjs +70 -0
  138. package/lib/storage/hybrid-query.mjs +184 -0
  139. package/lib/storage/sql-store.mjs +55 -0
  140. package/lib/storage/state-source.mjs +101 -0
  141. package/lib/storage/sync.mjs +164 -0
  142. package/lib/storage/vector-store.mjs +59 -0
  143. package/lib/telemetry/backends/langfuse.mjs +58 -0
  144. package/lib/telemetry/backends/noop.mjs +16 -0
  145. package/lib/telemetry/langfuse-ingest.mjs +108 -0
  146. package/lib/telemetry/langfuse-model-sync.mjs +270 -0
  147. package/lib/telemetry/team-rollup.mjs +143 -0
  148. package/lib/toolkit-env.mjs +30 -0
  149. package/lib/validator.mjs +181 -0
  150. package/lib/workflow-state.mjs +794 -0
  151. package/package.json +53 -0
  152. package/personas/construct.md +94 -0
  153. package/platforms/claude/CLAUDE.md +30 -0
  154. package/platforms/claude/settings.template.json +472 -0
  155. package/platforms/opencode/config.template.json +65 -0
  156. package/platforms/opencode/plugins/construct-fallback.js +5 -0
  157. package/platforms/opencode/sync-config.mjs +69 -0
  158. package/rules/common/agents.md +55 -0
  159. package/rules/common/code-review.md +129 -0
  160. package/rules/common/coding-style.md +95 -0
  161. package/rules/common/comments.md +139 -0
  162. package/rules/common/cx-agent-routing.md +61 -0
  163. package/rules/common/cx-skill-routing.md +11 -0
  164. package/rules/common/development-workflow.md +49 -0
  165. package/rules/common/git-workflow.md +29 -0
  166. package/rules/common/hooks.md +35 -0
  167. package/rules/common/patterns.md +36 -0
  168. package/rules/common/performance.md +71 -0
  169. package/rules/common/security.md +34 -0
  170. package/rules/common/testing.md +62 -0
  171. package/rules/golang/coding-style.md +37 -0
  172. package/rules/golang/hooks.md +22 -0
  173. package/rules/golang/patterns.md +50 -0
  174. package/rules/golang/security.md +39 -0
  175. package/rules/golang/testing.md +36 -0
  176. package/rules/python/coding-style.md +47 -0
  177. package/rules/python/hooks.md +24 -0
  178. package/rules/python/patterns.md +44 -0
  179. package/rules/python/security.md +35 -0
  180. package/rules/python/testing.md +43 -0
  181. package/rules/swift/coding-style.md +52 -0
  182. package/rules/swift/hooks.md +25 -0
  183. package/rules/swift/patterns.md +71 -0
  184. package/rules/swift/security.md +38 -0
  185. package/rules/swift/testing.md +50 -0
  186. package/rules/typescript/coding-style.md +204 -0
  187. package/rules/typescript/hooks.md +27 -0
  188. package/rules/typescript/patterns.md +57 -0
  189. package/rules/typescript/security.md +33 -0
  190. package/rules/typescript/testing.md +23 -0
  191. package/rules/web/coding-style.md +101 -0
  192. package/rules/web/design-quality.md +68 -0
  193. package/rules/web/hooks.md +125 -0
  194. package/rules/web/patterns.md +84 -0
  195. package/rules/web/performance.md +69 -0
  196. package/rules/web/security.md +62 -0
  197. package/rules/web/testing.md +60 -0
  198. package/rules/zh/README.md +113 -0
  199. package/rules/zh/agents.md +55 -0
  200. package/rules/zh/code-review.md +129 -0
  201. package/rules/zh/coding-style.md +53 -0
  202. package/rules/zh/development-workflow.md +49 -0
  203. package/rules/zh/git-workflow.md +29 -0
  204. package/rules/zh/hooks.md +35 -0
  205. package/rules/zh/patterns.md +36 -0
  206. package/rules/zh/performance.md +60 -0
  207. package/rules/zh/security.md +34 -0
  208. package/rules/zh/testing.md +34 -0
  209. package/skills/ai/agent-dev.md +102 -0
  210. package/skills/ai/llm-security.md +105 -0
  211. package/skills/ai/ml-ops.md +169 -0
  212. package/skills/ai/orchestration-workflow.md +87 -0
  213. package/skills/ai/prompt-and-eval.md +114 -0
  214. package/skills/ai/prompt-optimizer.md +114 -0
  215. package/skills/ai/rag-system.md +104 -0
  216. package/skills/architecture/api-design.md +100 -0
  217. package/skills/architecture/caching.md +101 -0
  218. package/skills/architecture/cloud-native.md +97 -0
  219. package/skills/architecture/message-queue.md +100 -0
  220. package/skills/architecture/security-arch.md +105 -0
  221. package/skills/development/cpp.md +127 -0
  222. package/skills/development/go.md +129 -0
  223. package/skills/development/java.md +134 -0
  224. package/skills/development/kotlin.md +140 -0
  225. package/skills/development/mobile-crossplatform.md +144 -0
  226. package/skills/development/python.md +109 -0
  227. package/skills/development/rust.md +127 -0
  228. package/skills/development/shell.md +127 -0
  229. package/skills/development/swift.md +129 -0
  230. package/skills/development/typescript.md +129 -0
  231. package/skills/devops/ci-cd.md +108 -0
  232. package/skills/devops/containerization.md +106 -0
  233. package/skills/devops/cost-optimization.md +105 -0
  234. package/skills/devops/data-engineering.md +181 -0
  235. package/skills/devops/database.md +95 -0
  236. package/skills/devops/dependency-management.md +91 -0
  237. package/skills/devops/devsecops.md +96 -0
  238. package/skills/devops/git-workflow.md +100 -0
  239. package/skills/devops/incident-response.md +167 -0
  240. package/skills/devops/monorepo.md +87 -0
  241. package/skills/devops/observability.md +103 -0
  242. package/skills/devops/performance.md +104 -0
  243. package/skills/devops/testing.md +104 -0
  244. package/skills/docs/adr-workflow.md +32 -0
  245. package/skills/docs/backlog-proposal-workflow.md +19 -0
  246. package/skills/docs/customer-profile-workflow.md +22 -0
  247. package/skills/docs/evidence-ingest-workflow.md +23 -0
  248. package/skills/docs/init-docs.md +160 -0
  249. package/skills/docs/init-project.md +50 -0
  250. package/skills/docs/prd-workflow.md +57 -0
  251. package/skills/docs/prfaq-workflow.md +25 -0
  252. package/skills/docs/product-intelligence-review.md +22 -0
  253. package/skills/docs/product-intelligence-workflow.md +62 -0
  254. package/skills/docs/product-signal-workflow.md +27 -0
  255. package/skills/docs/research-workflow.md +28 -0
  256. package/skills/docs/runbook-workflow.md +24 -0
  257. package/skills/exploration/repo-map.md +297 -0
  258. package/skills/frameworks/django.md +159 -0
  259. package/skills/frameworks/nextjs.md +148 -0
  260. package/skills/frameworks/react.md +132 -0
  261. package/skills/frameworks/spring-boot.md +165 -0
  262. package/skills/frontend-design/accessibility.md +153 -0
  263. package/skills/frontend-design/component-patterns.md +111 -0
  264. package/skills/frontend-design/engineering.md +122 -0
  265. package/skills/frontend-design/state-management.md +118 -0
  266. package/skills/frontend-design/ui-aesthetics.md +102 -0
  267. package/skills/frontend-design/ux-principles.md +126 -0
  268. package/skills/quality-gates/review-work.md +90 -0
  269. package/skills/quality-gates/verify-change.md +94 -0
  270. package/skills/quality-gates/verify-module.md +96 -0
  271. package/skills/quality-gates/verify-quality.md +93 -0
  272. package/skills/quality-gates/verify-security.md +95 -0
  273. package/skills/roles/architect.ai-systems.md +37 -0
  274. package/skills/roles/architect.data.md +37 -0
  275. package/skills/roles/architect.enterprise.md +37 -0
  276. package/skills/roles/architect.integration.md +37 -0
  277. package/skills/roles/architect.md +68 -0
  278. package/skills/roles/architect.platform.md +37 -0
  279. package/skills/roles/data-analyst.experiment.md +37 -0
  280. package/skills/roles/data-analyst.md +68 -0
  281. package/skills/roles/data-analyst.product-intelligence.md +37 -0
  282. package/skills/roles/data-analyst.product.md +37 -0
  283. package/skills/roles/data-analyst.telemetry.md +37 -0
  284. package/skills/roles/data-engineer.pipeline.md +37 -0
  285. package/skills/roles/data-engineer.vector-retrieval.md +37 -0
  286. package/skills/roles/data-engineer.warehouse.md +37 -0
  287. package/skills/roles/debugger.md +68 -0
  288. package/skills/roles/designer.accessibility.md +43 -0
  289. package/skills/roles/designer.md +68 -0
  290. package/skills/roles/engineer.ai.md +49 -0
  291. package/skills/roles/engineer.data.md +49 -0
  292. package/skills/roles/engineer.md +85 -0
  293. package/skills/roles/engineer.platform.md +49 -0
  294. package/skills/roles/operator.docs.md +43 -0
  295. package/skills/roles/operator.md +68 -0
  296. package/skills/roles/operator.release.md +43 -0
  297. package/skills/roles/operator.sre.md +43 -0
  298. package/skills/roles/orchestrator.md +66 -0
  299. package/skills/roles/product-manager.ai-product.md +37 -0
  300. package/skills/roles/product-manager.business-strategy.md +43 -0
  301. package/skills/roles/product-manager.enterprise.md +37 -0
  302. package/skills/roles/product-manager.growth.md +37 -0
  303. package/skills/roles/product-manager.md +67 -0
  304. package/skills/roles/product-manager.platform.md +37 -0
  305. package/skills/roles/product-manager.product.md +37 -0
  306. package/skills/roles/qa.ai-eval.md +37 -0
  307. package/skills/roles/qa.api-contract.md +37 -0
  308. package/skills/roles/qa.data-pipeline.md +37 -0
  309. package/skills/roles/qa.md +68 -0
  310. package/skills/roles/qa.test-automation.md +49 -0
  311. package/skills/roles/qa.web-ui.md +37 -0
  312. package/skills/roles/researcher.explorer.md +43 -0
  313. package/skills/roles/researcher.md +68 -0
  314. package/skills/roles/researcher.ux.md +43 -0
  315. package/skills/roles/reviewer.devil-advocate.md +43 -0
  316. package/skills/roles/reviewer.evaluator.md +43 -0
  317. package/skills/roles/reviewer.md +68 -0
  318. package/skills/roles/reviewer.trace.md +43 -0
  319. package/skills/roles/security.ai.md +37 -0
  320. package/skills/roles/security.appsec.md +37 -0
  321. package/skills/roles/security.cloud.md +37 -0
  322. package/skills/roles/security.legal-compliance.md +49 -0
  323. package/skills/roles/security.md +68 -0
  324. package/skills/roles/security.privacy.md +37 -0
  325. package/skills/roles/security.supply-chain.md +37 -0
  326. package/skills/routing.md +139 -0
  327. package/skills/security/blue-team.md +83 -0
  328. package/skills/security/code-audit.md +94 -0
  329. package/skills/security/pentest.md +84 -0
  330. package/skills/security/red-team.md +81 -0
  331. package/skills/security/threat-intel.md +89 -0
  332. package/skills/security/vuln-research.md +87 -0
  333. package/skills/utility/clean-code.md +165 -0
  334. package/sync-agents.mjs +899 -0
  335. package/templates/docs/adr.md +27 -0
  336. package/templates/docs/backlog-proposal.md +26 -0
  337. package/templates/docs/customer-profile.md +34 -0
  338. package/templates/docs/evidence-brief.md +37 -0
  339. package/templates/docs/incident-report.md +46 -0
  340. package/templates/docs/memo.md +27 -0
  341. package/templates/docs/meta-prd.md +56 -0
  342. package/templates/docs/one-pager.md +24 -0
  343. package/templates/docs/prd-business.md +61 -0
  344. package/templates/docs/prd-platform.md +62 -0
  345. package/templates/docs/prd.md +47 -0
  346. package/templates/docs/prfaq.md +31 -0
  347. package/templates/docs/product-intelligence-report.md +31 -0
  348. package/templates/docs/research-brief.md +29 -0
  349. package/templates/docs/rfc-platform.md +60 -0
  350. package/templates/docs/rfc.md +46 -0
  351. package/templates/docs/runbook.md +33 -0
  352. package/templates/docs/signal-brief.md +25 -0
@@ -0,0 +1,132 @@
1
+ <!--
2
+ skills/frameworks/react.md — React — By default, components are **Server Components** — they run on the server, have
3
+
4
+ ## Component Design ### Server vs Client Components (React 19 / Next.js App Router)
5
+ -->
6
+ # React
7
+
8
+ ## Component Design
9
+
10
+ ### Server vs Client Components (React 19 / Next.js App Router)
11
+
12
+ By default, components are **Server Components** — they run on the server, have no state, and can fetch data directly. Add `'use client'` only when you need interactivity, browser APIs, or hooks.
13
+
14
+ ```tsx
15
+ // Server Component — no directive needed
16
+ async function ItemList() {
17
+ const items = await db.items.findMany(); // direct DB access fine here
18
+ return <ul>{items.map(i => <Item key={i.id} {...i} />)}</ul>;
19
+ }
20
+
21
+ // Client Component — needs browser or state
22
+ 'use client';
23
+ export function SearchBar({ onSearch }: { onSearch: (q: string) => void }) {
24
+ const [query, setQuery] = useState('');
25
+ ...
26
+ }
27
+ ```
28
+
29
+ Push the `'use client'` boundary as far down the tree as possible.
30
+
31
+ ### Composition over configuration
32
+
33
+ Prefer children and render props over proliferating boolean props:
34
+
35
+ ```tsx
36
+ // Avoid: <Modal showHeader closeButton title="..." />
37
+ // Prefer:
38
+ <Modal>
39
+ <Modal.Header onClose={close}>Title</Modal.Header>
40
+ <Modal.Body>...</Modal.Body>
41
+ </Modal>
42
+ ```
43
+
44
+ ## State Management
45
+
46
+ See decision matrix:
47
+
48
+ | Concern | Tool |
49
+ |---|---|
50
+ | Server state (fetching, caching) | TanStack Query / SWR |
51
+ | Global UI state | Zustand / Jotai |
52
+ | Form state | React Hook Form + Zod |
53
+ | URL state | `useSearchParams` / router |
54
+ | Component-local state | `useState` / `useReducer` |
55
+
56
+ Do not put server data in a client store — TanStack Query is the cache. Derive don't duplicate.
57
+
58
+ ## Performance
59
+
60
+ ### Memoization discipline
61
+
62
+ `useMemo` and `useCallback` add overhead if misapplied. Measure first:
63
+
64
+ ```tsx
65
+ // Justified: expensive computation, stable deps
66
+ const sorted = useMemo(() => expensiveSort(items), [items]);
67
+
68
+ // Unjustified: not expensive, adds indirection for nothing
69
+ const label = useMemo(() => `Hello ${name}`, [name]);
70
+ ```
71
+
72
+ ### Concurrent features
73
+
74
+ - `useTransition` for non-urgent state updates (e.g., search filter)
75
+ - `useDeferredValue` to deprioritize expensive re-renders while keeping input responsive
76
+ - `<Suspense>` boundaries for async data; pair with streaming in App Router
77
+
78
+ ### Code splitting
79
+
80
+ ```tsx
81
+ const HeavyChart = lazy(() => import('./HeavyChart'));
82
+ <Suspense fallback={<Spinner />}><HeavyChart /></Suspense>
83
+ ```
84
+
85
+ ## Patterns
86
+
87
+ ### Custom hooks extract logic, not JSX
88
+
89
+ ```ts
90
+ // Good: encapsulates fetch + error + loading
91
+ export function useItems() {
92
+ return useQuery({ queryKey: ['items'], queryFn: fetchItems });
93
+ }
94
+ ```
95
+
96
+ ### Controlled vs uncontrolled
97
+
98
+ - Controlled: React owns value via `state` — use for forms with validation, derived fields
99
+ - Uncontrolled: DOM owns value via `ref` — use for file inputs and simple browser-owned fields
100
+
101
+ ## Testing
102
+
103
+ ```tsx
104
+ import { render, screen } from '@testing-library/react';
105
+ import userEvent from '@testing-library/user-event';
106
+
107
+ test('submits search query', async () => {
108
+ const onSearch = vi.fn();
109
+ render(<SearchBar onSearch={onSearch} />);
110
+ await userEvent.type(screen.getByRole('searchbox'), 'react');
111
+ await userEvent.keyboard('{Enter}');
112
+ expect(onSearch).toHaveBeenCalledWith('react');
113
+ });
114
+ ```
115
+
116
+ - Use `@testing-library/react` — test behavior, not implementation
117
+ - `userEvent` over `fireEvent` — simulates real user interactions
118
+ - Mock at the network boundary (`msw`) not the component boundary
119
+
120
+ ## Tooling
121
+
122
+ - **Vite** for non-Next apps; fast HMR, native ESM
123
+ - **Biome** for lint + format in a single fast tool (replaces ESLint + Prettier)
124
+ - **TypeScript strict mode** — enables `noUncheckedIndexedAccess`, `strictNullChecks`, etc.
125
+ - React DevTools Profiler for recomposition analysis
126
+
127
+ ## Common Pitfalls
128
+
129
+ - Stale closures in `useEffect` — include all reactive values in the dependency array or use `useEffectEvent` (React 19)
130
+ - `useEffect` for data fetching — use TanStack Query instead
131
+ - Direct DOM mutation inside render — causes tearing with concurrent mode
132
+ - Key prop as array index — breaks reconciliation on reorder/insert
@@ -0,0 +1,165 @@
1
+ <!--
2
+ skills/frameworks/spring-boot.md — Spring Boot — ```
3
+
4
+ ## Project Structure ```
5
+ -->
6
+ # Spring Boot
7
+
8
+ ## Project Structure
9
+
10
+ ```
11
+ src/
12
+ ├── main/
13
+ │ ├── kotlin/com/example/app/
14
+ │ │ ├── Application.kt ← @SpringBootApplication entry
15
+ │ │ ├── config/ ← @Configuration classes
16
+ │ │ ├── domain/ ← Entities, value objects
17
+ │ │ ├── repository/ ← Spring Data repositories
18
+ │ │ ├── service/ ← Business logic (@Service)
19
+ │ │ ├── web/ ← Controllers (@RestController)
20
+ │ │ │ ├── dto/ ← Request/response DTOs
21
+ │ │ │ └── advice/ ← @ControllerAdvice
22
+ │ │ └── security/ ← Security config
23
+ │ └── resources/
24
+ │ ├── application.yml
25
+ │ └── db/migration/ ← Flyway migrations
26
+ └── test/
27
+ ```
28
+
29
+ ## Layered Architecture
30
+
31
+ ```
32
+ @RestController → @Service → @Repository → DB
33
+ ```
34
+
35
+ - **Controller**: validate input, delegate to service, map to DTO
36
+ - **Service**: business logic; transaction boundary; no JPA entities exposed outside layer
37
+ - **Repository**: data access only; query methods or `@Query`
38
+ - **Domain**: pure entities with business behavior; no Spring dependencies
39
+
40
+ Never inject repositories directly into controllers.
41
+
42
+ ## REST Controllers
43
+
44
+ ```kotlin
45
+ @RestController
46
+ @RequestMapping("/api/items")
47
+ class ItemController(private val itemService: ItemService) {
48
+
49
+ @GetMapping("/{id}")
50
+ fun getItem(@PathVariable id: UUID): ResponseEntity<ItemDto> =
51
+ itemService.findById(id)
52
+ ?.let { ResponseEntity.ok(it.toDto()) }
53
+ ?: ResponseEntity.notFound().build()
54
+
55
+ @PostMapping
56
+ @ResponseStatus(HttpStatus.CREATED)
57
+ fun createItem(@Valid @RequestBody req: CreateItemRequest): ItemDto =
58
+ itemService.create(req).toDto()
59
+ }
60
+ ```
61
+
62
+ Use `@Valid` + Bean Validation (`@NotBlank`, `@Size`, etc.) for input validation. Handle `MethodArgumentNotValidException` in `@ControllerAdvice`.
63
+
64
+ ## JPA / Spring Data
65
+
66
+ ```kotlin
67
+ @Entity
68
+ @Table(name = "items")
69
+ class Item(
70
+ @Id val id: UUID = UUID.randomUUID(),
71
+ @Column(nullable = false) var title: String,
72
+ @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "owner_id") val owner: User,
73
+ )
74
+
75
+ interface ItemRepository : JpaRepository<Item, UUID> {
76
+ fun findByOwnerAndStatus(owner: User, status: Status): List<Item>
77
+
78
+ @Query("SELECT i FROM Item i JOIN FETCH i.owner WHERE i.id = :id")
79
+ fun findByIdWithOwner(id: UUID): Item?
80
+ }
81
+ ```
82
+
83
+ - Default `FetchType.LAZY` for associations — never `EAGER`
84
+ - Use `JOIN FETCH` in queries when you need the association
85
+ - Enable `spring.jpa.open-in-view=false` — prevents lazy-loading in the web layer
86
+ - Use Flyway or Liquibase for schema migrations; never `ddl-auto=update` in production
87
+
88
+ ## Transactions
89
+
90
+ ```kotlin
91
+ @Service
92
+ @Transactional(readOnly = true) // default for the class
93
+ class ItemService(private val repo: ItemRepository) {
94
+
95
+ @Transactional // write override
96
+ fun create(req: CreateItemRequest): Item {
97
+ val item = Item(title = req.title, owner = currentUser())
98
+ return repo.save(item)
99
+ }
100
+ }
101
+ ```
102
+
103
+ - `@Transactional` on service layer, not repository or controller
104
+ - `readOnly = true` as class-level default; override on writes — signals no dirty-check needed
105
+ - Do not call `@Transactional` methods via `this` — Spring proxy won't intercept it
106
+
107
+ ## Security (Spring Security 6)
108
+
109
+ ```kotlin
110
+ @Configuration
111
+ @EnableWebSecurity
112
+ class SecurityConfig {
113
+ @Bean
114
+ fun securityFilterChain(http: HttpSecurity): SecurityFilterChain = http
115
+ .csrf { it.disable() } // stateless JWT API
116
+ .sessionManagement { it.sessionCreationPolicy(STATELESS) }
117
+ .authorizeHttpRequests {
118
+ it.requestMatchers("/api/auth/**").permitAll()
119
+ .anyRequest().authenticated()
120
+ }
121
+ .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter::class.java)
122
+ .build()
123
+ }
124
+ ```
125
+
126
+ - JWT for stateless APIs; sessions for web apps with CSRF
127
+ - `@PreAuthorize("hasRole('ADMIN')")` for method-level authorization
128
+ - Never log authentication credentials or tokens
129
+
130
+ ## Testing
131
+
132
+ ```kotlin
133
+ @SpringBootTest(webEnvironment = RANDOM_PORT)
134
+ @AutoConfigureTestDatabase(replace = NONE) // use Testcontainers
135
+ class ItemControllerIT(@Autowired val restTemplate: TestRestTemplate) {
136
+
137
+ @Test
138
+ fun `POST items creates and returns 201`() {
139
+ val resp = restTemplate.postForEntity("/api/items",
140
+ CreateItemRequest(title = "Test"), ItemDto::class.java)
141
+ assertEquals(HttpStatus.CREATED, resp.statusCode)
142
+ }
143
+ }
144
+ ```
145
+
146
+ - `@WebMvcTest` for controller-only tests (fast, no DB)
147
+ - `@DataJpaTest` for repository tests against a real embedded or Testcontainers DB
148
+ - `@SpringBootTest` for integration tests — use Testcontainers for realistic DB
149
+ - `MockMvc` + `@AutoConfigureMockMvc` for HTTP-layer testing without a real port
150
+
151
+ ## Performance
152
+
153
+ - Connection pool: `HikariCP` (default) — tune `maximumPoolSize` based on load testing
154
+ - N+1 queries: use `JOIN FETCH` or `@EntityGraph`; verify with `spring.jpa.show-sql=true` in dev
155
+ - Caching: `@Cacheable` + Spring Cache with Redis (`spring-boot-starter-data-redis`)
156
+ - Async: `@EnableAsync` + `@Async` on service methods for fire-and-forget; use `CompletableFuture<T>` return type
157
+ - Virtual threads (Spring Boot 3.2+): `spring.threads.virtual.enabled=true` for high-concurrency blocking I/O
158
+
159
+ ## Common Pitfalls
160
+
161
+ - `LazyInitializationException` after transaction closes — resolve with `JOIN FETCH` or DTO projection
162
+ - `@Transactional` on private methods — Spring AOP proxy can't intercept; move to public
163
+ - Bean cycle injection — restructure or use `@Lazy`
164
+ - Returning JPA entities directly from controllers — exposes internal model; always map to DTOs
165
+ - `findAll()` without pagination on large tables — always use `Pageable`
@@ -0,0 +1,153 @@
1
+ <!--
2
+ skills/frontend-design/accessibility.md — Accessibility (WCAG 2.2 / Inclusive Design) — Target **WCAG 2.1 AA** as the minimum for any public-facing product. WCAG 2.2 AA
3
+
4
+ ## Compliance Baseline Target **WCAG 2.1 AA** as the minimum for any public-facing product. WCAG 2.2 AA is the current standard (published October 2023) and req
5
+ -->
6
+ # Accessibility (WCAG 2.2 / Inclusive Design)
7
+
8
+ ## Compliance Baseline
9
+
10
+ Target **WCAG 2.1 AA** as the minimum for any public-facing product. WCAG 2.2 AA is the current standard (published October 2023) and required by many regulatory frameworks (EU Web Accessibility Directive, ADA, Section 508).
11
+
12
+ ## Semantic HTML First
13
+
14
+ Use the right element before reaching for ARIA:
15
+
16
+ ```html
17
+ <!-- Avoid: div soup -->
18
+ <div class="btn" onclick="submit()">Submit</div>
19
+
20
+ <!-- Correct: semantic button -->
21
+ <button type="submit">Submit</button>
22
+ ```
23
+
24
+ ARIA augments semantics it can't add natively; it cannot fix broken semantics.
25
+
26
+ ## ARIA Rules
27
+
28
+ 1. If a native HTML element provides the required semantics, use it — do not add ARIA to a `<div>` when `<button>` exists.
29
+ 2. Do not change native semantics: `<h2 role="button">` is invalid.
30
+ 3. All interactive ARIA widgets must be keyboard-operable.
31
+ 4. Do not hide focusable elements with `aria-hidden="true"`.
32
+ 5. Every interactive element must have an accessible name.
33
+
34
+ Common patterns:
35
+
36
+ ```html
37
+ <!-- Label associated via for/id -->
38
+ <label for="email">Email</label>
39
+ <input id="email" type="email" />
40
+
41
+ <!-- Icon button with visually hidden label -->
42
+ <button aria-label="Close dialog">
43
+ <svg aria-hidden="true">...</svg>
44
+ </button>
45
+
46
+ <!-- Live region for async updates -->
47
+ <div aria-live="polite" aria-atomic="true" id="status"></div>
48
+ ```
49
+
50
+ ## Keyboard Navigation
51
+
52
+ Every interactive element must be reachable and operable by keyboard:
53
+
54
+ | Key | Expected behavior |
55
+ |---|---|
56
+ | `Tab` / `Shift+Tab` | Move focus forward / backward |
57
+ | `Enter` | Activate links and buttons |
58
+ | `Space` | Activate buttons, toggle checkboxes |
59
+ | `Arrow keys` | Navigate within composite widgets (menus, tabs, sliders) |
60
+ | `Escape` | Close modals, dismiss menus |
61
+
62
+ Focus trap in modals:
63
+
64
+ ```ts
65
+ // Lock focus inside the modal when open
66
+ function trapFocus(modal: HTMLElement) {
67
+ const focusable = modal.querySelectorAll<HTMLElement>(
68
+ 'a[href], button:not([disabled]), input, select, textarea, [tabindex]:not([tabindex="-1"])'
69
+ );
70
+ const first = focusable[0];
71
+ const last = focusable[focusable.length - 1];
72
+ modal.addEventListener('keydown', (e) => {
73
+ if (e.key === 'Tab') {
74
+ if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
75
+ else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
76
+ }
77
+ });
78
+ }
79
+ ```
80
+
81
+ ## Color & Contrast
82
+
83
+ | Text size | Minimum contrast (AA) | Enhanced (AAA) |
84
+ |---|---|---|
85
+ | Normal text (< 18pt / 14pt bold) | 4.5:1 | 7:1 |
86
+ | Large text (≥ 18pt / 14pt bold) | 3:1 | 4.5:1 |
87
+ | UI components / graphical objects | 3:1 | — |
88
+
89
+ Tools: Figma Contrast plugin, axe DevTools, APCA calculator for sophisticated use cases.
90
+
91
+ Do not convey information by color alone — add shape, pattern, or text.
92
+
93
+ ## Motion
94
+
95
+ Respect `prefers-reduced-motion`:
96
+
97
+ ```css
98
+ @media (prefers-reduced-motion: reduce) {
99
+ *, *::before, *::after {
100
+ animation-duration: 0.01ms !important;
101
+ transition-duration: 0.01ms !important;
102
+ }
103
+ }
104
+ ```
105
+
106
+ In JS animations (GSAP, Framer Motion):
107
+
108
+ ```ts
109
+ const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
110
+ if (!prefersReduced) gsap.to(el, { y: -20, duration: 0.3 });
111
+ ```
112
+
113
+ ## Images & Media
114
+
115
+ - Decorative images: `alt=""`
116
+ - Informative images: concise alt text describing the content, not "image of"
117
+ - Complex images (charts, diagrams): short alt + long description via `aria-describedby` or adjacent text
118
+ - Video: captions for dialogue/audio content; audio description for visual-only information
119
+ - Auto-playing media: provide pause control; do not autoplay with sound
120
+
121
+ ## Forms
122
+
123
+ ```html
124
+ <fieldset>
125
+ <legend>Shipping address</legend>
126
+ <label for="street">Street <span aria-hidden="true">*</span></label>
127
+ <input id="street" name="street" required aria-required="true"
128
+ aria-describedby="street-error" />
129
+ <span id="street-error" role="alert"></span>
130
+ </fieldset>
131
+ ```
132
+
133
+ - Group related fields in `<fieldset>` with `<legend>`
134
+ - Error messages: use `role="alert"` or `aria-live="assertive"` so screen readers announce them
135
+ - Required fields: `required` + `aria-required="true"`; indicate requirement visually and in text
136
+
137
+ ## Testing Checklist
138
+
139
+ - [ ] Run `axe` or `Lighthouse Accessibility` — fix all violations
140
+ - [ ] Navigate entire flow with keyboard only
141
+ - [ ] Test with VoiceOver (macOS/iOS) or NVDA/JAWS (Windows)
142
+ - [ ] Verify color contrast meets 4.5:1 for body text
143
+ - [ ] Test with browser zoom at 200% — no horizontal scroll, no content loss
144
+ - [ ] Test with `prefers-reduced-motion: reduce` enabled
145
+ - [ ] All form errors are announced by screen reader
146
+
147
+ ## Cognitive Load
148
+
149
+ - Plain language: grade 8 reading level or below for public-facing copy
150
+ - Consistent navigation: same elements in same place across pages
151
+ - Timeouts: warn before session expiry; allow extension
152
+ - Error recovery: clear error messages with actionable fix instructions
153
+ - No flashing content: nothing flashing more than 3 times/second (seizure risk)
@@ -0,0 +1,111 @@
1
+ <!--
2
+ skills/frontend-design/component-patterns.md — Component Patterns — Use this skill when designing component architecture, building design systems, o
3
+
4
+ Use this skill when designing component architecture, building design systems, or structuring reusable UI. ## Component Hierarchy
5
+ -->
6
+ # Component Patterns
7
+
8
+ Use this skill when designing component architecture, building design systems, or structuring reusable UI.
9
+
10
+ ## Component Hierarchy
11
+
12
+ ### Atoms
13
+ - Smallest meaningful UI elements: button, input, label, icon, badge
14
+ - Self-contained: no dependencies on other components
15
+ - Accept props for variants: size, color, disabled state
16
+ - Fully accessible with ARIA attributes and keyboard support
17
+
18
+ ### Molecules
19
+ - Combinations of atoms: search field (input + button), form group (label + input + error)
20
+ - Encapsulate a single interaction pattern
21
+ - Manage internal state for the interaction only
22
+
23
+ ### Organisms
24
+ - Complex sections composed of molecules: navigation bar, card grid, data table
25
+ - May connect to data sources or global state
26
+ - Define layout and composition of their children
27
+
28
+ ### Templates and Pages
29
+ - Templates define the layout structure without data
30
+ - Pages are templates filled with real content and connected to routing
31
+
32
+ ## Composition Patterns
33
+
34
+ ### Compound Components
35
+ - Related components share implicit state via context
36
+ - Parent owns state; children consume and render
37
+ - Gives consumers control over rendering while keeping logic centralized
38
+
39
+ ### Render Props / Slots
40
+ - Component provides behavior; consumer provides rendering
41
+ - Useful for headless components: dropdown logic without markup opinion
42
+ - Keeps ARIA, keyboard, and focus management in the shared layer
43
+
44
+ ### Container / Presentational
45
+ - Container: handles data fetching, state management, side effects
46
+ - Presentational: receives props, renders UI, stays pure
47
+ - Easier to test, reuse, and maintain
48
+
49
+ ### Polymorphic Components
50
+ - `as` or `component` prop to render as different HTML elements
51
+ - A `Button` that renders as `<a>` for link-style buttons
52
+ - Preserves type safety with generics
53
+
54
+ ## Props Design
55
+
56
+ - Required props: minimum needed for the component to function
57
+ - Optional props with sensible defaults
58
+ - Boolean props: avoid double negatives (`isDisabled` not `isNotEnabled`)
59
+ - Event handlers: `on` prefix (`onClick`, `onChange`)
60
+ - Children: use `children` prop or slots for composition
61
+ - Avoid prop drilling beyond two levels; use context or composition
62
+
63
+ ## State Ownership
64
+
65
+ | State Type | Where to Manage |
66
+ |---|---|
67
+ | UI state (open, focused, hovered) | Component-local |
68
+ | Form state (values, validation, dirty) | Form library or parent component |
69
+ | Server state (API data, cache) | Data fetching library (TanStack Query, SWR) |
70
+ | URL state (filters, pagination, tab) | URL / router |
71
+ | Global state (theme, user, preferences) | Context or lightweight store |
72
+
73
+ - Lift state to the nearest common ancestor that needs it
74
+ - Derive values instead of storing computed state
75
+ - Single source of truth for each piece of state
76
+
77
+ ## Design System Tokens
78
+
79
+ - **Color**: semantic names (text-primary, surface-elevated, border-subtle)
80
+ - **Typography**: scale steps (text-sm, text-base, text-lg, text-xl)
81
+ - **Spacing**: scale steps (space-1 through space-12)
82
+ - **Radius**: small, medium, large, full
83
+ - **Shadow**: elevation levels (shadow-sm, shadow-md, shadow-lg)
84
+ - Implement as CSS custom properties or theme objects
85
+ - Document every token with visual examples
86
+
87
+ ## Accessibility Checklist
88
+
89
+ - [ ] Every interactive element is keyboard accessible
90
+ - [ ] Focus order matches visual order
91
+ - [ ] Focus indicators are visible
92
+ - [ ] ARIA roles, labels, and states are correct
93
+ - [ ] Color contrast meets WCAG AA
94
+ - [ ] Animations respect `prefers-reduced-motion`
95
+ - [ ] Screen reader announces state changes (live regions)
96
+
97
+ ## Testing Components
98
+
99
+ - Unit test: logic, state transitions, prop handling
100
+ - Interaction test: click, type, keyboard navigation
101
+ - Visual regression: screenshot comparison at key breakpoints
102
+ - Accessibility audit: automated scanning plus manual keyboard test
103
+ - Storybook or equivalent for isolated component development and documentation
104
+
105
+ ## Anti-Patterns
106
+
107
+ - God components that handle fetching, state, rendering, and styling
108
+ - Prop drilling through more than two intermediate components
109
+ - Tightly coupled components that cannot be used independently
110
+ - Rebuilding browser-native behavior (scrolling, focus management) poorly
111
+ - CSS leaking between components via global selectors
@@ -0,0 +1,122 @@
1
+ <!--
2
+ skills/frontend-design/engineering.md — Frontend Engineering — Use this skill when working on build tooling, bundling, rendering strategies, or
3
+
4
+ Use this skill when working on build tooling, bundling, rendering strategies, or frontend infrastructure. ## Build Tools
5
+ -->
6
+ # Frontend Engineering
7
+
8
+ Use this skill when working on build tooling, bundling, rendering strategies, or frontend infrastructure.
9
+
10
+ ## Build Tools
11
+
12
+ | Tool | Strength |
13
+ |---|---|
14
+ | Vite | Fast dev server, ESM-native, good for most projects |
15
+ | Turbopack | Next.js integrated, incremental compilation |
16
+ | esbuild | Extremely fast bundling for libraries and tools |
17
+ | Webpack | Mature ecosystem, complex configuration |
18
+ | Rollup | Clean ESM output for libraries |
19
+ | Rspack | Webpack-compatible with Rust-based speed |
20
+
21
+ ### Configuration Principles
22
+ - Start with framework defaults; customize only when needed
23
+ - Enable tree-shaking for unused code elimination
24
+ - Code-split by route and by heavy dependency
25
+ - Source maps in development; conditional in production (security vs debugging trade-off)
26
+ - Hashed filenames for cache busting
27
+
28
+ ## Rendering Strategies
29
+
30
+ ### Static Site Generation (SSG)
31
+ - Pre-render pages at build time
32
+ - Best for: marketing pages, blogs, documentation
33
+ - Fastest TTFB; cacheable at CDN edge
34
+ - Rebuild on content change or use incremental regeneration
35
+
36
+ ### Server-Side Rendering (SSR)
37
+ - Render on each request
38
+ - Best for: dynamic content, personalized pages, SEO-critical content
39
+ - Higher TTFB than SSG; requires server infrastructure
40
+ - Hydration on the client for interactivity
41
+
42
+ ### Client-Side Rendering (CSR)
43
+ - Render entirely in the browser
44
+ - Best for: authenticated apps, dashboards, tools behind login
45
+ - Fast after initial load; poor SEO without prerendering
46
+ - Show skeleton during initial data fetch
47
+
48
+ ### Streaming SSR
49
+ - Send HTML progressively as components resolve
50
+ - Reduces TTFB by starting the response before all data is ready
51
+ - Suspense boundaries define streaming chunks
52
+ - Best for: pages with mixed fast and slow data sources
53
+
54
+ ### Islands Architecture
55
+ - Static HTML with isolated interactive components (islands)
56
+ - Minimal JavaScript shipped; only interactive parts hydrate
57
+ - Best for: content-heavy sites with sparse interactivity
58
+ - Frameworks: Astro, Fresh
59
+
60
+ ## Performance Budget
61
+
62
+ | Page Type | JS (gzipped) | CSS (gzipped) | LCP |
63
+ |---|---|---|---|
64
+ | Landing | <150KB | <30KB | <2.5s |
65
+ | App page | <300KB | <50KB | <3s |
66
+ | Microsite | <80KB | <15KB | <2s |
67
+
68
+ ### Optimization Techniques
69
+ - Dynamic imports for below-the-fold and conditional features
70
+ - Preload critical resources: hero image, primary font
71
+ - Defer non-critical CSS and JavaScript
72
+ - Compress with Brotli (or gzip fallback)
73
+ - Image optimization: AVIF/WebP, explicit dimensions, lazy loading
74
+
75
+ ## Module Federation
76
+
77
+ - Share dependencies across independently deployed micro-frontends
78
+ - Define clear ownership: one team per module
79
+ - Version shared dependencies carefully
80
+ - Fallback when a remote module is unavailable
81
+ - Use for: large organizations with multiple teams on one product
82
+
83
+ ## Monorepo Patterns
84
+
85
+ - Nx, Turborepo, or PNPM workspaces for multi-package management
86
+ - Share configuration (ESLint, TypeScript, test setup) from root
87
+ - Affected-based CI: only build/test changed packages and dependents
88
+ - Consistent dependency versions across packages
89
+ - Publish internal packages with workspace protocol
90
+
91
+ ## Developer Experience
92
+
93
+ - Hot module replacement for fast iteration
94
+ - TypeScript for type safety across the codebase
95
+ - Storybook for isolated component development
96
+ - Automated formatting and linting on save (Prettier, ESLint)
97
+ - Preview deployments on pull requests
98
+
99
+ ## Testing Infrastructure
100
+
101
+ - Unit: Vitest or Jest for logic and utilities
102
+ - Component: Testing Library for interaction tests
103
+ - Visual regression: Playwright screenshots at key breakpoints
104
+ - E2E: Playwright or Cypress for critical user flows
105
+ - Accessibility: axe-core in CI, manual keyboard testing
106
+ - Run the full suite in CI; fast subset on pre-commit
107
+
108
+ ## Deployment
109
+
110
+ - CDN for static assets with long-lived cache and content hashing
111
+ - Edge functions for dynamic personalization at the CDN layer
112
+ - Preview environments per pull request
113
+ - Feature flags for progressive rollout
114
+ - Rollback strategy: revert deploy or disable feature flag
115
+
116
+ ## Anti-Patterns
117
+
118
+ - Bundling everything into one chunk (no code splitting)
119
+ - Importing entire libraries when only a function is needed
120
+ - Client-side rendering for SEO-critical pages
121
+ - No performance budget (unconstrained growth)
122
+ - Polyfilling for browsers no longer in the support matrix