@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,550 @@
1
+ ---
2
+ name: api-bypass-layers
3
+ description: |
4
+ Multi-layer security architecture for API bypass (superadmin/developer).
5
+ Covers authentication layers, authorization, team context, RLS policies, and three-layer bypass validation.
6
+ Use this skill when implementing admin bypass features or validating security architecture.
7
+ allowed-tools: Read, Glob, Grep
8
+ version: 1.1.0
9
+ ---
10
+
11
+ # API Bypass Layers Skill
12
+
13
+ Security architecture for superadmin and developer bypass access in the API layer.
14
+
15
+ ## File References
16
+
17
+ | File | Purpose |
18
+ |------|---------|
19
+ | `packages/core/src/lib/api/auth/dual-auth.ts` | App-level bypass (canBypassTeamContext) |
20
+ | `packages/core/src/lib/api/entity/generic-handler.ts` | CRUD handler (validateTeamContextWithBypass) |
21
+ | `packages/core/migrations/001_better_auth_and_functions.sql` | get_auth_user_id() function |
22
+ | `packages/core/migrations/010_teams_functions_triggers.sql` | can_bypass_rls(), get_user_team_ids(), RLS policies |
23
+ | `packages/core/migrations/090_sample_data.sql` | System Admin Team (team-nextspark-001) |
24
+
25
+ ## Architecture Overview
26
+
27
+ ```
28
+ ┌─────────────────────────────────────────────────────────────────┐
29
+ │ LAYER 1: AUTHENTICATION │
30
+ ├─────────────────────────────────────────────────────────────────┤
31
+ │ API Key Auth │ Session Auth │
32
+ │ ├─ x-api-key header │ ├─ Browser cookies │
33
+ │ ├─ Constant-time delay │ ├─ Better Auth framework │
34
+ │ ├─ Key expiration check │ └─ Full access (scopes: ['all']) │
35
+ │ ├─ Failed attempt lockout │ │
36
+ │ └─ Scoped permissions │ │
37
+ └─────────────────────────────────────────────────────────────────┘
38
+
39
+ ┌─────────────────────────────────────────────────────────────────┐
40
+ │ LAYER 2: AUTHORIZATION │
41
+ ├─────────────────────────────────────────────────────────────────┤
42
+ │ Admin Bypass Check (Three-Layer Validation) │
43
+ │ ├─ LAYER 1: Role check (superadmin OR developer) │
44
+ │ ├─ LAYER 2: Header confirmation (x-admin-bypass) │
45
+ │ └─ LAYER 3: System Admin Team membership (team-nextspark-001) │
46
+ │ │
47
+ │ Permission Check │
48
+ │ ├─ Entity-level permissions (entity.action format) │
49
+ │ ├─ Team role hierarchy (owner > admin > member > viewer) │
50
+ │ └─ Scope validation for API keys │
51
+ └─────────────────────────────────────────────────────────────────┘
52
+
53
+ ┌─────────────────────────────────────────────────────────────────┐
54
+ │ LAYER 3: TEAM CONTEXT │
55
+ ├─────────────────────────────────────────────────────────────────┤
56
+ │ Normal Mode (isBypass = false) │
57
+ │ ├─ x-team-id header REQUIRED │
58
+ │ ├─ Validate user is team member │
59
+ │ ├─ Filter by teamId AND userId │
60
+ │ └─ Reject if not member (403 TEAM_ACCESS_DENIED) │
61
+ │ │
62
+ │ Bypass Mode (isBypass = true) │
63
+ │ ├─ x-team-id header OPTIONAL │
64
+ │ ├─ Skip membership validation │
65
+ │ ├─ Skip userId filter │
66
+ │ └─ Cross-team or specific team access │
67
+ └─────────────────────────────────────────────────────────────────┘
68
+
69
+ ┌─────────────────────────────────────────────────────────────────┐
70
+ │ LAYER 4: DATABASE RLS │
71
+ ├─────────────────────────────────────────────────────────────────┤
72
+ │ PostgreSQL Row Level Security (Final Defense) │
73
+ │ ├─ can_bypass_rls() - superadmin ALWAYS, developer IF member │
74
+ │ ├─ get_auth_user_id() - reads from app.user_id GUC │
75
+ │ ├─ get_user_team_ids() - array of user's teams │
76
+ │ └─ Policies: SELECT/INSERT/UPDATE/DELETE per table │
77
+ │ │
78
+ │ Example Policy: │
79
+ │ can_bypass_rls() OR teamId = ANY(get_user_team_ids()) │
80
+ └─────────────────────────────────────────────────────────────────┘
81
+ ```
82
+
83
+ ## When to Use This Skill
84
+
85
+ - Understanding the multi-layer security model
86
+ - Implementing admin bypass for new features
87
+ - Debugging authorization issues
88
+ - Validating RLS policies work correctly
89
+ - Adding new bypass-protected endpoints
90
+ - Testing cross-team access scenarios
91
+
92
+ ## Constants
93
+
94
+ **File:** `packages/core/src/lib/api/auth/dual-auth.ts:13-31`
95
+
96
+ ```typescript
97
+ // System Admin Team - Members can bypass team context validation
98
+ export const SYSTEM_ADMIN_TEAM_ID = 'team-nextspark-001'
99
+
100
+ // Header required to confirm cross-team access intention
101
+ export const ADMIN_BYPASS_HEADER = 'x-admin-bypass'
102
+ export const ADMIN_BYPASS_VALUE = 'confirm-cross-team-access'
103
+
104
+ // Roles that can potentially bypass team context
105
+ const ELEVATED_ROLES = ['superadmin', 'developer'] as const
106
+ ```
107
+
108
+ ## App-Level Bypass: canBypassTeamContext()
109
+
110
+ **File:** `packages/core/src/lib/api/auth/dual-auth.ts:205-226`
111
+
112
+ Three-layer validation for admin bypass at the application level:
113
+
114
+ ```typescript
115
+ export async function canBypassTeamContext(
116
+ authResult: DualAuthResult,
117
+ request: NextRequest
118
+ ): Promise<boolean> {
119
+ // LAYER 1: Must have elevated role
120
+ if (!authResult.success || !authResult.user) return false
121
+ const hasElevatedRole = ELEVATED_ROLES.includes(
122
+ authResult.user.role as typeof ELEVATED_ROLES[number]
123
+ )
124
+ if (!hasElevatedRole) return false
125
+
126
+ // LAYER 2: Must include confirmation header
127
+ const bypassHeader = request.headers.get(ADMIN_BYPASS_HEADER)
128
+ if (bypassHeader !== ADMIN_BYPASS_VALUE) return false
129
+
130
+ // LAYER 3: Must be member of System Admin Team
131
+ const isMember = await checkSystemAdminMembership(authResult.user.id)
132
+ if (!isMember) {
133
+ console.log('[dual-auth] User has elevated role but is not member of System Admin Team')
134
+ }
135
+ return isMember
136
+ }
137
+ ```
138
+
139
+ ### Three-Layer Validation Table
140
+
141
+ | Layer | Check | Requirement |
142
+ |-------|-------|-------------|
143
+ | 1 | Role | `user.role` is `superadmin` OR `developer` |
144
+ | 2 | Header | `x-admin-bypass: confirm-cross-team-access` |
145
+ | 3 | Membership | User belongs to `team-nextspark-001` |
146
+
147
+ ## Team Context Validation: validateTeamContextWithBypass()
148
+
149
+ **File:** `packages/core/src/lib/api/entity/generic-handler.ts:267-309`
150
+
151
+ ```typescript
152
+ async function validateTeamContextWithBypass(
153
+ request: NextRequest,
154
+ authResult: DualAuthResult,
155
+ userId: string
156
+ ): Promise<{ valid: true; teamId: string | null; isBypass: boolean } | { valid: false; error: NextResponse }> {
157
+ const teamId = getTeamIdFromRequest(request)
158
+
159
+ // Check if user can bypass team validation
160
+ const canBypass = await canBypassTeamContext(authResult, request)
161
+
162
+ if (canBypass) {
163
+ // Admin bypass: teamId is optional
164
+ // - If provided: filter by that team (no membership check)
165
+ // - If not provided: cross-team access (all teams)
166
+ // isBypass = true means skip userId filter too (see all records)
167
+ console.log('[GenericHandler] Admin bypass active:', { userId, teamId: teamId || 'cross-team' })
168
+ return { valid: true, teamId, isBypass: true }
169
+ }
170
+
171
+ // Normal flow: require teamId and membership
172
+ if (!teamId) {
173
+ const response = createApiError(
174
+ 'Team context required. Include x-team-id header.',
175
+ 400,
176
+ undefined,
177
+ 'TEAM_CONTEXT_REQUIRED'
178
+ )
179
+ return { valid: false, error: await addCorsHeaders(response) }
180
+ }
181
+
182
+ const isMember = await validateTeamMembership(userId, teamId)
183
+ if (!isMember) {
184
+ const response = createApiError(
185
+ 'Access denied: You are not a member of this team',
186
+ 403,
187
+ undefined,
188
+ 'TEAM_ACCESS_DENIED'
189
+ )
190
+ return { valid: false, error: await addCorsHeaders(response) }
191
+ }
192
+
193
+ return { valid: true, teamId, isBypass: false }
194
+ }
195
+ ```
196
+
197
+ ## isBypass Flag Usage
198
+
199
+ **File:** `packages/core/src/lib/api/entity/generic-handler.ts`
200
+
201
+ The `isBypass` flag controls userId filtering in queries:
202
+
203
+ ```typescript
204
+ // Line ~509, 538, 563, 1138
205
+ if (userId && !entityConfig.access?.shared && !skipUserFilter && !isBypass) {
206
+ // Apply userId filter - only see own records
207
+ }
208
+ // When isBypass = true, this filter is skipped, allowing cross-user access
209
+ ```
210
+
211
+ ## Database-Level Bypass: can_bypass_rls()
212
+
213
+ **File:** `packages/core/migrations/010_teams_functions_triggers.sql:115-147`
214
+
215
+ **CRITICAL DIFFERENCE from App-Level:**
216
+ - **Superadmin:** ALWAYS bypasses RLS (no team membership check)
217
+ - **Developer:** Only bypasses IF member of System Admin Team
218
+
219
+ ```sql
220
+ CREATE OR REPLACE FUNCTION public.can_bypass_rls()
221
+ RETURNS BOOLEAN AS $$
222
+ DECLARE
223
+ current_user_id TEXT;
224
+ user_role TEXT;
225
+ is_system_admin_member BOOLEAN;
226
+ BEGIN
227
+ current_user_id := public.get_auth_user_id();
228
+
229
+ -- Get user role
230
+ SELECT role INTO user_role
231
+ FROM public."users"
232
+ WHERE id = current_user_id;
233
+
234
+ -- Superadmin ALWAYS bypasses (no team membership check)
235
+ IF user_role = 'superadmin' THEN
236
+ RETURN TRUE;
237
+ END IF;
238
+
239
+ -- Developer can bypass ONLY if member of System Admin Team
240
+ IF user_role = 'developer' THEN
241
+ SELECT EXISTS(
242
+ SELECT 1 FROM public."team_members"
243
+ WHERE "userId" = current_user_id
244
+ AND "teamId" = 'team-nextspark-001'
245
+ ) INTO is_system_admin_member;
246
+
247
+ RETURN is_system_admin_member;
248
+ END IF;
249
+
250
+ RETURN FALSE;
251
+ END;
252
+ $$ LANGUAGE plpgsql STABLE SECURITY DEFINER;
253
+ ```
254
+
255
+ ## App vs DB Bypass Logic Comparison
256
+
257
+ | Role | App-Level (canBypassTeamContext) | DB-Level (can_bypass_rls) |
258
+ |------|----------------------------------|---------------------------|
259
+ | superadmin | Needs header + team membership | ALWAYS bypasses |
260
+ | developer | Needs header + team membership | Only with team membership |
261
+ | member | Cannot bypass | Cannot bypass |
262
+
263
+ **Why the difference?**
264
+ - App-level: Requires explicit intent (header) to prevent accidents
265
+ - DB-level: Final defense, superadmin always trusted at data layer
266
+
267
+ ## RLS Helper Functions
268
+
269
+ ### get_auth_user_id()
270
+
271
+ **File:** `packages/core/migrations/001_better_auth_and_functions.sql:10-24`
272
+
273
+ ```sql
274
+ CREATE OR REPLACE FUNCTION public.get_auth_user_id()
275
+ RETURNS TEXT
276
+ LANGUAGE plpgsql
277
+ SECURITY DEFINER
278
+ SET search_path = public
279
+ AS $$
280
+ DECLARE v TEXT;
281
+ BEGIN
282
+ v := current_setting('app.user_id', true);
283
+ IF v IS NULL OR v = '' THEN
284
+ RETURN NULL;
285
+ END IF;
286
+ RETURN v;
287
+ END;
288
+ $$;
289
+ ```
290
+
291
+ ### get_user_team_ids()
292
+
293
+ **File:** `packages/core/migrations/010_teams_functions_triggers.sql:98-109`
294
+
295
+ ```sql
296
+ CREATE OR REPLACE FUNCTION public.get_user_team_ids()
297
+ RETURNS TEXT[] AS $$
298
+ DECLARE
299
+ user_teams TEXT[];
300
+ BEGIN
301
+ SELECT ARRAY_AGG(tm."teamId") INTO user_teams
302
+ FROM public."team_members" tm
303
+ WHERE tm."userId" = public.get_auth_user_id();
304
+
305
+ RETURN COALESCE(user_teams, ARRAY[]::TEXT[]);
306
+ END;
307
+ $$ LANGUAGE plpgsql STABLE SECURITY DEFINER;
308
+ ```
309
+
310
+ ## RLS Policy Pattern
311
+
312
+ **File:** `packages/core/migrations/010_teams_functions_triggers.sql:164-208`
313
+
314
+ ```sql
315
+ -- SELECT policy
316
+ CREATE POLICY "teams_select_policy" ON public."teams"
317
+ FOR SELECT TO authenticated
318
+ USING (
319
+ public.is_superadmin() -- Alias for can_bypass_rls()
320
+ OR
321
+ id IN (
322
+ SELECT "teamId" FROM public."team_members"
323
+ WHERE "userId" = public.get_auth_user_id()
324
+ )
325
+ );
326
+
327
+ -- UPDATE policy
328
+ CREATE POLICY "teams_update_policy" ON public."teams"
329
+ FOR UPDATE TO authenticated
330
+ USING (
331
+ public.is_superadmin()
332
+ OR
333
+ "ownerId" = public.get_auth_user_id()
334
+ )
335
+ WITH CHECK (
336
+ public.is_superadmin()
337
+ OR
338
+ "ownerId" = public.get_auth_user_id()
339
+ );
340
+
341
+ -- DELETE policy
342
+ CREATE POLICY "teams_delete_policy" ON public."teams"
343
+ FOR DELETE TO authenticated
344
+ USING (
345
+ public.is_superadmin()
346
+ OR
347
+ "ownerId" = public.get_auth_user_id()
348
+ );
349
+ ```
350
+
351
+ ## Error Codes
352
+
353
+ | Code | HTTP Status | Trigger |
354
+ |------|-------------|---------|
355
+ | `TEAM_CONTEXT_REQUIRED` | 400 | Missing `x-team-id` header (non-bypass mode) |
356
+ | `TEAM_ACCESS_DENIED` | 403 | User not member of specified team |
357
+ | `AUTHENTICATION_FAILED` | 401 | Invalid credentials |
358
+
359
+ ## Normal Mode vs Bypass Mode
360
+
361
+ ### Normal Mode (Default)
362
+
363
+ ```typescript
364
+ // Headers required
365
+ const headers = {
366
+ 'x-team-id': 'team-xxx' // REQUIRED
367
+ }
368
+
369
+ // Behavior
370
+ // - teamId is REQUIRED
371
+ // - Validate user is team member
372
+ // - Filter results by teamId AND userId
373
+ // - Return 403 TEAM_ACCESS_DENIED if not member
374
+ ```
375
+
376
+ ### Bypass Mode (Admin)
377
+
378
+ ```typescript
379
+ // Headers required
380
+ const headers = {
381
+ 'x-admin-bypass': 'confirm-cross-team-access', // REQUIRED
382
+ 'x-team-id': 'team-xxx' // OPTIONAL (for filtering)
383
+ }
384
+
385
+ // Behavior
386
+ // - teamId is OPTIONAL
387
+ // - Skip membership validation
388
+ // - Skip userId filter (isBypass = true)
389
+ // - Access all teams or specific team
390
+ ```
391
+
392
+ ## Request Flow Diagram
393
+
394
+ ```
395
+ ┌──────────────────────────────────────────────────────────────────────────┐
396
+ │ API REQUEST │
397
+ ├──────────────────────────────────────────────────────────────────────────┤
398
+ │ Headers: │
399
+ │ ├─ Authorization: Bearer <api-key> OR Cookie: session=... │
400
+ │ ├─ x-team-id: team-xxx (required in normal mode) │
401
+ │ └─ x-admin-bypass: confirm-... (enables bypass mode) │
402
+ └──────────────────────────────────────────────────────────────────────────┘
403
+
404
+
405
+ ┌──────────────────────────────────────────────────────────────────────────┐
406
+ │ BACKEND SECURITY LAYERS │
407
+ ├──────────────────────────────────────────────────────────────────────────┤
408
+ │ │
409
+ │ LAYER 1: Authentication (dual-auth.ts:71-89) │
410
+ │ └─ authenticateRequest() → DualAuthResult │
411
+ │ │
412
+ │ LAYER 2: Authorization (dual-auth.ts:205-226) │
413
+ │ └─ canBypassTeamContext() → role + header + team check │
414
+ │ │
415
+ │ LAYER 3: Team Context (generic-handler.ts:267-309) │
416
+ │ └─ validateTeamContextWithBypass() → { teamId, isBypass } │
417
+ │ │
418
+ │ LAYER 4: Query Building (generic-handler.ts:509+) │
419
+ │ └─ Add teamId/userId filters based on isBypass flag │
420
+ │ │
421
+ │ LAYER 5: Database RLS (010_teams_functions_triggers.sql:115-147) │
422
+ │ └─ can_bypass_rls() OR teamId = ANY(get_user_team_ids()) │
423
+ │ │
424
+ └──────────────────────────────────────────────────────────────────────────┘
425
+
426
+
427
+ ┌──────────────────────────────────────────────────────────────────────────┐
428
+ │ FILTERED RESPONSE │
429
+ ├──────────────────────────────────────────────────────────────────────────┤
430
+ │ { success: true, data: [...filtered results...], info: { total: N } } │
431
+ └──────────────────────────────────────────────────────────────────────────┘
432
+ ```
433
+
434
+ ## Testing Bypass Mode
435
+
436
+ ### Cypress API Test
437
+
438
+ ```typescript
439
+ describe('Admin Bypass', () => {
440
+ const SUPERADMIN_KEY = Cypress.env('SUPERADMIN_API_KEY')
441
+
442
+ it('should allow cross-team access with bypass', () => {
443
+ cy.request({
444
+ method: 'GET',
445
+ url: '/api/v1/products',
446
+ headers: {
447
+ 'Authorization': `Bearer ${SUPERADMIN_KEY}`,
448
+ 'x-admin-bypass': 'confirm-cross-team-access'
449
+ // No x-team-id = cross-team mode
450
+ }
451
+ }).then((response) => {
452
+ expect(response.status).to.eq(200)
453
+ // Returns data from ALL teams
454
+ })
455
+ })
456
+
457
+ it('should filter to specific team with bypass', () => {
458
+ cy.request({
459
+ method: 'GET',
460
+ url: '/api/v1/products',
461
+ headers: {
462
+ 'Authorization': `Bearer ${SUPERADMIN_KEY}`,
463
+ 'x-admin-bypass': 'confirm-cross-team-access',
464
+ 'x-team-id': 'team-tmt-002' // Filter to specific team
465
+ }
466
+ }).then((response) => {
467
+ expect(response.status).to.eq(200)
468
+ // Returns data only from team-tmt-002
469
+ })
470
+ })
471
+
472
+ it('should reject bypass without header', () => {
473
+ cy.request({
474
+ method: 'GET',
475
+ url: '/api/v1/products',
476
+ headers: {
477
+ 'Authorization': `Bearer ${SUPERADMIN_KEY}`
478
+ // Missing x-admin-bypass and x-team-id
479
+ },
480
+ failOnStatusCode: false
481
+ }).then((response) => {
482
+ expect(response.status).to.eq(400)
483
+ expect(response.body.code).to.eq('TEAM_CONTEXT_REQUIRED')
484
+ })
485
+ })
486
+ })
487
+ ```
488
+
489
+ ## Security Strengths
490
+
491
+ | Feature | Implementation | Benefit |
492
+ |---------|----------------|---------|
493
+ | **Dual Authentication** | API Key + Session | Flexibility for different use cases |
494
+ | **Three-Layer App Bypass** | Role + Header + Team | Defense in depth, prevents accidents |
495
+ | **RLS Final Defense** | PostgreSQL policies | Data isolation even if app bypassed |
496
+ | **Team Isolation** | App + DB checks | Multi-tenant security |
497
+ | **System Admin Team** | Hardcoded ID | Prevents privilege escalation |
498
+ | **isBypass Flag** | Skip userId filter | Cross-user visibility for admins |
499
+
500
+ ## Anti-Patterns
501
+
502
+ ```typescript
503
+ // NEVER: Allow bypass based on role alone at app level
504
+ if (user.role === 'superadmin') {
505
+ return true // WRONG! Missing header and team checks at app level
506
+ }
507
+
508
+ // CORRECT: Use the three-layer function
509
+ const isBypass = await canBypassTeamContext(authResult, request)
510
+
511
+ // NEVER: Trust client-provided bypass status
512
+ const isBypass = request.body.isBypass // User can fake this!
513
+
514
+ // CORRECT: Validate bypass on server
515
+ const isBypass = await canBypassTeamContext(authResult, request)
516
+
517
+ // NEVER: Skip userId filter without checking bypass
518
+ if (user.role === 'superadmin') {
519
+ skipUserFilter = true // WRONG! Should use isBypass from validation
520
+ }
521
+
522
+ // CORRECT: Use the isBypass flag from validateTeamContextWithBypass
523
+ const { teamId, isBypass } = await validateTeamContextWithBypass(request, authResult, userId)
524
+ if (!isBypass) {
525
+ // Apply userId filter
526
+ }
527
+ ```
528
+
529
+ ## Checklist
530
+
531
+ Before finalizing bypass implementation:
532
+
533
+ - [ ] App-level uses three-layer validation (role + header + team)
534
+ - [ ] `x-admin-bypass` header value is exactly `confirm-cross-team-access`
535
+ - [ ] System Admin Team ID is `team-nextspark-001` (hardcoded)
536
+ - [ ] RLS policies use `can_bypass_rls()` function
537
+ - [ ] Superadmin always bypasses RLS (no team check at DB level)
538
+ - [ ] Developer requires System Admin Team membership for RLS bypass
539
+ - [ ] `isBypass` flag controls userId filter in queries
540
+ - [ ] Normal mode requires `x-team-id` header
541
+ - [ ] Bypass mode makes `x-team-id` optional
542
+ - [ ] Error codes: `TEAM_CONTEXT_REQUIRED` (400), `TEAM_ACCESS_DENIED` (403)
543
+
544
+ ## Related Skills
545
+
546
+ - `better-auth` - Authentication patterns and session management
547
+ - `permissions-system` - RBAC + Features + Quotas permission model
548
+ - `database-migrations` - PostgreSQL RLS policies
549
+ - `nextjs-api-development` - API route patterns with dual auth
550
+ - `cypress-api` - API testing with bypass scenarios