nextjs-hackathon-stack 0.1.40 → 0.1.41

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 (173) hide show
  1. package/dist/index.js +3 -63
  2. package/package.json +1 -1
  3. package/template/.claude/agents/backend.md +54 -0
  4. package/template/.claude/agents/business-analyst.md +195 -0
  5. package/template/.claude/agents/code-reviewer.md +76 -0
  6. package/template/.claude/agents/frontend.md +85 -0
  7. package/template/.claude/agents/security-researcher.md +54 -0
  8. package/template/.claude/agents/technical-lead.md +92 -0
  9. package/template/.claude/agents/test-qa.md +85 -0
  10. package/template/.claude/rules/architecture.mdc +48 -0
  11. package/template/.claude/rules/coding-standards.mdc +120 -0
  12. package/template/.claude/rules/components.mdc +49 -0
  13. package/template/.claude/rules/data-fetching.mdc +115 -0
  14. package/template/.claude/rules/forms.mdc +100 -0
  15. package/template/.claude/rules/general.mdc +54 -0
  16. package/template/.claude/rules/migrations.mdc +11 -0
  17. package/template/.claude/rules/nextjs.mdc +71 -0
  18. package/template/.claude/rules/security.mdc +108 -0
  19. package/template/.claude/rules/supabase.mdc +70 -0
  20. package/template/.claude/rules/testing.mdc +136 -0
  21. package/template/.claude/settings.json +16 -0
  22. package/template/.claude/skills/build-feature/SKILL.md +198 -0
  23. package/template/.claude/skills/build-feature/references/server-action-test-template.md +103 -0
  24. package/template/.claude/skills/create-api-route/SKILL.md +62 -0
  25. package/template/.claude/skills/discover-feature/SKILL.md +200 -0
  26. package/template/.claude/skills/memory/SKILL.md +208 -0
  27. package/template/.claude/skills/review-branch/SKILL.md +43 -0
  28. package/template/.claude/skills/review-branch/references/review-checklist.md +36 -0
  29. package/template/.claude/skills/security-audit/SKILL.md +40 -0
  30. package/template/.claude/skills/security-audit/references/audit-steps.md +41 -0
  31. package/template/.claude/skills/supabase/SKILL.md +105 -0
  32. package/template/.claude/skills/supabase/assets/feedback-issue-template.md +17 -0
  33. package/template/.claude/skills/supabase/references/skill-feedback.md +17 -0
  34. package/template/.claude/skills/supabase-postgres-best-practices/SKILL.md +65 -0
  35. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp__contributing.md +170 -0
  36. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp__sections.md +39 -0
  37. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp__template.md +34 -0
  38. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_advanced-full-text-search.md +55 -0
  39. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_advanced-jsonb-indexing.md +49 -0
  40. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_conn-idle-timeout.md +46 -0
  41. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_conn-limits.md +44 -0
  42. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_conn-pooling.md +41 -0
  43. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_conn-prepared-statements.md +46 -0
  44. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_data-batch-inserts.md +54 -0
  45. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_data-n-plus-one.md +53 -0
  46. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_data-pagination.md +50 -0
  47. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_data-upsert.md +50 -0
  48. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_lock-advisory.md +56 -0
  49. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_lock-deadlock-prevention.md +68 -0
  50. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_lock-short-transactions.md +50 -0
  51. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_lock-skip-locked.md +54 -0
  52. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_monitor-explain-analyze.md +45 -0
  53. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_monitor-pg-stat-statements.md +55 -0
  54. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_monitor-vacuum-analyze.md +55 -0
  55. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_query-composite-indexes.md +44 -0
  56. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_query-covering-indexes.md +40 -0
  57. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_query-index-types.md +48 -0
  58. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_query-missing-indexes.md +43 -0
  59. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_query-partial-indexes.md +45 -0
  60. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_schema-constraints.md +80 -0
  61. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_schema-data-types.md +46 -0
  62. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_schema-foreign-key-indexes.md +59 -0
  63. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_schema-lowercase-identifiers.md +55 -0
  64. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_schema-partitioning.md +55 -0
  65. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_schema-primary-keys.md +61 -0
  66. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_security-privileges.md +54 -0
  67. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_security-rls-basics.md +50 -0
  68. package/template/.claude/skills/supabase-postgres-best-practices/references/pgbp_security-rls-performance.md +57 -0
  69. package/template/.cursor/agents/business-analyst.md +197 -0
  70. package/template/.cursor/agents/technical-lead.md +3 -3
  71. package/template/.cursor/mcp.json +6 -2
  72. package/template/.cursor/skills/build-feature/SKILL.md +20 -21
  73. package/template/.cursor/skills/discover-feature/SKILL.md +118 -29
  74. package/template/.cursor/skills/supabase/SKILL.md +104 -0
  75. package/template/.cursor/skills/supabase/assets/feedback-issue-template.md +17 -0
  76. package/template/.cursor/skills/supabase/references/skill-feedback.md +17 -0
  77. package/template/.cursor/skills/supabase-postgres-best-practices/SKILL.md +64 -0
  78. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp__contributing.md +170 -0
  79. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp__sections.md +39 -0
  80. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp__template.md +34 -0
  81. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_advanced-full-text-search.md +55 -0
  82. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_advanced-jsonb-indexing.md +49 -0
  83. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_conn-idle-timeout.md +46 -0
  84. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_conn-limits.md +44 -0
  85. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_conn-pooling.md +41 -0
  86. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_conn-prepared-statements.md +46 -0
  87. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_data-batch-inserts.md +54 -0
  88. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_data-n-plus-one.md +53 -0
  89. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_data-pagination.md +50 -0
  90. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_data-upsert.md +50 -0
  91. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_lock-advisory.md +56 -0
  92. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_lock-deadlock-prevention.md +68 -0
  93. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_lock-short-transactions.md +50 -0
  94. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_lock-skip-locked.md +54 -0
  95. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_monitor-explain-analyze.md +45 -0
  96. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_monitor-pg-stat-statements.md +55 -0
  97. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_monitor-vacuum-analyze.md +55 -0
  98. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_query-composite-indexes.md +44 -0
  99. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_query-covering-indexes.md +40 -0
  100. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_query-index-types.md +48 -0
  101. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_query-missing-indexes.md +43 -0
  102. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_query-partial-indexes.md +45 -0
  103. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_schema-constraints.md +80 -0
  104. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_schema-data-types.md +46 -0
  105. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_schema-foreign-key-indexes.md +59 -0
  106. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_schema-lowercase-identifiers.md +55 -0
  107. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_schema-partitioning.md +55 -0
  108. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_schema-primary-keys.md +61 -0
  109. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_security-privileges.md +54 -0
  110. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_security-rls-basics.md +50 -0
  111. package/template/.cursor/skills/supabase-postgres-best-practices/references/pgbp_security-rls-performance.md +57 -0
  112. package/template/.mcp.json +16 -0
  113. package/template/.opencode/agents/backend.md +72 -0
  114. package/template/.opencode/agents/business-analyst.md +153 -0
  115. package/template/.opencode/agents/code-reviewer.md +80 -0
  116. package/template/.opencode/agents/frontend.md +84 -0
  117. package/template/.opencode/agents/security-researcher.md +58 -0
  118. package/template/.opencode/agents/technical-lead.md +131 -0
  119. package/template/.opencode/agents/test-qa.md +103 -0
  120. package/template/.opencode/memory/architecture-snapshot.md +127 -0
  121. package/template/.opencode/skills/build-feature/SKILL.md +208 -0
  122. package/template/.opencode/skills/create-api-route/SKILL.md +63 -0
  123. package/template/.opencode/skills/discover-feature/SKILL.md +194 -0
  124. package/template/.opencode/skills/memory/SKILL.md +199 -0
  125. package/template/.opencode/skills/review-branch/SKILL.md +43 -0
  126. package/template/.opencode/skills/security-audit/SKILL.md +40 -0
  127. package/template/.opencode/skills/supabase/SKILL.md +105 -0
  128. package/template/.opencode/skills/supabase/assets/feedback-issue-template.md +17 -0
  129. package/template/.opencode/skills/supabase/references/skill-feedback.md +17 -0
  130. package/template/.opencode/skills/supabase-postgres-best-practices/SKILL.md +65 -0
  131. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp__contributing.md +170 -0
  132. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp__sections.md +39 -0
  133. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp__template.md +34 -0
  134. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_advanced-full-text-search.md +55 -0
  135. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_advanced-jsonb-indexing.md +49 -0
  136. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_conn-idle-timeout.md +46 -0
  137. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_conn-limits.md +44 -0
  138. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_conn-pooling.md +41 -0
  139. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_conn-prepared-statements.md +46 -0
  140. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_data-batch-inserts.md +54 -0
  141. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_data-n-plus-one.md +53 -0
  142. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_data-pagination.md +50 -0
  143. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_data-upsert.md +50 -0
  144. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_lock-advisory.md +56 -0
  145. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_lock-deadlock-prevention.md +68 -0
  146. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_lock-short-transactions.md +50 -0
  147. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_lock-skip-locked.md +54 -0
  148. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_monitor-explain-analyze.md +45 -0
  149. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_monitor-pg-stat-statements.md +55 -0
  150. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_monitor-vacuum-analyze.md +55 -0
  151. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_query-composite-indexes.md +44 -0
  152. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_query-covering-indexes.md +40 -0
  153. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_query-index-types.md +48 -0
  154. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_query-missing-indexes.md +43 -0
  155. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_query-partial-indexes.md +45 -0
  156. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_schema-constraints.md +80 -0
  157. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_schema-data-types.md +46 -0
  158. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_schema-foreign-key-indexes.md +59 -0
  159. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_schema-lowercase-identifiers.md +55 -0
  160. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_schema-partitioning.md +55 -0
  161. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_schema-primary-keys.md +61 -0
  162. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_security-privileges.md +54 -0
  163. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_security-rls-basics.md +50 -0
  164. package/template/.opencode/skills/supabase-postgres-best-practices/references/pgbp_security-rls-performance.md +57 -0
  165. package/template/.requirements/README.md +1 -1
  166. package/template/AGENTS.md +1 -1
  167. package/template/CLAUDE.md +1 -1
  168. package/template/README.md +15 -2
  169. package/template/_gitignore +3 -0
  170. package/template/docker-compose.yml +26 -0
  171. package/template/ia-flow.md +341 -0
  172. package/template/opencode.json +23 -0
  173. package/template/.cursor/agents/business-intelligence.md +0 -83
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: test-qa
3
+ description: Testing specialist. Use when writing tests, enforcing TDD workflow, fixing coverage gaps, or debugging test failures. Always write tests BEFORE implementation. Triggers: writing tests, TDD workflow, coverage gaps, test failures, mock setup.
4
+ ---
5
+
6
+ # Test & QA Agent
7
+
8
+ ## First Step — Load Context via MCP Memory
9
+
10
+ 1. Read `package.json` to get the project name (`<project-name>`)
11
+ 2. Call `search_memory` with `tags: ["project:<project-name>", "domain:patterns"]` and `query: "test mock supabase"` — canonical test references and mock setup (`makeChain`, `makeSupabaseMock`)
12
+ 3. **Fallback**: if the memory service is unavailable or returns no results, read `.cursor/memory/architecture-snapshot.md` directly
13
+
14
+ Import `makeChain` and `makeSupabaseMock` from `@/shared/test-utils/supabase-mock` — never recreate the mock chain from scratch.
15
+
16
+ ## TDD Workflow
17
+
18
+ 1. **RED** — write failing test that describes the desired behavior
19
+ 2. **GREEN** — write minimum code to make test pass
20
+ 3. **REFACTOR** — clean up while keeping tests green
21
+ 4. **VERIFY** — run `pnpm test:coverage` and confirm 100%
22
+
23
+ ## Verification Gates (mandatory — show output, do not just claim)
24
+
25
+ Each phase requires pasting the actual terminal output before proceeding:
26
+
27
+ | Gate | Command | Expected output |
28
+ |------|---------|-----------------|
29
+ | After RED | `pnpm test:unit` | All new tests **FAIL** (red) |
30
+ | After GREEN | `pnpm test:unit` | All tests **PASS** (green) |
31
+ | After VERIFY | `pnpm test:coverage` | ≥95% statements/functions/lines, ≥90% branches |
32
+
33
+ **Never say "tests pass" or "tests fail" without showing the actual output.**
34
+ **Do NOT write any implementation code until the RED gate output confirms failures.**
35
+
36
+ ## Key Rules (auto-loaded by file context)
37
+ - Testing standards, AAA pattern, coverage: `testing.mdc`
38
+ - TDD iron rules: `coding-standards.mdc`
39
+
40
+ ## Coverage Requirement
41
+ ```
42
+ branches: 90%
43
+ functions: 95%
44
+ lines: 95%
45
+ statements: 95%
46
+ ```
47
+
48
+ Use `/* v8 ignore next */` for genuinely unreachable defensive branches only.
49
+
50
+ After every change:
51
+ 1. Run `pnpm test:coverage`
52
+ 2. If below thresholds, add missing tests
53
+ 3. Never mark work complete without meeting thresholds
54
+
55
+ ## Supabase Mock Pattern
56
+
57
+ Always use the shared helpers — never inline mock chain construction:
58
+
59
+ ```typescript
60
+ import { makeChain, makeSupabaseMock } from "@/shared/test-utils/supabase-mock";
61
+
62
+ // Unauthenticated
63
+ const { mockClient } = makeSupabaseMock({ user: null });
64
+
65
+ // Authenticated + DB success
66
+ const { mockClient, mockFrom } = makeSupabaseMock({ user: { id: "user-1" } });
67
+ mockFrom.mockReturnValue(makeChain({ data: [...], error: null }));
68
+
69
+ // DB error
70
+ mockFrom.mockReturnValue(makeChain({ error: { message: "db error" } }));
71
+ ```
72
+
73
+ ## Test Plan Compliance
74
+
75
+ When the Technical Lead provides a test plan, follow it:
76
+ - Use the specified test files, `describe` block names, and mock setup
77
+ - Flag missing edge cases to the TL **before** adding unplanned tests — do not expand scope unilaterally
78
+ - If the plan is ambiguous or incomplete, ask for clarification rather than guessing
79
+
80
+ For the full Server Action test template, see `build-feature` skill references (`references/server-action-test-template.md`).
81
+
82
+ ## Guardrails
83
+ - Never write implementation without a failing test first
84
+ - Never mock internal project code — only external deps
85
+ - Verify all edge cases: empty states, errors, loading states
@@ -0,0 +1,48 @@
1
+ ---
2
+ description: Feature-based architecture rules. Applies to all source files.
3
+ alwaysApply: false
4
+ globs: ["src/**"]
5
+ ---
6
+
7
+ # Architecture Rules
8
+
9
+ ## Feature-Based Structure
10
+ ```
11
+ features/
12
+ └── <feature-name>/
13
+ ├── components/ # React components
14
+ ├── actions/ # Server Actions (*.action.ts)
15
+ ├── queries/ # Read queries — *.queries.ts (repository layer)
16
+ ├── hooks/ # React hooks (use-*.ts)
17
+ ├── api/ # Route handlers (route.ts)
18
+ ├── lib/ # Feature-specific utilities, schemas, and types
19
+ └── __tests__/ # Colocated tests
20
+ ```
21
+
22
+ ## Dependency Direction
23
+ ```
24
+ features/* → shared/* ✅
25
+ shared/* → features/* ❌ (circular dependency)
26
+ features/a → features/b ❌ (cross-feature import)
27
+ ```
28
+
29
+ If two features share logic, move it to `shared/`.
30
+
31
+ ## Layer Rules
32
+ - `app/` — routing, layouts, RSC data fetching
33
+ - `features/` — feature business logic, UI, actions
34
+ - `shared/lib/` — infrastructure (supabase, ai, db)
35
+ - `shared/components/` — design system components
36
+
37
+ ## Error Boundaries
38
+ - Place at route level (`app/(protected)/layout.tsx`)
39
+ - Never let unhandled errors propagate to root
40
+
41
+ ## Server Actions
42
+ - File naming: `name.action.ts`
43
+ - Always `"use server"` at top of file
44
+ - Validate input with Zod before any business logic
45
+ - Return typed result objects, use `redirect()` for navigation
46
+ - Actions that mutate data must return `ActionResult` from `@/shared/lib/action-result` — never return `void`
47
+ - The calling component is responsible for showing `toast.success()` / `toast.error()` based on the result
48
+ - NEVER import or call client-only APIs inside server actions (`toast` from sonner, React hooks, `window`, `document`). Server actions run on the server where these APIs do not exist and will throw at runtime.
@@ -0,0 +1,120 @@
1
+ ---
2
+ description: Code quality standards. Applies to TypeScript/TSX source files.
3
+ alwaysApply: false
4
+ globs: ["src/**/*.ts", "src/**/*.tsx"]
5
+ ---
6
+
7
+ # Coding Standards
8
+
9
+ ## Absolute Rules
10
+ - **Zero `any`** — use `unknown` + type guards or proper generics. `@typescript-eslint/no-explicit-any: error`
11
+ - **Zero comments in production code** — code must be self-documenting through naming. Test AAA labels (`// Arrange`, `// Act`, `// Assert`) are required in tests.
12
+ - **Zero magic numbers/strings** — use typed constants
13
+ - **No `console.log`** in production code — `no-console: "error"`
14
+ - **No `!` non-null assertions** — use proper null checks
15
+ - **No `eslint-disable` inline comments** — fix the code instead. If a rule conflict is truly unavoidable (e.g. third-party API with no non-deprecated alternative), add a file-level override in `eslint.config.ts` with a `// TODO` comment explaining why.
16
+
17
+ ## AI Agent Lint Pre-Flight
18
+
19
+ Before writing any code, internalize these rules. The project runs `eslint --max-warnings 0` — any violation blocks commits. These are the patterns that most commonly trip AI code generation:
20
+
21
+ - **`no-console: "error"`** — never use `console.*` in production code. Use proper error handling (`throw`) or `ActionResult` error returns.
22
+ - **`strict-boolean-expressions`** — never write `if (value)` for non-boolean types. Use explicit checks:
23
+ - `string`: `if (str !== "")`
24
+ - `number`: `if (n !== 0)`
25
+ - `T | null | undefined`: `if (value !== null && value !== undefined)`
26
+ - `T[]`: `if (array.length > 0)`
27
+ - JSX: `{condition !== null && condition !== undefined && <Component />}`
28
+ - **`naming-convention`** — `camelCase` for variables/functions, `PascalCase` for types/interfaces/React components, `UPPER_CASE` allowed for constants. Never use `snake_case` except in `property` selectors (DB columns, JSON keys).
29
+ - **`no-floating-promises`** — always `await` or prefix with `void` for fire-and-forget.
30
+ - **`restrict-template-expressions`** — never interpolate non-string/number values directly: `` `${someObject}` `` → `` `${someObject.toString()}` ``.
31
+ - **`no-unnecessary-condition`** — never check conditions that the type system proves always truthy/falsy.
32
+ - **`no-unsafe-*`** — never pass `any`-typed values to typed parameters. Narrow with Zod or type guards first.
33
+
34
+ > **Rule of thumb**: If unsure whether a pattern is valid, read `eslint.config.ts` before writing.
35
+
36
+ ## TDD
37
+
38
+ Follow the RED → GREEN → REFACTOR cycle. See `testing.mdc` for the full rules and iron rules. Summary: never write implementation without a prior failing test.
39
+
40
+ ## SOLID Principles
41
+ - **S**ingle Responsibility: one reason to change per module
42
+ - **O**pen/Closed: extend behavior without modifying existing code
43
+ - **L**iskov Substitution: subtypes must be substitutable for base types
44
+ - **I**nterface Segregation: prefer small, focused interfaces
45
+ - **D**ependency Inversion: depend on abstractions, not concretions
46
+
47
+ ## KISS & DRY
48
+ - Simplest solution that works — no over-engineering
49
+ - Three similar lines is better than a premature abstraction
50
+ - Extract abstraction only when you have 3+ real use cases
51
+
52
+ ## Size Limits
53
+ - Functions: max 20 lines
54
+ - Files: max 200 lines
55
+ - If exceeded, split by responsibility
56
+
57
+ ## Error Handling
58
+ - Use `Result` types for expected failures
59
+ - Never swallow errors silently
60
+ - Always handle Promise rejections
61
+
62
+ ## Types
63
+ - Prefer `interface` for object shapes (enforced by ESLint `consistent-type-definitions`). Use `type` for unions, intersections, and utility types.
64
+ - Use `satisfies` for type-checked literals
65
+ - Use `as const` for immutable literals
66
+ - **Never use `as` type assertions for data from external sources** (DB, API, user input). Use Zod `.parse()` or `.safeParse()` to validate and type runtime data. `as const` is acceptable for literals.
67
+
68
+ ```typescript
69
+ // ✅
70
+ const schema = z.array(supportItemSchema);
71
+ const items = schema.parse(data);
72
+
73
+ // ❌
74
+ const items = data as SupportListItem[];
75
+ ```
76
+
77
+ ## Language Rules
78
+
79
+ - **Code-level text must be in English**: test `it()` descriptions, `describe()` block names, variable names, code comments, developer-facing `Error` constructor messages (never shown to users), `console` output
80
+ - **User-facing text stays in the target language**: UI labels, placeholders, toast messages, form validation messages shown on screen, `ActionResult` error/success strings that end up displayed in the UI
81
+
82
+ ```typescript
83
+ // ✅ Code-level: English
84
+ it("returns error when candidate is not found", async () => { ... });
85
+ throw new Error("Unexpected DB response shape"); // developer-facing, never shown in UI
86
+
87
+ // ✅ User-facing: target language (Spanish)
88
+ return { success: false, error: "Candidato no encontrado" }; // shown in toast
89
+ toast.error("No se pudo guardar el cambio");
90
+
91
+ // ❌ Wrong: code-level in wrong language
92
+ it("retorna error si el candidato no existe", async () => { ... });
93
+ ```
94
+
95
+ ## Coverage Exclusions (configure upfront, not reactively)
96
+
97
+ Before writing tests, add exclusions to `vitest.config.ts` for:
98
+ - Drizzle schema definition files (`src/shared/db/*.schema.ts`)
99
+ - Pure type files (files with only `type`/`interface` exports, no runtime logic)
100
+ - Third-party UI wrapper components that rely on portals or browser APIs not supported in jsdom (e.g., `sonner.tsx`, toast providers)
101
+
102
+ Configure these exclusions **before writing tests** to avoid reactive coverage fixes mid-implementation.
103
+
104
+ ```typescript
105
+ // vitest.config.ts
106
+ coverage: {
107
+ exclude: [
108
+ "src/shared/db/*.schema.ts",
109
+ "src/shared/components/ui/sonner.tsx",
110
+ // add other portal/type-only files here
111
+ ],
112
+ }
113
+ ```
114
+
115
+ ## Pre-commit Quality Gates
116
+ Every commit must pass two sequential gates:
117
+ 1. **lint-staged** — runs `eslint --max-warnings 0` on staged `.ts/.tsx` files. Any lint warning or error blocks the commit immediately (before the slower test suite runs).
118
+ 2. **Full test suite** — runs `vitest run --coverage` with 95% statement/function/line and 90% branch coverage required.
119
+
120
+ Code that fails either gate cannot be committed.
@@ -0,0 +1,49 @@
1
+ ---
2
+ description: shadcn/ui and Tailwind v4 component standards.
3
+ globs: ["src/**/components/**"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Component Standards
8
+
9
+ ## shadcn/ui
10
+ - Use shadcn/ui components from `@/shared/components/ui/`
11
+ - Never build custom UI primitives when shadcn has one
12
+ - Extend with `className` prop via `cn()` utility
13
+ - New York style, CSS variables for theming
14
+
15
+ ## shadcn/ui (MCP + CLI)
16
+ - **MCP tools** (preferred): `shadcn_search`, `shadcn_docs`, `shadcn_install`, `shadcn_diff`
17
+ - Before writing component code, use `shadcn_docs <component>` to get up-to-date API and usage patterns
18
+ - Use `shadcn_search <query>` to discover available components
19
+ - Install components with `shadcn_install` or `shadcn add <component>` — never copy-paste component source manually
20
+ - Use `shadcn_diff <component>` to check for upstream changes to already-installed components
21
+ - The shadcn skill (`pnpm dlx skills add shadcn/ui`) is installed during scaffolding — provides project context automatically
22
+
23
+ ## Tailwind v4
24
+ - CSS-native config via `@theme {}` in CSS
25
+ - No `tailwind.config.js` — all config in `tailwind.css`
26
+ - No inline styles, no CSS modules
27
+ - Use Tailwind utility classes only
28
+
29
+ ## Design Tokens (Required)
30
+ - Always use semantic token classes (`bg-primary`, `text-destructive`, `text-muted-foreground`, `border-border`, etc.)
31
+ - Never use raw Tailwind palette colors (`bg-blue-500`, `text-gray-700`, `text-red-500`, etc.)
32
+ - All colors must reference CSS variables defined in `@theme {}` in `tailwind.css`
33
+ - Available semantic colors: primary, secondary, accent, destructive, success, warning, info, muted, background, foreground, border, input, ring
34
+ - If a needed color does not exist as a token, add it to `@theme {}` in `tailwind.css` first
35
+
36
+ ## Accessibility (Required)
37
+ - Semantic HTML elements (`<button>`, `<nav>`, `<main>`, etc.)
38
+ - ARIA labels for interactive elements without visible text
39
+ - Keyboard navigation support
40
+ - Color contrast ratios (WCAG AA minimum)
41
+ - `role="alert"` for error messages
42
+
43
+ ## Server vs Client Components
44
+ - Default to Server Components (no `"use client"`)
45
+ - Add `"use client"` only when you need:
46
+ - Event handlers (`onClick`, `onChange`, etc.)
47
+ - Hooks (`useState`, `useEffect`, etc.)
48
+ - Browser APIs
49
+ - Keep Client Components small — push them to leaf nodes
@@ -0,0 +1,115 @@
1
+ ---
2
+ description: TanStack Query vs RSC data fetching boundaries. Applied when working on components, pages, queries, hooks, or actions.
3
+ globs: ["src/**/components/**", "src/**/queries/**", "src/**/hooks/**", "src/**/actions/**", "src/app/**"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Data Fetching Rules (Risk 1: TanStack Query + RSC Boundary)
8
+
9
+ ## Hard Boundary
10
+
11
+ | Use Case | Where |
12
+ |---|---|
13
+ | Initial page data | RSC `async` Server Component |
14
+ | Background refresh / polling | TanStack Query |
15
+ | User-triggered client reads | TanStack Query |
16
+ | All mutations | Server Actions ONLY |
17
+
18
+ **Never use TanStack Query mutations. Never use `useMutation`.**
19
+
20
+ ## WRONG ❌
21
+ ```typescript
22
+ // ❌ Fetching initial data in a Client Component with TanStack Query
23
+ "use client";
24
+ export function UserProfile({ userId }: { userId: string }) {
25
+ const { data } = useQuery({
26
+ queryKey: ["user", userId],
27
+ queryFn: () => fetchUser(userId), // Initial data should come from RSC
28
+ });
29
+ return <div>{data?.name}</div>;
30
+ }
31
+
32
+ // ❌ Mutation with TanStack Query
33
+ const mutation = useMutation({
34
+ mutationFn: (data) => updateUser(data), // Use Server Action instead
35
+ });
36
+ ```
37
+
38
+ ## CORRECT ✅
39
+ ```typescript
40
+ // ✅ Initial data from RSC via feature's queries/ module
41
+ import { getUserById } from "@/features/users/queries/users.queries";
42
+
43
+ export default async function UserPage({ params }: { params: { id: string } }) {
44
+ const supabase = await createClient();
45
+ const { data: user } = await getUserById(supabase, params.id); // via repository
46
+ return <UserProfile initialUser={user} />;
47
+ }
48
+
49
+ // ✅ TanStack Query for background refresh only
50
+ // queryFn must call a function from the feature's queries/ module — never inline supabase.from() here
51
+ "use client";
52
+ export function UserProfile({ initialUser }: { initialUser: User }) {
53
+ const { data: user } = useQuery({
54
+ queryKey: ["user", initialUser.id],
55
+ queryFn: () => fetchUser(initialUser.id), // fetchUser lives in features/users/queries/
56
+ initialData: initialUser, // Seeded from RSC
57
+ staleTime: 5 * 60 * 1000,
58
+ });
59
+ return <div>{user.name}</div>;
60
+ }
61
+
62
+ // ✅ Mutation via Server Action
63
+ async function updateUserAction(formData: FormData) {
64
+ "use server";
65
+ await db.update(users).set({ name: formData.get("name") });
66
+ revalidatePath("/profile");
67
+ }
68
+ ```
69
+
70
+ ## Error Handling
71
+
72
+ TanStack Query errors must be handled via the `error` property — never swallow them silently.
73
+
74
+ - **Data queries** (background reads): show an inline error state in the component
75
+ - **User-triggered actions**: show a toast via `sonner` (see `forms.mdc` Pattern A)
76
+
77
+ ```typescript
78
+ "use client";
79
+ export function UserProfile({ initialUser }: { initialUser: User }) {
80
+ const { data: user, error } = useQuery({
81
+ queryKey: ["user", initialUser.id],
82
+ queryFn: () => fetchUser(initialUser.id),
83
+ initialData: initialUser,
84
+ });
85
+
86
+ if (error) return <p role="alert">Failed to load user data.</p>;
87
+ return <div>{user.name}</div>;
88
+ }
89
+ ```
90
+
91
+ ## Cache Invalidation After Server Actions
92
+
93
+ After a Server Action mutates data, invalidate the relevant TanStack Query cache so the UI reflects the new state.
94
+
95
+ ```typescript
96
+ // In the calling component (Client Component)
97
+ import { useQueryClient } from "@tanstack/react-query";
98
+ import { toast } from "sonner";
99
+
100
+ const queryClient = useQueryClient();
101
+
102
+ startTransition(async () => {
103
+ const result = await updateUserAction(formData);
104
+ if (result.status === "success") {
105
+ // Invalidate cache so background queries re-fetch with fresh data
106
+ await queryClient.invalidateQueries({ queryKey: ["user", userId] });
107
+ toast.success(result.message);
108
+ } else {
109
+ toast.error(result.message);
110
+ }
111
+ });
112
+ ```
113
+
114
+ > **Note on optimistic updates**: Full optimistic updates use `onMutate` + rollback on failure (`onError`). Do not implement this pattern until you have a concrete use case — `invalidateQueries` is simpler and sufficient for most scenarios.
115
+
@@ -0,0 +1,100 @@
1
+ ---
2
+ description: React Hook Form + Server Actions pattern. Client-side validation via zodResolver + server-side revalidation in the action.
3
+ globs: ["src/**/*form*", "src/**/*.action.ts"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Forms Pattern (Risk 4: RHF + Server Actions)
8
+
9
+ ## The One Pattern
10
+
11
+ ```
12
+ Client: RHF + zodResolver → client validation (UX)
13
+ ↓ valid
14
+ Server Action → zod validate again (security) → business logic
15
+ ```
16
+
17
+ Zod validates TWICE:
18
+ 1. Client-side: immediate UX feedback via RHF
19
+ 2. Server-side: never trust the client
20
+
21
+ ## Template
22
+ ```typescript
23
+ // form.tsx (client)
24
+ "use client";
25
+ const schema = z.object({ email: z.string().email() });
26
+ type FormValues = z.infer<typeof schema>;
27
+
28
+ export function MyForm() {
29
+ const [state, formAction, isPending] = useActionState(myAction, { status: "idle" });
30
+ const { register, handleSubmit, formState: { errors } } = useForm<FormValues>({
31
+ resolver: zodResolver(schema),
32
+ });
33
+
34
+ const onSubmit = handleSubmit((data) => {
35
+ const fd = new FormData();
36
+ Object.entries(data).forEach(([k, v]) => fd.set(k, String(v)));
37
+ formAction(fd);
38
+ });
39
+
40
+ return (
41
+ <form onSubmit={onSubmit}>
42
+ {state.status === "error" && <p role="alert">{state.message}</p>}
43
+ <input {...register("email")} />
44
+ {errors.email && <p>{errors.email.message}</p>}
45
+ <button disabled={isPending}>Submit</button>
46
+ </form>
47
+ );
48
+ }
49
+
50
+ // action.ts (server)
51
+ "use server";
52
+ const schema = z.object({ email: z.string().email() });
53
+
54
+ export async function myAction(_prev: State, formData: FormData): Promise<State> {
55
+ const parsed = schema.safeParse({ email: formData.get("email") });
56
+ if (!parsed.success) return { status: "error", message: parsed.error.issues[0]?.message ?? "Invalid" };
57
+ // business logic...
58
+ redirect("/success");
59
+ }
60
+ ```
61
+
62
+ ## Shared Schema
63
+
64
+ Share the Zod schema between client and server from a single source (e.g., `lib/schemas.ts` or the Drizzle-generated schema via `drizzle-zod`) to avoid drift. The template above defines `schema` twice as an illustration — in production, import it from a shared module.
65
+
66
+ ## Toast Feedback
67
+
68
+ > **⚠️ Toast calls belong in client components ONLY.** Never import `sonner` or call `toast()` inside a `"use server"` file. The server action returns `ActionResult`; the component reads the result and shows the toast.
69
+
70
+ Every action that affects the database MUST show a toast to the user. No mutation should complete silently.
71
+
72
+ - Use `toast.success(message)` for successful operations
73
+ - Use `toast.error(message)` for failed operations
74
+ - Import `toast` from `sonner`
75
+ - Server actions that mutate data must return `ActionResult` from `@/shared/lib/action-result` (not `void`)
76
+ - Exception: if the action redirects to another page on success, no success toast is needed (the user sees the new page)
77
+
78
+ ### Pattern A — Direct action call (button onClick, non-`useActionState` forms)
79
+ ```typescript
80
+ import { toast } from "sonner";
81
+ import type { ActionResult } from "@/shared/lib/action-result";
82
+
83
+ startTransition(async () => {
84
+ const result = await myAction(id);
85
+ if (result.status === "success") toast.success(result.message);
86
+ else toast.error(result.message);
87
+ });
88
+ ```
89
+
90
+ ### Pattern B — `useActionState` forms
91
+ ```typescript
92
+ import { useEffect } from "react";
93
+ import { toast } from "sonner";
94
+
95
+ const [state, formAction] = useActionState(myAction, { status: "idle" });
96
+
97
+ useEffect(() => {
98
+ if (state.status === "error") toast.error(state.message);
99
+ }, [state]);
100
+ ```
@@ -0,0 +1,54 @@
1
+ ---
2
+ description: Stack overview and project conventions. Always loaded — defines the technology stack, project structure, and naming conventions for this project.
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # Stack Overview
7
+
8
+ ## Technology Stack
9
+ - **Framework**: Next.js 16.2 (App Router)
10
+ - **Database**: Supabase (PostgreSQL) with Drizzle ORM for schema/migrations
11
+ - **Auth**: Supabase Auth via `@supabase/ssr`
12
+ - **ORM**: Drizzle + `drizzle-zod` (schema + migrations ONLY — no runtime queries)
13
+ - **DB Runtime Queries**: `supabase-js` client (RLS active)
14
+ - **Client State**: TanStack Query v5
15
+ - **Validation**: Zod (auto-generated via `drizzle-zod`)
16
+ - **Forms**: React Hook Form + Zod resolver
17
+ - **UI**: shadcn/ui + Tailwind CSS v4 (shadcn skill installed for AI context)
18
+ - **AI**: Vercel AI SDK + Google Gemini 2.0 Flash via AI Gateway
19
+ - **Testing**: Vitest + React Testing Library + Playwright
20
+
21
+ ## Project Structure
22
+ ```
23
+ src/
24
+ ├── app/ # Next.js App Router pages
25
+ ├── features/ # Feature modules (auth, chat)
26
+ │ └── <feature>/
27
+ │ ├── components/
28
+ │ ├── actions/
29
+ │ ├── queries/
30
+ │ ├── hooks/
31
+ │ ├── api/
32
+ │ ├── lib/
33
+ │ └── __tests__/
34
+ ├── shared/ # Shared across features
35
+ │ ├── components/ui/ # shadcn/ui components
36
+ │ ├── lib/ # supabase, ai, utilities
37
+ │ └── db/ # Drizzle schema + migrations
38
+ └── e2e/ # Playwright tests
39
+ ```
40
+
41
+ ## Naming Conventions
42
+ - Files: `kebab-case.ts`
43
+ - Components: `PascalCase`
44
+ - Hooks: `useCamelCase`
45
+ - Server Actions: `kebab-case.action.ts`
46
+ - API Routes: `route.ts` (in feature `api/` folder)
47
+ - Tests: `*.test.ts` or `*.test.tsx`
48
+ - E2e: `*.spec.ts`
49
+
50
+ ## Import Ordering
51
+ 1. Node built-ins
52
+ 2. External packages
53
+ 3. Internal (`@/`)
54
+ 4. Relative (`./`, `../`)
@@ -0,0 +1,11 @@
1
+ ---
2
+ description: Migration files are auto-generated by Drizzle CLI. NEVER create, edit, or delete them directly.
3
+ globs: ["src/shared/db/migrations/**"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Migration Files — Generated Artifacts
8
+
9
+ Files in `src/shared/db/migrations/` are **auto-generated**. See `supabase.mdc` for the full migration workflow and CLI commands.
10
+
11
+ **Never create, edit, or delete migration files by hand.**
@@ -0,0 +1,71 @@
1
+ ---
2
+ description: Next.js 16.2 App Router patterns.
3
+ globs: ["src/app/**"]
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Next.js 16.2 Rules
8
+
9
+ ## App Router Conventions
10
+ - `page.tsx` — public route page component
11
+ - `layout.tsx` — shared layout (wraps child pages)
12
+ - `loading.tsx` — Suspense boundary UI
13
+ - `error.tsx` — Error boundary UI
14
+ - `route.ts` — API route handler
15
+ - `proxy.ts` — Request proxy (project root, Node.js runtime). Intercepts and rewrites requests before they reach route handlers (e.g., session validation, redirects).
16
+
17
+ ## Route Groups
18
+ - `(auth)` — unauthenticated routes
19
+ - `(protected)` — authenticated routes with RSC auth check
20
+
21
+ ## Data Fetching in RSC
22
+ ```typescript
23
+ // ✅ Async Server Component — fetch directly
24
+ export default async function Page() {
25
+ const data = await fetchData(); // No useState, no useEffect
26
+ return <ClientComponent initialData={data} />;
27
+ }
28
+ ```
29
+
30
+ ## Route Handler Patterns
31
+ ```typescript
32
+ // app/api/*/route.ts
33
+ export async function POST(request: Request) {
34
+ const body = await request.json() as unknown;
35
+ const parsed = schema.safeParse(body);
36
+ if (!parsed.success) return Response.json({ error: "Invalid input" }, { status: 400 });
37
+ // ...
38
+ }
39
+ ```
40
+
41
+ ## Metadata
42
+ ```typescript
43
+ export const metadata: Metadata = {
44
+ title: "Page Title",
45
+ description: "Page description",
46
+ };
47
+ ```
48
+
49
+ ## Browser Log Forwarding
50
+
51
+ Next.js 16.2 can forward browser logs to the terminal. Configure in `next.config.ts`:
52
+
53
+ ```typescript
54
+ const nextConfig: NextConfig = {
55
+ logging: {
56
+ browserToTerminal: 'error', // 'error' (default) | 'warn' | true (all) | false (disabled)
57
+ },
58
+ };
59
+ ```
60
+
61
+ - `'error'` — forwards browser errors only (default)
62
+ - `'warn'` — forwards errors and warnings
63
+ - `true` — forwards all console output
64
+ - `false` — disabled
65
+
66
+ ## Dev Server Lock File
67
+
68
+ Next.js 16.2 writes `.next/dev/lock` when `next dev` starts. The file contains the PID, port, and URL of the running dev server.
69
+
70
+ - Agents and scripts must check `.next/dev/lock` before starting `next dev` or `next build` to avoid duplicate processes.
71
+ - If the lock file exists and the PID is still alive, attach to the existing server instead of starting a new one.