@nextsparkjs/ai-workflow 0.1.0-beta.100

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 (272) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -0
  3. package/claude/_docs/workflows-optimizations.md +359 -0
  4. package/claude/agents/api-tester.md +634 -0
  5. package/claude/agents/architecture-supervisor.md +1351 -0
  6. package/claude/agents/backend-developer.md +997 -0
  7. package/claude/agents/backend-validator.md +417 -0
  8. package/claude/agents/bdd-docs-writer.md +737 -0
  9. package/claude/agents/block-developer.md +677 -0
  10. package/claude/agents/code-reviewer.md +1432 -0
  11. package/claude/agents/db-developer.md +721 -0
  12. package/claude/agents/db-validator.md +407 -0
  13. package/claude/agents/demo-video-generator.md +493 -0
  14. package/claude/agents/documentation-writer.md +1268 -0
  15. package/claude/agents/frontend-developer.md +1234 -0
  16. package/claude/agents/frontend-validator.md +777 -0
  17. package/claude/agents/functional-validator.md +630 -0
  18. package/claude/agents/mock-analyst.md +387 -0
  19. package/claude/agents/product-manager.md +963 -0
  20. package/claude/agents/qa-automation.md +1762 -0
  21. package/claude/agents/release-manager.md +634 -0
  22. package/claude/agents/selectors-translator.md +262 -0
  23. package/claude/agents/unit-test-writer.md +785 -0
  24. package/claude/agents/visual-comparator.md +329 -0
  25. package/claude/agents/workflow-maintainer.md +352 -0
  26. package/claude/commands/do/README.md +88 -0
  27. package/claude/commands/do/create-api.md +64 -0
  28. package/claude/commands/do/create-entity.md +66 -0
  29. package/claude/commands/do/create-migration.md +64 -0
  30. package/claude/commands/do/create-plugin.md +56 -0
  31. package/claude/commands/do/create-theme.md +70 -0
  32. package/claude/commands/do/mock-data.md +67 -0
  33. package/claude/commands/do/reset-db.md +71 -0
  34. package/claude/commands/do/setup-scheduled-action.md +75 -0
  35. package/claude/commands/do/sync-code-review.md +117 -0
  36. package/claude/commands/do/update-selectors.md +112 -0
  37. package/claude/commands/do/use-skills.md +90 -0
  38. package/claude/commands/do/validate-blocks.md +69 -0
  39. package/claude/commands/how-to/README.md +261 -0
  40. package/claude/commands/how-to/add-metadata.md +692 -0
  41. package/claude/commands/how-to/add-taxonomies.md +806 -0
  42. package/claude/commands/how-to/add-translations.md +571 -0
  43. package/claude/commands/how-to/create-api.md +577 -0
  44. package/claude/commands/how-to/create-block.md +575 -0
  45. package/claude/commands/how-to/create-child-entities.md +771 -0
  46. package/claude/commands/how-to/create-entity.md +597 -0
  47. package/claude/commands/how-to/create-migrations.md +605 -0
  48. package/claude/commands/how-to/create-plugin.md +654 -0
  49. package/claude/commands/how-to/customize-app.md +481 -0
  50. package/claude/commands/how-to/customize-dashboard.md +553 -0
  51. package/claude/commands/how-to/customize-theme.md +438 -0
  52. package/claude/commands/how-to/define-features-flows.md +632 -0
  53. package/claude/commands/how-to/deploy.md +507 -0
  54. package/claude/commands/how-to/handle-file-uploads.md +746 -0
  55. package/claude/commands/how-to/implement-search.md +1001 -0
  56. package/claude/commands/how-to/install-plugins.md +352 -0
  57. package/claude/commands/how-to/manage-test-coverage.md +984 -0
  58. package/claude/commands/how-to/run-tests.md +400 -0
  59. package/claude/commands/how-to/set-app-languages.md +601 -0
  60. package/claude/commands/how-to/set-plans-and-permissions.md +575 -0
  61. package/claude/commands/how-to/set-scheduled-actions.md +527 -0
  62. package/claude/commands/how-to/set-user-roles-and-permissions.md +550 -0
  63. package/claude/commands/how-to/setup-authentication.md +388 -0
  64. package/claude/commands/how-to/setup-claude-code.md +440 -0
  65. package/claude/commands/how-to/setup-database.md +274 -0
  66. package/claude/commands/how-to/setup-email-providers.md +598 -0
  67. package/claude/commands/how-to/setup-mobile-dev.md +627 -0
  68. package/claude/commands/how-to/start.md +500 -0
  69. package/claude/commands/how-to/use-devtools.md +639 -0
  70. package/claude/commands/how-to/use-superadmin.md +622 -0
  71. package/claude/commands/session/README.md +193 -0
  72. package/claude/commands/session/block-create.md +190 -0
  73. package/claude/commands/session/block-list.md +203 -0
  74. package/claude/commands/session/block-update.md +192 -0
  75. package/claude/commands/session/block-validate.md +218 -0
  76. package/claude/commands/session/changelog.md +115 -0
  77. package/claude/commands/session/close.md +225 -0
  78. package/claude/commands/session/commit.md +174 -0
  79. package/claude/commands/session/db-entity.md +206 -0
  80. package/claude/commands/session/db-fix.md +212 -0
  81. package/claude/commands/session/db-sample.md +206 -0
  82. package/claude/commands/session/demo.md +178 -0
  83. package/claude/commands/session/doc-bdd.md +207 -0
  84. package/claude/commands/session/doc-feature.md +218 -0
  85. package/claude/commands/session/doc-read.md +225 -0
  86. package/claude/commands/session/execute.md +204 -0
  87. package/claude/commands/session/explain.md +202 -0
  88. package/claude/commands/session/fix-bug.md +210 -0
  89. package/claude/commands/session/fix-build.md +182 -0
  90. package/claude/commands/session/fix-test.md +189 -0
  91. package/claude/commands/session/pending.md +232 -0
  92. package/claude/commands/session/refine.md +188 -0
  93. package/claude/commands/session/resume.md +192 -0
  94. package/claude/commands/session/review.md +192 -0
  95. package/claude/commands/session/scope-change.md +181 -0
  96. package/claude/commands/session/start-blocks.md +347 -0
  97. package/claude/commands/session/start.md +604 -0
  98. package/claude/commands/session/status.md +169 -0
  99. package/claude/commands/session/test-fix.md +221 -0
  100. package/claude/commands/session/test-run.md +203 -0
  101. package/claude/commands/session/test-write.md +242 -0
  102. package/claude/commands/session/validate.md +162 -0
  103. package/claude/config/context.json +40 -0
  104. package/claude/config/github.json +69 -0
  105. package/claude/config/github.schema.json +106 -0
  106. package/claude/config/team.json +46 -0
  107. package/claude/config/team.schema.json +106 -0
  108. package/claude/config/workspace.json +43 -0
  109. package/claude/config/workspace.schema.json +75 -0
  110. package/claude/skills/README.md +228 -0
  111. package/claude/skills/accessibility/SKILL.md +573 -0
  112. package/claude/skills/api-bypass-layers/SKILL.md +550 -0
  113. package/claude/skills/asana-integration/SKILL.md +499 -0
  114. package/claude/skills/better-auth/SKILL.md +666 -0
  115. package/claude/skills/billing-subscriptions/SKILL.md +660 -0
  116. package/claude/skills/block-decision-matrix/SKILL.md +359 -0
  117. package/claude/skills/clickup-integration/SKILL.md +434 -0
  118. package/claude/skills/core-theme-responsibilities/SKILL.md +485 -0
  119. package/claude/skills/create-plugin/SKILL.md +425 -0
  120. package/claude/skills/create-theme/SKILL.md +331 -0
  121. package/claude/skills/cypress-api/SKILL.md +511 -0
  122. package/claude/skills/cypress-api/scripts/generate-api-controller.py +329 -0
  123. package/claude/skills/cypress-api/scripts/generate-api-test.py +930 -0
  124. package/claude/skills/cypress-e2e/SKILL.md +526 -0
  125. package/claude/skills/cypress-e2e/scripts/extract-selectors.py +383 -0
  126. package/claude/skills/cypress-e2e/scripts/generate-uat-test.py +788 -0
  127. package/claude/skills/cypress-selectors/SKILL.md +309 -0
  128. package/claude/skills/cypress-selectors/scripts/extract-missing.py +243 -0
  129. package/claude/skills/cypress-selectors/scripts/generate-block-selectors.py +283 -0
  130. package/claude/skills/cypress-selectors/scripts/validate-selectors.py +145 -0
  131. package/claude/skills/database-migrations/SKILL.md +335 -0
  132. package/claude/skills/database-migrations/scripts/generate-sample-data.py +284 -0
  133. package/claude/skills/database-migrations/scripts/validate-migration.py +323 -0
  134. package/claude/skills/design-system/SKILL.md +682 -0
  135. package/claude/skills/documentation/SKILL.md +540 -0
  136. package/claude/skills/entity-api/SKILL.md +482 -0
  137. package/claude/skills/entity-system/SKILL.md +635 -0
  138. package/claude/skills/entity-system/scripts/generate-child-migration.py +298 -0
  139. package/claude/skills/entity-system/scripts/generate-metas-migration.py +233 -0
  140. package/claude/skills/entity-system/scripts/generate-migration.py +382 -0
  141. package/claude/skills/entity-system/scripts/generate-sample-data.py +418 -0
  142. package/claude/skills/entity-system/scripts/scaffold-entity.py +661 -0
  143. package/claude/skills/github/SKILL.md +467 -0
  144. package/claude/skills/i18n-nextintl/SKILL.md +302 -0
  145. package/claude/skills/i18n-nextintl/scripts/add-translation.py +243 -0
  146. package/claude/skills/i18n-nextintl/scripts/extract-hardcoded.py +246 -0
  147. package/claude/skills/i18n-nextintl/scripts/validate-translations.py +260 -0
  148. package/claude/skills/impact-analysis/SKILL.md +203 -0
  149. package/claude/skills/jest-unit/SKILL.md +306 -0
  150. package/claude/skills/jest-unit/references/component-testing.md +371 -0
  151. package/claude/skills/jest-unit/references/mocking-patterns.md +380 -0
  152. package/claude/skills/jest-unit/references/service-hook-testing.md +454 -0
  153. package/claude/skills/jira-integration/SKILL.md +539 -0
  154. package/claude/skills/media-library/SKILL.md +743 -0
  155. package/claude/skills/mock-analysis/SKILL.md +276 -0
  156. package/claude/skills/monorepo-architecture/SKILL.md +162 -0
  157. package/claude/skills/nextjs-api-development/SKILL.md +364 -0
  158. package/claude/skills/nextjs-api-development/scripts/generate-crud-tests.py +456 -0
  159. package/claude/skills/nextjs-api-development/scripts/scaffold-endpoint.py +481 -0
  160. package/claude/skills/nextjs-api-development/scripts/validate-api.py +283 -0
  161. package/claude/skills/notion-integration/SKILL.md +641 -0
  162. package/claude/skills/npm-development-workflow/SKILL.md +480 -0
  163. package/claude/skills/page-builder-blocks/SKILL.md +530 -0
  164. package/claude/skills/page-builder-blocks/scripts/scaffold-block.py +444 -0
  165. package/claude/skills/permissions-system/SKILL.md +619 -0
  166. package/claude/skills/plugins/SKILL.md +340 -0
  167. package/claude/skills/plugins/references/plugin-templates.md +414 -0
  168. package/claude/skills/plugins/references/plugin-testing.md +353 -0
  169. package/claude/skills/plugins/references/plugin-types.md +198 -0
  170. package/claude/skills/plugins/scripts/scaffold-plugin.py +443 -0
  171. package/claude/skills/pom-patterns/SKILL.md +452 -0
  172. package/claude/skills/pom-patterns/scripts/generate-pom.py +392 -0
  173. package/claude/skills/rate-limiting/SKILL.md +342 -0
  174. package/claude/skills/react-best-practices/AGENTS.md +2410 -0
  175. package/claude/skills/react-best-practices/README.md +123 -0
  176. package/claude/skills/react-best-practices/SKILL.md +125 -0
  177. package/claude/skills/react-best-practices/metadata.json +15 -0
  178. package/claude/skills/react-best-practices/rules/_sections.md +46 -0
  179. package/claude/skills/react-best-practices/rules/_template.md +28 -0
  180. package/claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  181. package/claude/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
  182. package/claude/skills/react-best-practices/rules/async-api-routes.md +38 -0
  183. package/claude/skills/react-best-practices/rules/async-defer-await.md +80 -0
  184. package/claude/skills/react-best-practices/rules/async-dependencies.md +36 -0
  185. package/claude/skills/react-best-practices/rules/async-parallel.md +28 -0
  186. package/claude/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  187. package/claude/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
  188. package/claude/skills/react-best-practices/rules/bundle-conditional.md +31 -0
  189. package/claude/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
  190. package/claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  191. package/claude/skills/react-best-practices/rules/bundle-preload.md +50 -0
  192. package/claude/skills/react-best-practices/rules/client-event-listeners.md +74 -0
  193. package/claude/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
  194. package/claude/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
  195. package/claude/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
  196. package/claude/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
  197. package/claude/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
  198. package/claude/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
  199. package/claude/skills/react-best-practices/rules/js-cache-storage.md +70 -0
  200. package/claude/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
  201. package/claude/skills/react-best-practices/rules/js-early-exit.md +50 -0
  202. package/claude/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
  203. package/claude/skills/react-best-practices/rules/js-index-maps.md +37 -0
  204. package/claude/skills/react-best-practices/rules/js-length-check-first.md +49 -0
  205. package/claude/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
  206. package/claude/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
  207. package/claude/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  208. package/claude/skills/react-best-practices/rules/rendering-activity.md +26 -0
  209. package/claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  210. package/claude/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
  211. package/claude/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
  212. package/claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  213. package/claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  214. package/claude/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
  215. package/claude/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
  216. package/claude/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
  217. package/claude/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
  218. package/claude/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
  219. package/claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  220. package/claude/skills/react-best-practices/rules/rerender-memo.md +44 -0
  221. package/claude/skills/react-best-practices/rules/rerender-transitions.md +40 -0
  222. package/claude/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
  223. package/claude/skills/react-best-practices/rules/server-cache-lru.md +41 -0
  224. package/claude/skills/react-best-practices/rules/server-cache-react.md +76 -0
  225. package/claude/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
  226. package/claude/skills/react-best-practices/rules/server-serialization.md +38 -0
  227. package/claude/skills/react-patterns/SKILL.md +688 -0
  228. package/claude/skills/registry-system/SKILL.md +331 -0
  229. package/claude/skills/scheduled-actions/SKILL.md +671 -0
  230. package/claude/skills/scope-enforcement/SKILL.md +542 -0
  231. package/claude/skills/scope-enforcement/scripts/validate-scope.py +357 -0
  232. package/claude/skills/server-actions/SKILL.md +493 -0
  233. package/claude/skills/service-layer/SKILL.md +587 -0
  234. package/claude/skills/session-management/SKILL.md +266 -0
  235. package/claude/skills/session-management/scripts/create-session.py +166 -0
  236. package/claude/skills/session-management/scripts/iteration-close.sh +105 -0
  237. package/claude/skills/session-management/scripts/iteration-init.sh +180 -0
  238. package/claude/skills/session-management/scripts/session-archive.sh +87 -0
  239. package/claude/skills/session-management/scripts/session-close.sh +133 -0
  240. package/claude/skills/session-management/scripts/session-init.sh +225 -0
  241. package/claude/skills/session-management/scripts/session-list.sh +163 -0
  242. package/claude/skills/session-management/scripts/split-plan.sh +116 -0
  243. package/claude/skills/shadcn-components/SKILL.md +586 -0
  244. package/claude/skills/shadcn-theming/SKILL.md +446 -0
  245. package/claude/skills/suspense-loading/SKILL.md +280 -0
  246. package/claude/skills/tailwind-theming/SKILL.md +507 -0
  247. package/claude/skills/tanstack-query/SKILL.md +608 -0
  248. package/claude/skills/test-coverage/SKILL.md +239 -0
  249. package/claude/skills/web-design-guidelines/SKILL.md +39 -0
  250. package/claude/skills/zod-validation/SKILL.md +537 -0
  251. package/claude/templates/blocks/progress.md +86 -0
  252. package/claude/templates/iteration/changes.md +61 -0
  253. package/claude/templates/iteration/progress.md +55 -0
  254. package/claude/templates/log.md +31 -0
  255. package/claude/templates/story/context.md +77 -0
  256. package/claude/templates/story/pendings.md +37 -0
  257. package/claude/templates/story/plan.md +299 -0
  258. package/claude/templates/story/requirements.md +109 -0
  259. package/claude/templates/story/scope.json +10 -0
  260. package/claude/templates/story/tests.md +91 -0
  261. package/claude/templates/task/progress.md +58 -0
  262. package/claude/templates/task/requirements.md +54 -0
  263. package/claude/workflows/README.md +154 -0
  264. package/claude/workflows/blocks.md +614 -0
  265. package/claude/workflows/story.md +1207 -0
  266. package/claude/workflows/task.md +927 -0
  267. package/claude/workflows/tweak.md +527 -0
  268. package/cursor/.gitkeep +0 -0
  269. package/package.json +35 -0
  270. package/scripts/postinstall.mjs +198 -0
  271. package/scripts/setup.mjs +282 -0
  272. package/scripts/sync.mjs +209 -0
@@ -0,0 +1,666 @@
1
+ ---
2
+ name: better-auth
3
+ description: |
4
+ Authentication patterns with Better Auth for this Next.js application.
5
+ Covers session authentication, API key authentication, dual auth, OAuth, and testing.
6
+ Use this skill when implementing or modifying authentication features.
7
+ allowed-tools: Read, Glob, Grep
8
+ version: 1.0.0
9
+ ---
10
+
11
+ # Better Auth Skill
12
+
13
+ Authentication patterns and best practices for this Next.js application using Better Auth.
14
+
15
+ ## Architecture Overview
16
+
17
+ ```
18
+ core/lib/
19
+ ├── auth.ts # Better Auth configuration
20
+ ├── auth-client.ts # Client-side auth utilities
21
+ └── api/auth/
22
+ ├── dual-auth.ts # Dual authentication (API Key + Session)
23
+ ├── index.ts # API key validation
24
+ └── scopes.ts # Permission scopes
25
+
26
+ app/hooks/
27
+ └── useAuth.ts # Client-side auth hook
28
+
29
+ app/(auth)/
30
+ ├── login/ # Login page
31
+ ├── register/ # Registration page
32
+ ├── verify-email/ # Email verification
33
+ └── forgot-password/ # Password reset
34
+ ```
35
+
36
+ ## When to Use This Skill
37
+
38
+ - Implementing authentication flows (login, register, logout)
39
+ - Adding API key authentication to endpoints
40
+ - Implementing role-based access control
41
+ - Setting up OAuth providers
42
+ - Testing authentication flows
43
+ - Securing API endpoints with dual auth
44
+
45
+ ## Authentication Methods
46
+
47
+ ### 1. Session Authentication (Dashboard)
48
+
49
+ Used for authenticated users in the dashboard UI.
50
+
51
+ ```typescript
52
+ // Server-side session check
53
+ import { auth } from '@/core/lib/auth'
54
+
55
+ const session = await auth.api.getSession({
56
+ headers: request.headers
57
+ })
58
+
59
+ if (!session?.user) {
60
+ return redirect('/login')
61
+ }
62
+ ```
63
+
64
+ ```typescript
65
+ // Client-side with useAuth hook
66
+ import { useAuth } from '@/app/hooks/useAuth'
67
+
68
+ function Dashboard() {
69
+ const { user, session, isLoading, isAuthenticated } = useAuth()
70
+
71
+ if (isLoading) return <Loading />
72
+ if (!isAuthenticated) return redirect('/login')
73
+
74
+ return <div>Welcome, {user.name}</div>
75
+ }
76
+ ```
77
+
78
+ ### 2. API Key Authentication (External APIs)
79
+
80
+ Used for external integrations and programmatic access.
81
+
82
+ ```typescript
83
+ // API Key headers
84
+ // Option 1: Authorization header
85
+ Authorization: Bearer sk_live_xxxxxxxxxxxxx
86
+
87
+ // Option 2: x-api-key header
88
+ x-api-key: sk_live_xxxxxxxxxxxxx
89
+
90
+ // CRITICAL: Always include team context
91
+ x-team-id: team-tmt-001
92
+ ```
93
+
94
+ ### 3. Dual Authentication (Unified Endpoints)
95
+
96
+ All `/api/v1/` endpoints support both authentication methods.
97
+
98
+ ```typescript
99
+ import { authenticateRequest } from '@/core/lib/api/auth/dual-auth'
100
+
101
+ export async function GET(request: NextRequest) {
102
+ // Tries API Key first, then Session
103
+ const authResult = await authenticateRequest(request)
104
+
105
+ if (!authResult.success) {
106
+ return createAuthError('Unauthorized', 401)
107
+ }
108
+
109
+ // authResult contains:
110
+ // - type: 'api-key' | 'session'
111
+ // - user: { id, email, role, defaultTeamId }
112
+ // - scopes: string[] (for API keys) or ['all'] (for sessions)
113
+ }
114
+ ```
115
+
116
+ ## User Roles vs Team Roles
117
+
118
+ ### CRITICAL: Two Separate Role Systems
119
+
120
+ This application has **two completely separate role systems**:
121
+
122
+ | Aspect | User Roles (App-Level) | Team Roles (Team-Level) |
123
+ |--------|------------------------|-------------------------|
124
+ | **Stored in** | `user.role` column | `teamMembers.role` column |
125
+ | **Scope** | Global (entire app) | Per-team membership |
126
+ | **Extensible** | ❌ NO - Fixed in core | ✅ YES - Themes can add custom roles |
127
+ | **Purpose** | System access (routes) | Entity permissions within team |
128
+
129
+ ### User Roles (App-Level, FIXED)
130
+
131
+ ```typescript
132
+ // 3 fixed system roles - CANNOT be extended by themes
133
+ type UserRole = 'member' | 'superadmin' | 'developer'
134
+ ```
135
+
136
+ | Role | Hierarchy | Access | Routes |
137
+ |------|-----------|--------|--------|
138
+ | `member` | 1 | Standard user | `/dashboard/*` |
139
+ | `superadmin` | 99 | System admin, bypasses team permissions | `/superadmin/*` |
140
+ | `developer` | 100 | Full access, debugging APIs | `/devtools/*` |
141
+
142
+ **Check user role:**
143
+ ```typescript
144
+ import { roleHelpers } from '@/core/lib/role-helpers'
145
+
146
+ // CORRECT: Use roleHelpers for user roles
147
+ if (roleHelpers.isDeveloper(user.role)) {
148
+ // Access to /devtools/*
149
+ }
150
+ if (roleHelpers.isSuperAdmin(user.role)) {
151
+ // Access to /superadmin/*, bypass team checks
152
+ }
153
+
154
+ // WRONG: Don't check user roles like team roles
155
+ if (membership.hasRole('superadmin')) {} // Wrong context!
156
+ ```
157
+
158
+ ### Team Roles (Team-Level, EXTENSIBLE)
159
+
160
+ ```typescript
161
+ // Core team roles (protected, always available)
162
+ type CoreTeamRole = 'owner' | 'admin' | 'member' | 'viewer'
163
+
164
+ // Theme can add custom roles
165
+ type TeamRole = CoreTeamRole | 'editor' | 'contributor' | string
166
+ ```
167
+
168
+ | Role | Hierarchy | Description |
169
+ |------|-----------|-------------|
170
+ | `owner` | 100 | Team creator, all permissions, cannot be removed |
171
+ | `admin` | 50 | Team management, member roles, billing |
172
+ | `member` | 10 | Standard entity access |
173
+ | `viewer` | 1 | Read-only access |
174
+ | `editor`* | 5 | Theme-defined: Edit without delete |
175
+ | `contributor`* | 3 | Theme-defined: Limited create/edit |
176
+
177
+ *Custom roles defined in `permissions.config.ts`
178
+
179
+ **Check team role:**
180
+ ```typescript
181
+ import { MembershipService } from '@/core/lib/services'
182
+
183
+ // Get membership context
184
+ const membership = await MembershipService.get(userId, teamId)
185
+
186
+ // Check team role
187
+ if (membership.hasRole('admin')) {
188
+ // Can manage team members
189
+ }
190
+
191
+ // Check specific permission
192
+ if (membership.can('products.create')) {
193
+ // Can create products in this team
194
+ }
195
+ ```
196
+
197
+ ### Why Two Systems?
198
+
199
+ | User Roles | Team Roles |
200
+ |------------|------------|
201
+ | Control **where** users can go | Control **what** users can do |
202
+ | Route-level access | Entity-level permissions |
203
+ | Fixed for security | Flexible for business logic |
204
+ | Checked by middleware | Checked by API/UI |
205
+
206
+ ## User Metadata (users_metas)
207
+
208
+ User metadata is stored in a **separate table** (`users_metas`) using the standard entity meta pattern.
209
+
210
+ ### Schema
211
+
212
+ ```sql
213
+ -- core/migrations/003_user_metas.sql
214
+ CREATE TABLE "users_metas" (
215
+ id TEXT PRIMARY KEY,
216
+ "userId" TEXT NOT NULL REFERENCES "users"(id) ON DELETE CASCADE,
217
+ "metaKey" TEXT NOT NULL,
218
+ "metaValue" JSONB NOT NULL DEFAULT '{}',
219
+ "dataType" TEXT, -- 'string' | 'number' | 'boolean' | 'json'
220
+ "isPublic" BOOLEAN DEFAULT FALSE,
221
+ "isSearchable" BOOLEAN DEFAULT FALSE,
222
+ CONSTRAINT users_metas_unique_key UNIQUE ("userId", "metaKey")
223
+ );
224
+ ```
225
+
226
+ ### Common Meta Keys
227
+
228
+ | Key | Type | Description | isPublic |
229
+ |-----|------|-------------|----------|
230
+ | `preferences.theme` | string | 'light' \| 'dark' \| 'system' | false |
231
+ | `preferences.language` | string | Locale code ('en', 'es') | false |
232
+ | `preferences.timezone` | string | Timezone identifier | false |
233
+ | `preferences.sidebarCollapsed` | boolean | UI state | false |
234
+ | `onboarding.completed` | boolean | Onboarding status | false |
235
+ | `onboarding.step` | number | Current onboarding step | false |
236
+ | `notifications.email` | boolean | Email notification preference | false |
237
+ | `profile.bio` | string | User biography | true |
238
+ | `profile.socialLinks` | json | Social media links | true |
239
+
240
+ ### Usage
241
+
242
+ ```typescript
243
+ import { MetaService } from '@/core/lib/services'
244
+
245
+ // Get user meta
246
+ const theme = await MetaService.get('users', userId, 'preferences.theme')
247
+
248
+ // Set user meta
249
+ await MetaService.set('users', userId, 'preferences.theme', 'dark')
250
+
251
+ // Get multiple metas
252
+ const prefs = await MetaService.getMany('users', userId, [
253
+ 'preferences.theme',
254
+ 'preferences.language'
255
+ ])
256
+
257
+ // Delete meta
258
+ await MetaService.delete('users', userId, 'onboarding.step')
259
+ ```
260
+
261
+ ### Client-Side Hook
262
+
263
+ ```typescript
264
+ import { useUserSettings } from '@/core/hooks/useUserSettings'
265
+
266
+ function SettingsPage() {
267
+ const { settings, updateSetting, isLoading } = useUserSettings()
268
+
269
+ const toggleTheme = () => {
270
+ updateSetting('preferences.theme', settings.theme === 'dark' ? 'light' : 'dark')
271
+ }
272
+
273
+ return (
274
+ <Button onClick={toggleTheme}>
275
+ {settings.theme === 'dark' ? 'Light Mode' : 'Dark Mode'}
276
+ </Button>
277
+ )
278
+ }
279
+ ```
280
+
281
+ ### RLS Policies
282
+
283
+ - **Owner access:** Users can read/write their own metas
284
+ - **Admin access:** Superadmins can read/write any user's metas
285
+ - **Public read:** Metas with `isPublic = true` are readable by anyone
286
+
287
+ ## API Key Scopes
288
+
289
+ ```typescript
290
+ // Scope format: {entity}:{action}
291
+ // Examples:
292
+ // - tasks:read → Read tasks
293
+ // - tasks:write → Create/update tasks
294
+ // - tasks:delete → Delete tasks
295
+ // - tasks:* → Full tasks access
296
+ // - * → Superadmin full access
297
+
298
+ // Check scopes in API
299
+ const hasAccess = authResult.scopes?.includes('tasks:read') ||
300
+ authResult.scopes?.includes('tasks:*') ||
301
+ authResult.scopes?.includes('*')
302
+ ```
303
+
304
+ ## Test Users
305
+
306
+ ### Theme Users (password: `Test1234`)
307
+
308
+ ```typescript
309
+ DEFAULT_THEME_USERS = {
310
+ OWNER: 'carlos.mendoza@tmt.dev', // Everpoint Labs (owner)
311
+ ADMIN: 'james.wilson@tmt.dev', // Everpoint Labs (admin)
312
+ MEMBER: 'emily.johnson@tmt.dev', // Everpoint Labs (member)
313
+ EDITOR: 'diego.ramirez@tmt.dev', // Everpoint Labs (editor)
314
+ VIEWER: 'sarah.davis@tmt.dev', // Ironvale Global (viewer)
315
+ }
316
+ ```
317
+
318
+ ### Core Users (password: `Pandora1234`)
319
+
320
+ ```typescript
321
+ CORE_USERS = {
322
+ SUPERADMIN: 'superadmin@tmt.dev', // Global superadmin
323
+ DEVELOPER: 'developer@tmt.dev', // Global developer
324
+ }
325
+ ```
326
+
327
+ ### Test Teams
328
+
329
+ | Team ID | Team Name | Description |
330
+ |---------|-----------|-------------|
331
+ | `team-tmt-001` | Everpoint Labs | Primary test team |
332
+ | `team-tmt-002` | Ironvale Global | Secondary test team |
333
+
334
+ ## Authentication Flows
335
+
336
+ ### Email/Password Registration
337
+
338
+ ```
339
+ 1. User submits registration form
340
+ 2. Validate email format and password strength
341
+ 3. Create user with emailVerified = false
342
+ 4. Send verification email with token
343
+ 5. User clicks verification link
344
+ 6. Set emailVerified = true
345
+ 7. Redirect to login
346
+ ```
347
+
348
+ ### Email/Password Login
349
+
350
+ ```
351
+ 1. User submits login form
352
+ 2. Validate credentials
353
+ 3. Check emailVerified = true
354
+ 4. Create session
355
+ 5. Set HttpOnly cookie
356
+ 6. Redirect to dashboard
357
+ ```
358
+
359
+ ### Google OAuth
360
+
361
+ ```
362
+ 1. User clicks "Sign in with Google"
363
+ 2. Redirect to Google OAuth
364
+ 3. Google returns profile data
365
+ 4. Map profile to user (mapProfileToUser)
366
+ 5. Create/update user record
367
+ 6. Create session
368
+ 7. Redirect to dashboard
369
+ ```
370
+
371
+ ### Password Reset
372
+
373
+ ```
374
+ 1. User requests password reset
375
+ 2. Generate reset token (1-hour expiry)
376
+ 3. Send reset email
377
+ 4. User clicks reset link
378
+ 5. Validate token
379
+ 6. User enters new password
380
+ 7. Update password hash (bcrypt)
381
+ 8. Invalidate token
382
+ 9. Redirect to login
383
+ ```
384
+
385
+ ## Security Rules
386
+
387
+ ### Password Requirements
388
+
389
+ ```typescript
390
+ // Minimum requirements
391
+ const passwordSchema = z.string()
392
+ .min(8, 'Password must be at least 8 characters')
393
+ .max(128, 'Password cannot exceed 128 characters')
394
+ .regex(/[A-Z]/, 'Password must contain uppercase letter')
395
+ .regex(/[0-9]/, 'Password must contain a number')
396
+ ```
397
+
398
+ ### Session Configuration
399
+
400
+ ```typescript
401
+ // Session settings
402
+ const sessionConfig = {
403
+ expiresIn: 60 * 60 * 24 * 7, // 7 days
404
+ updateAge: 60 * 60 * 24, // Update every day
405
+ cookieOptions: {
406
+ httpOnly: true,
407
+ secure: process.env.NODE_ENV === 'production',
408
+ sameSite: 'lax'
409
+ }
410
+ }
411
+ ```
412
+
413
+ ### Rate Limiting
414
+
415
+ | Action | Limit | Window |
416
+ |--------|-------|--------|
417
+ | Login attempts | 5 | 15 minutes |
418
+ | Password reset | 3 | 1 hour |
419
+ | Verification email | 5 | 1 hour |
420
+ | API requests | 100 | 1 minute |
421
+
422
+ ### Token Expiration
423
+
424
+ | Token Type | Expiration |
425
+ |------------|------------|
426
+ | Email verification | 24 hours |
427
+ | Password reset | 1 hour |
428
+ | Session | 7 days |
429
+ | API Key | No expiration (revocable) |
430
+
431
+ ## useAuth Hook
432
+
433
+ ```typescript
434
+ import { useAuth } from '@/app/hooks/useAuth'
435
+
436
+ function Component() {
437
+ const {
438
+ // State
439
+ user, // Current user object
440
+ session, // Session data
441
+ isLoading, // Loading state
442
+ isAuthenticated, // Boolean auth status
443
+
444
+ // Actions
445
+ signIn, // (email, password) => Promise
446
+ signUp, // (email, password, name) => Promise
447
+ signOut, // () => Promise
448
+ resetPassword, // (email) => Promise
449
+ updateProfile, // (data) => Promise
450
+ } = useAuth()
451
+
452
+ // Example: Sign in
453
+ const handleLogin = async () => {
454
+ try {
455
+ await signIn(email, password)
456
+ router.push('/dashboard')
457
+ } catch (error) {
458
+ setError(error.message)
459
+ }
460
+ }
461
+ }
462
+ ```
463
+
464
+ ## Protected Routes
465
+
466
+ ### Middleware Protection
467
+
468
+ ```typescript
469
+ // middleware.ts
470
+ export { auth as middleware } from "@/core/lib/auth"
471
+
472
+ export const config = {
473
+ matcher: [
474
+ '/dashboard/:path*',
475
+ '/profile/:path*',
476
+ '/api/user/:path*'
477
+ ]
478
+ }
479
+ ```
480
+
481
+ ### Page-Level Protection
482
+
483
+ ```typescript
484
+ // app/dashboard/page.tsx
485
+ import { auth } from '@/core/lib/auth'
486
+ import { redirect } from 'next/navigation'
487
+
488
+ export default async function DashboardPage() {
489
+ const session = await auth.api.getSession({
490
+ headers: headers()
491
+ })
492
+
493
+ if (!session) {
494
+ redirect('/login')
495
+ }
496
+
497
+ return <Dashboard user={session.user} />
498
+ }
499
+ ```
500
+
501
+ ## Error Codes
502
+
503
+ | Code | HTTP Status | Description |
504
+ |------|-------------|-------------|
505
+ | `AUTHENTICATION_REQUIRED` | 401 | No auth credentials provided |
506
+ | `INVALID_API_KEY` | 401 | API key invalid or expired |
507
+ | `INVALID_CREDENTIALS` | 401 | Wrong email/password |
508
+ | `EMAIL_NOT_VERIFIED` | 401 | User hasn't verified email |
509
+ | `INSUFFICIENT_PERMISSIONS` | 403 | User lacks required scope |
510
+ | `TEAM_CONTEXT_REQUIRED` | 400 | Missing x-team-id header |
511
+ | `SESSION_EXPIRED` | 401 | Session no longer valid |
512
+
513
+ ## Testing Authentication
514
+
515
+ ### Cypress Session Pattern
516
+
517
+ ```typescript
518
+ describe('Authenticated Tests', () => {
519
+ beforeEach(() => {
520
+ cy.session('owner-session', () => {
521
+ cy.visit('/login')
522
+ cy.get('[data-cy="email-input"]').type('carlos.mendoza@tmt.dev')
523
+ cy.get('[data-cy="password-input"]').type('Test1234')
524
+ cy.get('[data-cy="login-submit"]').click()
525
+ cy.url().should('include', '/dashboard')
526
+ }, {
527
+ validate: () => {
528
+ cy.visit('/dashboard')
529
+ cy.url().should('include', '/dashboard')
530
+ }
531
+ })
532
+ })
533
+
534
+ it('should access protected page', () => {
535
+ cy.visit('/dashboard/tasks')
536
+ cy.get('[data-cy="tasks-table"]').should('exist')
537
+ })
538
+ })
539
+ ```
540
+
541
+ ### API Test Pattern
542
+
543
+ ```typescript
544
+ describe('API Auth Tests', () => {
545
+ const API_KEY = Cypress.env('SUPERADMIN_API_KEY')
546
+ const TEAM_ID = 'team-tmt-001'
547
+
548
+ it('should authenticate with API key', () => {
549
+ cy.request({
550
+ method: 'GET',
551
+ url: '/api/v1/tasks',
552
+ headers: {
553
+ 'Authorization': `Bearer ${API_KEY}`,
554
+ 'x-team-id': TEAM_ID
555
+ }
556
+ }).then((response) => {
557
+ expect(response.status).to.eq(200)
558
+ })
559
+ })
560
+
561
+ it('should reject without API key', () => {
562
+ cy.request({
563
+ method: 'GET',
564
+ url: '/api/v1/tasks',
565
+ failOnStatusCode: false
566
+ }).then((response) => {
567
+ expect(response.status).to.eq(401)
568
+ })
569
+ })
570
+ })
571
+ ```
572
+
573
+ ## OAuth Configuration
574
+
575
+ ### Google OAuth
576
+
577
+ ```typescript
578
+ // core/lib/auth.ts
579
+ socialProviders: {
580
+ google: {
581
+ clientId: process.env.GOOGLE_CLIENT_ID!,
582
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
583
+ mapProfileToUser: (profile) => ({
584
+ email: profile.email,
585
+ name: profile.name,
586
+ image: profile.picture,
587
+ emailVerified: profile.email_verified
588
+ })
589
+ }
590
+ }
591
+ ```
592
+
593
+ ### Environment Variables
594
+
595
+ ```env
596
+ # Better Auth
597
+ BETTER_AUTH_SECRET=your-secret-key
598
+ NEXT_PUBLIC_APP_URL=http://localhost:5173
599
+
600
+ # Google OAuth
601
+ GOOGLE_CLIENT_ID=your-client-id
602
+ GOOGLE_CLIENT_SECRET=your-client-secret
603
+
604
+ # Email (Resend)
605
+ RESEND_API_KEY=your-resend-key
606
+ RESEND_FROM_EMAIL=noreply@yourdomain.com
607
+ ```
608
+
609
+ ## Anti-Patterns
610
+
611
+ ```typescript
612
+ // NEVER: Store passwords in plain text
613
+ user.password = 'plain-text-password'
614
+
615
+ // CORRECT: Use bcrypt via Better Auth
616
+ await auth.api.signUp({ email, password, name })
617
+
618
+ // NEVER: Skip email verification
619
+ if (!user.emailVerified) {
620
+ // Allow access anyway... WRONG!
621
+ }
622
+
623
+ // CORRECT: Require verification
624
+ if (!user.emailVerified) {
625
+ redirect('/verify-email')
626
+ }
627
+
628
+ // NEVER: Expose API keys in client code
629
+ const API_KEY = 'sk_live_xxxxx' // In browser!
630
+
631
+ // CORRECT: Use environment variables (server-side only)
632
+ const API_KEY = process.env.API_KEY // Server only
633
+
634
+ // NEVER: Skip team context for entity operations
635
+ // Missing x-team-id header
636
+
637
+ // CORRECT: Always include team context
638
+ headers: { 'x-team-id': teamId }
639
+
640
+ // NEVER: Trust client-provided user data
641
+ const userId = request.body.userId // User can fake this!
642
+
643
+ // CORRECT: Get user from authenticated session
644
+ const { user } = await authenticateRequest(request)
645
+ ```
646
+
647
+ ## Checklist
648
+
649
+ Before finalizing authentication code:
650
+
651
+ - [ ] Uses Better Auth for all auth operations
652
+ - [ ] Sessions use HttpOnly, Secure cookies
653
+ - [ ] Email verification required for email/password
654
+ - [ ] Password meets minimum requirements (8+ chars)
655
+ - [ ] API endpoints use dual auth pattern
656
+ - [ ] Protected routes redirect unauthenticated users
657
+ - [ ] Error responses use proper status codes
658
+ - [ ] Rate limiting implemented for sensitive endpoints
659
+ - [ ] OAuth profile mapping configured correctly
660
+ - [ ] Test users documented and working
661
+
662
+ ## Related Skills
663
+
664
+ - `cypress-e2e` - UAT testing with session authentication
665
+ - `cypress-api` - API testing with API key authentication
666
+ - `nextjs-api-development` - API route patterns