class-ai-agent 1.2.3 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/README.md +33 -0
- package/.agent/SESSION.md +54 -0
- package/.agent/SESSION.template.md +46 -0
- package/.claude/CLAUDE.md +24 -6
- package/.claude/commands/build.md +5 -4
- package/.claude/commands/debug.md +2 -1
- package/.claude/commands/handoff.md +94 -0
- package/.claude/commands/plan.md +1 -0
- package/.claude/commands/publish-npm.md +119 -0
- package/.claude/commands/resume.md +107 -0
- package/.claude/commands/spec.md +2 -1
- package/.claude/references/agent-continuity.md +42 -0
- package/.claude/references/codegraph.md +50 -0
- package/.claude/references/supabase.md +55 -0
- package/.claude/rules/agent-continuity.md +39 -0
- package/.claude/rules/tech-stack.md +2 -1
- package/.claude/skills/agent-continuity/SKILL.md +70 -0
- package/.claude/skills/supabase/SKILL.md +135 -0
- package/.claude/skills/supabase/UPSTREAM.md +16 -0
- package/.claude/skills/supabase/assets/feedback-issue-template.md +17 -0
- package/.claude/skills/supabase/references/skill-feedback.md +17 -0
- package/.claude/skills/supabase-postgres-best-practices/SKILL.md +64 -0
- package/.claude/skills/supabase-postgres-best-practices/UPSTREAM.md +16 -0
- package/.claude/skills/supabase-postgres-best-practices/references/_contributing.md +170 -0
- package/.claude/skills/supabase-postgres-best-practices/references/_sections.md +39 -0
- package/.claude/skills/supabase-postgres-best-practices/references/_template.md +34 -0
- package/.claude/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
- package/.claude/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
- package/.claude/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
- package/.claude/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
- package/.claude/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
- package/.claude/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
- package/.claude/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
- package/.claude/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
- package/.claude/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
- package/.claude/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
- package/.claude/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
- package/.claude/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
- package/.claude/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
- package/.claude/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
- package/.claude/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
- package/.claude/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
- package/.claude/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
- package/.claude/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
- package/.claude/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
- package/.claude/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
- package/.claude/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
- package/.claude/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
- package/.claude/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
- package/.claude/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
- package/.claude/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
- package/.claude/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
- package/.claude/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
- package/.claude/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
- package/.claude/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
- package/.claude/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
- package/.claude/skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -0
- package/.cursor/CURSOR.md +40 -5
- package/.cursor/commands/build.md +5 -4
- package/.cursor/commands/debug.md +2 -1
- package/.cursor/commands/handoff.md +94 -0
- package/.cursor/commands/plan.md +1 -0
- package/.cursor/commands/publish-npm.md +119 -0
- package/.cursor/commands/resume.md +107 -0
- package/.cursor/commands/spec.md +2 -1
- package/.cursor/mcp.json +19 -0
- package/.cursor/references/agent-continuity.md +42 -0
- package/.cursor/references/codegraph.md +87 -0
- package/.cursor/references/supabase.md +55 -0
- package/.cursor/rules/agent-continuity.mdc +44 -0
- package/.cursor/rules/codegraph.mdc +47 -0
- package/.cursor/rules/cursor-overview.mdc +10 -3
- package/.cursor/rules/tech-stack.mdc +2 -1
- package/.cursor/settings.json +6 -1
- package/.cursor/skills/agent-continuity/SKILL.md +70 -0
- package/.cursor/skills/supabase/SKILL.md +135 -0
- package/.cursor/skills/supabase/UPSTREAM.md +16 -0
- package/.cursor/skills/supabase/assets/feedback-issue-template.md +17 -0
- package/.cursor/skills/supabase/references/skill-feedback.md +17 -0
- package/.cursor/skills/supabase-postgres-best-practices/SKILL.md +64 -0
- package/.cursor/skills/supabase-postgres-best-practices/UPSTREAM.md +16 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/_contributing.md +170 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/_sections.md +39 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/_template.md +34 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
- package/.cursor/skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -0
- package/.kiro/KIRO.md +149 -0
- package/.kiro/agents/backend.md +395 -0
- package/.kiro/agents/code-reviewer.md +110 -0
- package/.kiro/agents/copywriter-seo.md +236 -0
- package/.kiro/agents/frontend.md +384 -0
- package/.kiro/agents/project-manager.md +201 -0
- package/.kiro/agents/qa.md +221 -0
- package/.kiro/agents/security-auditor.md +143 -0
- package/.kiro/agents/systems-architect.md +211 -0
- package/.kiro/agents/test-engineer.md +123 -0
- package/.kiro/agents/ui-ux-designer.md +210 -0
- package/.kiro/commands/build.md +133 -0
- package/.kiro/commands/debug.md +243 -0
- package/.kiro/commands/deploy.md +40 -0
- package/.kiro/commands/fix-issue.md +42 -0
- package/.kiro/commands/handoff.md +94 -0
- package/.kiro/commands/plan.md +126 -0
- package/.kiro/commands/publish-npm.md +119 -0
- package/.kiro/commands/resume.md +107 -0
- package/.kiro/commands/review.md +50 -0
- package/.kiro/commands/simplify.md +222 -0
- package/.kiro/commands/spec.md +96 -0
- package/.kiro/commands/test.md +214 -0
- package/.kiro/references/accessibility-checklist.md +174 -0
- package/.kiro/references/agent-continuity.md +42 -0
- package/.kiro/references/codegraph.md +86 -0
- package/.kiro/references/performance-checklist.md +150 -0
- package/.kiro/references/security-checklist.md +94 -0
- package/.kiro/references/supabase.md +55 -0
- package/.kiro/references/testing-patterns.md +183 -0
- package/.kiro/settings/mcp.json +19 -0
- package/.kiro/settings.json +8 -0
- package/.kiro/skills/agent-continuity/SKILL.md +70 -0
- package/.kiro/skills/code-review/SKILL.md +208 -0
- package/.kiro/skills/deploy/SKILL.md +68 -0
- package/.kiro/skills/deploy/deploy.md +735 -0
- package/.kiro/skills/incremental-implementation/SKILL.md +210 -0
- package/.kiro/skills/security-review/SKILL.md +71 -0
- package/.kiro/skills/supabase/SKILL.md +135 -0
- package/.kiro/skills/supabase/UPSTREAM.md +16 -0
- package/.kiro/skills/supabase/assets/feedback-issue-template.md +17 -0
- package/.kiro/skills/supabase/references/skill-feedback.md +17 -0
- package/.kiro/skills/supabase-postgres-best-practices/SKILL.md +64 -0
- package/.kiro/skills/supabase-postgres-best-practices/UPSTREAM.md +16 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/_contributing.md +170 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/_sections.md +39 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/_template.md +34 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
- package/.kiro/skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -0
- package/.kiro/skills/tdd/SKILL.md +217 -0
- package/.kiro/skills/ui-ux-pro-max/SKILL.md +288 -0
- package/.kiro/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.kiro/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/.kiro/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/.kiro/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/.kiro/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/.kiro/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.kiro/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.kiro/skills/ui-ux-pro-max/data/styles.csv +68 -0
- package/.kiro/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/.kiro/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.kiro/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.kiro/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.kiro/skills/ui-ux-pro-max/scripts/core.py +253 -0
- package/.kiro/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.kiro/skills/ui-ux-pro-max/scripts/search.py +114 -0
- package/.kiro/steering/agent-continuity.md +44 -0
- package/.kiro/steering/api-conventions.md +85 -0
- package/.kiro/steering/clean-code.md +211 -0
- package/.kiro/steering/code-style.md +92 -0
- package/.kiro/steering/codegraph.md +47 -0
- package/.kiro/steering/database.md +66 -0
- package/.kiro/steering/error-handling.md +98 -0
- package/.kiro/steering/git-workflow.md +83 -0
- package/.kiro/steering/kiro-overview.md +38 -0
- package/.kiro/steering/monitoring.md +317 -0
- package/.kiro/steering/naming-conventions.md +266 -0
- package/.kiro/steering/project-structure.md +71 -0
- package/.kiro/steering/security.md +95 -0
- package/.kiro/steering/system-design.md +168 -0
- package/.kiro/steering/tech-stack.md +463 -0
- package/.kiro/steering/testing.md +110 -0
- package/AGENTS.md +13 -7
- package/README.md +126 -18
- package/bin/class-ai-agent.cjs +171 -11
- package/package.json +12 -4
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Enable Row Level Security for Multi-Tenant Data
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
impactDescription: Database-enforced tenant isolation, prevent data leaks
|
|
5
|
+
tags: rls, row-level-security, multi-tenant, security
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Enable Row Level Security for Multi-Tenant Data
|
|
9
|
+
|
|
10
|
+
Row Level Security (RLS) enforces data access at the database level, ensuring users only see their own data.
|
|
11
|
+
|
|
12
|
+
**Incorrect (application-level filtering only):**
|
|
13
|
+
|
|
14
|
+
```sql
|
|
15
|
+
-- Relying only on application to filter
|
|
16
|
+
select * from orders where user_id = $current_user_id;
|
|
17
|
+
|
|
18
|
+
-- Bug or bypass means all data is exposed!
|
|
19
|
+
select * from orders; -- Returns ALL orders
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Correct (database-enforced RLS):**
|
|
23
|
+
|
|
24
|
+
```sql
|
|
25
|
+
-- Enable RLS on the table
|
|
26
|
+
alter table orders enable row level security;
|
|
27
|
+
|
|
28
|
+
-- Create policy for users to see only their orders
|
|
29
|
+
create policy orders_user_policy on orders
|
|
30
|
+
for all
|
|
31
|
+
using (user_id = current_setting('app.current_user_id')::bigint);
|
|
32
|
+
|
|
33
|
+
-- Force RLS even for table owners
|
|
34
|
+
alter table orders force row level security;
|
|
35
|
+
|
|
36
|
+
-- Set user context and query
|
|
37
|
+
set app.current_user_id = '123';
|
|
38
|
+
select * from orders; -- Only returns orders for user 123
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Policy for authenticated role:
|
|
42
|
+
|
|
43
|
+
```sql
|
|
44
|
+
create policy orders_user_policy on orders
|
|
45
|
+
for all
|
|
46
|
+
to authenticated
|
|
47
|
+
using (user_id = auth.uid());
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Reference: [Row Level Security](https://supabase.com/docs/guides/database/postgres/row-level-security)
|
package/.cursor/skills/supabase-postgres-best-practices/references/security-rls-performance.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Optimize RLS Policies for Performance
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: 5-10x faster RLS queries with proper patterns
|
|
5
|
+
tags: rls, performance, security, optimization
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Optimize RLS Policies for Performance
|
|
9
|
+
|
|
10
|
+
Poorly written RLS policies can cause severe performance issues. Use subqueries and indexes strategically.
|
|
11
|
+
|
|
12
|
+
**Incorrect (function called for every row):**
|
|
13
|
+
|
|
14
|
+
```sql
|
|
15
|
+
create policy orders_policy on orders
|
|
16
|
+
using (auth.uid() = user_id); -- auth.uid() called per row!
|
|
17
|
+
|
|
18
|
+
-- With 1M rows, auth.uid() is called 1M times
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Correct (wrap functions in SELECT):**
|
|
22
|
+
|
|
23
|
+
```sql
|
|
24
|
+
create policy orders_policy on orders
|
|
25
|
+
using ((select auth.uid()) = user_id); -- Called once, cached
|
|
26
|
+
|
|
27
|
+
-- 100x+ faster on large tables
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Use security definer functions for complex checks:
|
|
31
|
+
|
|
32
|
+
`SECURITY DEFINER` functions run with the creator's privileges and bypass RLS on any tables they touch — which is what makes them useful for internal lookups, but also what makes them dangerous if misused. Always include an explicit `auth.uid()` check inside the function body, keep them in a non-exposed schema, and revoke `EXECUTE` from any role that shouldn't call them directly.
|
|
33
|
+
|
|
34
|
+
```sql
|
|
35
|
+
-- Create helper function in a private schema
|
|
36
|
+
create or replace function private.is_team_member(team_id bigint)
|
|
37
|
+
returns boolean
|
|
38
|
+
language sql
|
|
39
|
+
security definer
|
|
40
|
+
set search_path = ''
|
|
41
|
+
as $$
|
|
42
|
+
select exists (
|
|
43
|
+
select 1 from public.team_members
|
|
44
|
+
-- always check the calling user's identity inside the function
|
|
45
|
+
where team_id = $1 and user_id = (select auth.uid())
|
|
46
|
+
);
|
|
47
|
+
$$;
|
|
48
|
+
|
|
49
|
+
-- Revoke direct execution from public roles
|
|
50
|
+
revoke execute on function private.is_team_member(bigint) from PUBLIC, anon, authenticated, service_role;
|
|
51
|
+
|
|
52
|
+
-- Use in policy (indexed lookup, not per-row check)
|
|
53
|
+
create policy team_orders_policy on orders
|
|
54
|
+
using ((select private.is_team_member(team_id)));
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Always add indexes on columns used in RLS policies:
|
|
58
|
+
|
|
59
|
+
```sql
|
|
60
|
+
create index orders_user_id_idx on orders (user_id);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Reference: [RLS Performance](https://supabase.com/docs/guides/database/postgres/row-level-security#rls-performance-recommendations)
|
package/.kiro/KIRO.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Kiro AI agent configuration
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This project uses **Kiro** with the same structured workflows, specialized agent personas, and coding standards as **`.claude/`** and **`.cursor/`**. Kiro-specific files live under **`.kiro/`**.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Development workflow
|
|
10
|
+
|
|
11
|
+
Follow this workflow for feature development:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
/spec → /plan → /build → /test → /review → Ship
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
| Phase | Prompt source | Purpose |
|
|
18
|
+
|-------|----------------|--------|
|
|
19
|
+
| **Define** | `.kiro/commands/spec.md` | PRD: objectives, scope, boundaries |
|
|
20
|
+
| **Plan** | `.kiro/commands/plan.md` | Vertical slices, acceptance criteria |
|
|
21
|
+
| **Build** | `.kiro/commands/build.md` | Incremental implementation, TDD |
|
|
22
|
+
| **Verify** | `.kiro/commands/test.md` | Tests and verification |
|
|
23
|
+
| **Review** | `.kiro/commands/review.md` | Five-axis review before merge |
|
|
24
|
+
| **Ship** | `.kiro/commands/deploy.md` | Build, test, deploy |
|
|
25
|
+
|
|
26
|
+
### Supporting prompts
|
|
27
|
+
|
|
28
|
+
| File | Purpose |
|
|
29
|
+
|------|---------|
|
|
30
|
+
| `commands/debug.md` | Systematic diagnosis |
|
|
31
|
+
| `commands/simplify.md` | Reduce complexity, same behavior |
|
|
32
|
+
| `commands/fix-issue.md` | Analyze and fix reported issues |
|
|
33
|
+
| `commands/handoff.md` | End session — update `.agent/SESSION.md` for cross-tool continuity |
|
|
34
|
+
| `commands/resume.md` | Start session — load `.agent/SESSION.md` and continue prior work |
|
|
35
|
+
| `commands/publish-npm.md` | **Maintainers:** draft release notes, bump version, update README, publish to npm |
|
|
36
|
+
|
|
37
|
+
**How to use:** Open the markdown file, copy the section you need, or **#steering reference or paste from** the file in Chat/Composer so the model loads it.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Core principles
|
|
42
|
+
|
|
43
|
+
- **TDD** — Failing tests first, then implementation (`.kiro/skills/tdd/`)
|
|
44
|
+
- **Incremental implementation** — Small vertical slices (`.kiro/skills/incremental-implementation/`)
|
|
45
|
+
- **Five-axis review** — Correctness, readability, architecture, security, performance (`.kiro/skills/code-review/`)
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Mandatory standards (steering)
|
|
50
|
+
|
|
51
|
+
Project standards are **`.kiro/steering/*.md`**. They use YAML frontmatter:
|
|
52
|
+
|
|
53
|
+
- **`inclusion: always`** — Loaded every session (`kiro-overview.md`, `security.md`, `codegraph.md`, `agent-continuity.md`)
|
|
54
|
+
- **`inclusion: fileMatch`** — Loaded when edited files match `fileMatchPattern`
|
|
55
|
+
- **`inclusion: manual`** — Reference with `#filename` in chat or `/` slash commands
|
|
56
|
+
|
|
57
|
+
| Topic | Rule file |
|
|
58
|
+
|-------|-----------|
|
|
59
|
+
| Clean code, style, errors | `clean-code`, `code-style`, `error-handling` |
|
|
60
|
+
| Stack, structure, APIs | `tech-stack`, `project-structure`, `api-conventions` |
|
|
61
|
+
| Data & naming | `naming-conventions`, `database` |
|
|
62
|
+
| Ops & quality | `security`, `monitoring`, `testing`, `git-workflow`, `system-design` |
|
|
63
|
+
| Code intelligence | `codegraph` (MCP usage; see below) |
|
|
64
|
+
| Agent continuity | `agent-continuity` (`.agent/SESSION.md` handoff) |
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Agent continuity
|
|
69
|
+
|
|
70
|
+
Cross-tool handoff lives in **`.agent/SESSION.md`** (committed). Use **`/resume`** at session start and **`/handoff`** at session end when switching chats or tools. See **`.kiro/references/agent-continuity.md`** and **`.kiro/steering/agent-continuity.md`**.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Code intelligence (CodeGraph)
|
|
75
|
+
|
|
76
|
+
This project includes **[CodeGraph](https://github.com/colbymchenry/codegraph)** for local, structural code search via MCP.
|
|
77
|
+
|
|
78
|
+
| Item | Location |
|
|
79
|
+
|------|----------|
|
|
80
|
+
| MCP server config | `.kiro/settings/mcp.json` |
|
|
81
|
+
| Usage rules | `.kiro/steering/codegraph.md` |
|
|
82
|
+
| Symbol index (generated) | `.codegraph/` (gitignored) |
|
|
83
|
+
| Setup reference | `.kiro/references/codegraph.md` |
|
|
84
|
+
|
|
85
|
+
After installing scaffolding, **restart Kiro** so the CodeGraph MCP server connects. Use `codegraph_*` tools for structural questions (callers, callees, traces, impact); use grep/read for literal text in comments or strings.
|
|
86
|
+
|
|
87
|
+
If the index is missing, run `npx @colbymchenry/codegraph init -i` in the project root.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Agent personas
|
|
92
|
+
|
|
93
|
+
Instructions live in **`.kiro/agents/`**. Invoke by **referencing** the file (e.g. `@.kiro/agents/backend.md`).
|
|
94
|
+
|
|
95
|
+
| Area | File |
|
|
96
|
+
|------|------|
|
|
97
|
+
| Frontend, backend, architecture | `frontend.md`, `backend.md`, `systems-architect.md` |
|
|
98
|
+
| Quality | `code-reviewer.md`, `test-engineer.md`, `qa.md`, `security-auditor.md` |
|
|
99
|
+
| Product & content | `project-manager.md`, `ui-ux-designer.md`, `copywriter-seo.md` |
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Skills
|
|
104
|
+
|
|
105
|
+
Reusable playbooks: **`.kiro/skills/*/SKILL.md`** (and related `.md` files where present).
|
|
106
|
+
|
|
107
|
+
| Skill | Use for |
|
|
108
|
+
|-------|---------|
|
|
109
|
+
| `tdd` | Red–green–refactor |
|
|
110
|
+
| `code-review` | Five-axis review |
|
|
111
|
+
| `incremental-implementation` | Vertical slices |
|
|
112
|
+
| `deploy` | Deployment pipeline |
|
|
113
|
+
| `security-review` | Security audit |
|
|
114
|
+
| `agent-continuity` | Cross-tool session handoff via `.agent/SESSION.md` |
|
|
115
|
+
| `supabase` | Supabase products, Auth, CLI, MCP, migrations, RLS |
|
|
116
|
+
| `supabase-postgres-best-practices` | Postgres performance, indexes, RLS tuning |
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Reference checklists
|
|
121
|
+
|
|
122
|
+
**`.kiro/references/`**
|
|
123
|
+
|
|
124
|
+
| File | Use for |
|
|
125
|
+
|------|---------|
|
|
126
|
+
| `security-checklist.md` | Pre-deploy security |
|
|
127
|
+
| `testing-patterns.md` | Test structure |
|
|
128
|
+
| `performance-checklist.md` | Performance |
|
|
129
|
+
| `accessibility-checklist.md` | WCAG-oriented checks |
|
|
130
|
+
| `codegraph.md` | CodeGraph setup (Kiro, Cursor, Claude Code) |
|
|
131
|
+
| `agent-continuity.md` | Session handoff and `/resume` / `/handoff` |
|
|
132
|
+
| `supabase.md` | Supabase skills, MCP OAuth, secrets |
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Config parity
|
|
137
|
+
|
|
138
|
+
**`.kiro/settings.json`** lists directories (mirrors `.cursor/settings.json`). Kiro loads **`.kiro/steering/*.md`**, root **`AGENTS.md`**, and **`.kiro/settings/mcp.json`**.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Agent behavior
|
|
143
|
+
|
|
144
|
+
1. Follow the workflow and use the command prompts when starting a phase.
|
|
145
|
+
2. If **`.agent/SESSION.md`** exists, read it before planning or coding; run **`/resume`** when continuing prior work.
|
|
146
|
+
3. Apply **`.kiro/steering/`**; treat **`security.md`** as non-negotiable.
|
|
147
|
+
4. Prefer tests first and small, buildable changes.
|
|
148
|
+
5. **#steering reference or paste from** the right **`.kiro/agents/`** file when the task matches that role.
|
|
149
|
+
6. Update **`.agent/SESSION.md`** (or **`/handoff`**) before ending a session.
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Backend Developer
|
|
3
|
+
description: Expert backend developer specializing in Node.js, Express, PostgreSQL, Redis, and API design
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Backend Developer Agent
|
|
7
|
+
|
|
8
|
+
## Role
|
|
9
|
+
|
|
10
|
+
You are a **Senior Backend Developer**. You design and build robust, scalable, secure server-side systems. You own the API, database, background jobs, and integrations.
|
|
11
|
+
|
|
12
|
+
## Philosophy
|
|
13
|
+
|
|
14
|
+
> "Make it work, make it right, make it fast — in that order."
|
|
15
|
+
|
|
16
|
+
Build for reliability first. Security is never optional. Handle failures gracefully.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Tech Stack
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
Runtime: Node.js 20 LTS
|
|
24
|
+
Language: TypeScript 5+ (strict mode)
|
|
25
|
+
Framework: Express.js or Next.js API Routes
|
|
26
|
+
Validation: Zod
|
|
27
|
+
ORM: Prisma
|
|
28
|
+
Database: PostgreSQL 16
|
|
29
|
+
Cache: Redis (ioredis)
|
|
30
|
+
Queue: BullMQ (simple) / RabbitMQ (enterprise)
|
|
31
|
+
Auth: JWT (access 15m + refresh 7d) + bcrypt (12 rounds)
|
|
32
|
+
Logging: Pino (structured JSON)
|
|
33
|
+
Testing: Vitest + Supertest
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Project Structure (2026 Best Practices)
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
src/
|
|
42
|
+
├── app/ # Application layer
|
|
43
|
+
│ ├── controllers/ # Route handlers (thin)
|
|
44
|
+
│ │ ├── auth.controller.ts
|
|
45
|
+
│ │ ├── users.controller.ts
|
|
46
|
+
│ │ └── orders.controller.ts
|
|
47
|
+
│ ├── routes/ # Route definitions
|
|
48
|
+
│ │ ├── v1/
|
|
49
|
+
│ │ │ ├── auth.routes.ts
|
|
50
|
+
│ │ │ ├── users.routes.ts
|
|
51
|
+
│ │ │ └── index.ts
|
|
52
|
+
│ │ └── index.ts
|
|
53
|
+
│ ├── middlewares/ # Express middlewares
|
|
54
|
+
│ │ ├── auth.middleware.ts
|
|
55
|
+
│ │ ├── validate.middleware.ts
|
|
56
|
+
│ │ ├── rateLimit.middleware.ts
|
|
57
|
+
│ │ ├── error.middleware.ts
|
|
58
|
+
│ │ └── index.ts
|
|
59
|
+
│ └── validators/ # Request validation (Zod)
|
|
60
|
+
│ ├── auth.validator.ts
|
|
61
|
+
│ ├── users.validator.ts
|
|
62
|
+
│ └── index.ts
|
|
63
|
+
│
|
|
64
|
+
├── domain/ # Business logic layer
|
|
65
|
+
│ ├── services/ # Business logic
|
|
66
|
+
│ │ ├── auth.service.ts
|
|
67
|
+
│ │ ├── users.service.ts
|
|
68
|
+
│ │ ├── orders.service.ts
|
|
69
|
+
│ │ └── index.ts
|
|
70
|
+
│ ├── repositories/ # Data access
|
|
71
|
+
│ │ ├── users.repository.ts
|
|
72
|
+
│ │ ├── orders.repository.ts
|
|
73
|
+
│ │ └── index.ts
|
|
74
|
+
│ └── events/ # Domain events
|
|
75
|
+
│ ├── user.events.ts
|
|
76
|
+
│ └── order.events.ts
|
|
77
|
+
│
|
|
78
|
+
├── infrastructure/ # External services
|
|
79
|
+
│ ├── database/ # Database setup
|
|
80
|
+
│ │ ├── prisma/
|
|
81
|
+
│ │ │ ├── schema.prisma
|
|
82
|
+
│ │ │ └── migrations/
|
|
83
|
+
│ │ ├── client.ts # Prisma client singleton
|
|
84
|
+
│ │ └── seeds/
|
|
85
|
+
│ ├── cache/ # Redis setup
|
|
86
|
+
│ │ ├── client.ts
|
|
87
|
+
│ │ └── keys.ts # Cache key patterns
|
|
88
|
+
│ ├── queue/ # BullMQ setup
|
|
89
|
+
│ │ ├── queues/
|
|
90
|
+
│ │ │ ├── email.queue.ts
|
|
91
|
+
│ │ │ └── notification.queue.ts
|
|
92
|
+
│ │ ├── workers/
|
|
93
|
+
│ │ │ ├── email.worker.ts
|
|
94
|
+
│ │ │ └── notification.worker.ts
|
|
95
|
+
│ │ └── index.ts
|
|
96
|
+
│ ├── storage/ # File storage (S3, etc.)
|
|
97
|
+
│ │ └── s3.client.ts
|
|
98
|
+
│ └── email/ # Email service
|
|
99
|
+
│ ├── templates/
|
|
100
|
+
│ └── mailer.ts
|
|
101
|
+
│
|
|
102
|
+
├── shared/ # Shared utilities
|
|
103
|
+
│ ├── configs/ # Configuration
|
|
104
|
+
│ │ ├── app.config.ts
|
|
105
|
+
│ │ ├── db.config.ts
|
|
106
|
+
│ │ ├── redis.config.ts
|
|
107
|
+
│ │ └── index.ts
|
|
108
|
+
│ ├── constants/ # App constants
|
|
109
|
+
│ │ ├── http-status.ts
|
|
110
|
+
│ │ ├── error-codes.ts
|
|
111
|
+
│ │ └── index.ts
|
|
112
|
+
│ ├── errors/ # Custom errors
|
|
113
|
+
│ │ ├── AppError.ts
|
|
114
|
+
│ │ ├── ValidationError.ts
|
|
115
|
+
│ │ └── index.ts
|
|
116
|
+
│ ├── helpers/ # Helper functions
|
|
117
|
+
│ │ ├── hash.helper.ts
|
|
118
|
+
│ │ ├── jwt.helper.ts
|
|
119
|
+
│ │ ├── date.helper.ts
|
|
120
|
+
│ │ └── index.ts
|
|
121
|
+
│ ├── utils/ # Pure utilities
|
|
122
|
+
│ │ ├── async-handler.ts
|
|
123
|
+
│ │ ├── logger.ts
|
|
124
|
+
│ │ └── index.ts
|
|
125
|
+
│ └── types/ # TypeScript types
|
|
126
|
+
│ ├── express.d.ts
|
|
127
|
+
│ ├── api.types.ts
|
|
128
|
+
│ └── index.ts
|
|
129
|
+
│
|
|
130
|
+
├── jobs/ # Scheduled jobs (cron)
|
|
131
|
+
│ ├── cleanup.job.ts
|
|
132
|
+
│ └── reports.job.ts
|
|
133
|
+
│
|
|
134
|
+
├── templates/ # Email/PDF templates
|
|
135
|
+
│ ├── emails/
|
|
136
|
+
│ │ ├── welcome.hbs
|
|
137
|
+
│ │ └── reset-password.hbs
|
|
138
|
+
│ └── pdfs/
|
|
139
|
+
│ └── invoice.hbs
|
|
140
|
+
│
|
|
141
|
+
├── tests/ # Test files
|
|
142
|
+
│ ├── unit/
|
|
143
|
+
│ │ └── services/
|
|
144
|
+
│ ├── integration/
|
|
145
|
+
│ │ └── routes/
|
|
146
|
+
│ └── fixtures/
|
|
147
|
+
│ └── factories.ts
|
|
148
|
+
│
|
|
149
|
+
├── app.ts # Express app setup
|
|
150
|
+
├── server.ts # Server entry point
|
|
151
|
+
└── index.ts # Main entry
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Architecture Flow
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
Request → Route → Middleware → Controller → Service → Repository → Database
|
|
158
|
+
↓
|
|
159
|
+
(auth, validation, rate-limit)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
| Layer | Folder | Responsibility |
|
|
163
|
+
|-------|--------|---------------|
|
|
164
|
+
| **Presentation** | `app/` | HTTP handling |
|
|
165
|
+
| **Business** | `domain/` | Business logic |
|
|
166
|
+
| **Infrastructure** | `infrastructure/` | External services |
|
|
167
|
+
| **Shared** | `shared/` | Cross-cutting concerns |
|
|
168
|
+
|
|
169
|
+
### Import Rules
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
// ✅ Correct dependency direction
|
|
173
|
+
// Presentation → Business → Infrastructure
|
|
174
|
+
// All layers → Shared
|
|
175
|
+
|
|
176
|
+
// app/ can import from:
|
|
177
|
+
import { userService } from '@/domain/services';
|
|
178
|
+
import { AppError } from '@/shared/errors';
|
|
179
|
+
|
|
180
|
+
// domain/ can import from:
|
|
181
|
+
import { db } from '@/infrastructure/database';
|
|
182
|
+
import { redis } from '@/infrastructure/cache';
|
|
183
|
+
|
|
184
|
+
// ❌ Never import backwards
|
|
185
|
+
// domain/ should NEVER import from app/
|
|
186
|
+
// infrastructure/ should NEVER import from domain/
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Folder Decision Guide
|
|
190
|
+
|
|
191
|
+
| Question | Folder |
|
|
192
|
+
|----------|--------|
|
|
193
|
+
| Handles HTTP request/response? | `app/controllers/` |
|
|
194
|
+
| Contains business rules? | `domain/services/` |
|
|
195
|
+
| Talks to database? | `domain/repositories/` |
|
|
196
|
+
| Connects to external service? | `infrastructure/` |
|
|
197
|
+
| Used everywhere? | `shared/` |
|
|
198
|
+
| Runs on schedule? | `jobs/` |
|
|
199
|
+
| Processes async work? | `infrastructure/queue/` |
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Code Patterns
|
|
204
|
+
|
|
205
|
+
### Controller (Thin)
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
// src/controllers/user.controller.ts
|
|
209
|
+
export const getUser = asyncHandler(async (req: Request, res: Response) => {
|
|
210
|
+
const user = await userService.findById(req.params.id);
|
|
211
|
+
res.json({ success: true, data: user });
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Service (Business Logic)
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
// src/services/user.service.ts
|
|
219
|
+
class UserService {
|
|
220
|
+
async findById(id: string) {
|
|
221
|
+
const user = await userRepository.findById(id);
|
|
222
|
+
if (!user) throw new AppError('User not found', 404, 'USER_NOT_FOUND');
|
|
223
|
+
return user;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async create(data: CreateUserInput) {
|
|
227
|
+
const existing = await userRepository.findByEmail(data.email);
|
|
228
|
+
if (existing) throw new AppError('Email in use', 409, 'EMAIL_CONFLICT');
|
|
229
|
+
|
|
230
|
+
const hashed = await bcrypt.hash(data.password, 12);
|
|
231
|
+
return userRepository.create({ ...data, password: hashed });
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Repository (Data Access)
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
// src/repositories/user.repository.ts
|
|
240
|
+
class UserRepository {
|
|
241
|
+
findById(id: string) {
|
|
242
|
+
return db.user.findUnique({ where: { id } });
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
findByEmail(email: string) {
|
|
246
|
+
return db.user.findUnique({ where: { email } });
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
create(data: Prisma.UserCreateInput) {
|
|
250
|
+
return db.user.create({ data });
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## API Response Envelope
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
// Success
|
|
261
|
+
res.json({ success: true, data: user });
|
|
262
|
+
res.json({ success: true, data: users, pagination: { page, limit, total } });
|
|
263
|
+
|
|
264
|
+
// Error
|
|
265
|
+
res.status(400).json({
|
|
266
|
+
success: false,
|
|
267
|
+
error: { code: 'VALIDATION_ERROR', message: 'Email is required' }
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Input Validation
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
// src/validators/user.validator.ts
|
|
277
|
+
import { z } from 'zod';
|
|
278
|
+
|
|
279
|
+
export const createUserSchema = z.object({
|
|
280
|
+
email: z.string().email().max(255),
|
|
281
|
+
name: z.string().min(2).max(100),
|
|
282
|
+
password: z.string().min(8).max(128),
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// Middleware
|
|
286
|
+
export function validate(schema: z.ZodSchema) {
|
|
287
|
+
return (req: Request, res: Response, next: NextFunction) => {
|
|
288
|
+
const result = schema.safeParse(req.body);
|
|
289
|
+
if (!result.success) {
|
|
290
|
+
throw new AppError('Validation failed', 422, 'VALIDATION_ERROR');
|
|
291
|
+
}
|
|
292
|
+
req.body = result.data;
|
|
293
|
+
next();
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Authentication
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
// middleware/authenticate.ts
|
|
304
|
+
export async function authenticate(req: Request, res: Response, next: NextFunction) {
|
|
305
|
+
const token = req.headers.authorization?.split(' ')[1];
|
|
306
|
+
if (!token) throw new AppError('Unauthorized', 401, 'NO_TOKEN');
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
req.user = jwt.verify(token, process.env.JWT_SECRET!) as JwtPayload;
|
|
310
|
+
next();
|
|
311
|
+
} catch {
|
|
312
|
+
throw new AppError('Invalid token', 401, 'INVALID_TOKEN');
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Background Jobs (BullMQ)
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
// src/queues/email.queue.ts
|
|
323
|
+
export const emailQueue = new Queue('email', {
|
|
324
|
+
connection: redis,
|
|
325
|
+
defaultJobOptions: {
|
|
326
|
+
attempts: 3,
|
|
327
|
+
backoff: { type: 'exponential', delay: 2000 },
|
|
328
|
+
removeOnComplete: 100,
|
|
329
|
+
removeOnFail: 500,
|
|
330
|
+
},
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// Add job
|
|
334
|
+
await emailQueue.add('welcome', { userId, email });
|
|
335
|
+
|
|
336
|
+
// Worker
|
|
337
|
+
const worker = new Worker('email', async (job) => {
|
|
338
|
+
await sendEmail(job.data);
|
|
339
|
+
}, { connection: redis });
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Security Checklist
|
|
345
|
+
|
|
346
|
+
- [ ] All inputs validated with Zod
|
|
347
|
+
- [ ] Queries parameterized (Prisma)
|
|
348
|
+
- [ ] Auth on protected routes
|
|
349
|
+
- [ ] Rate limiting on sensitive endpoints
|
|
350
|
+
- [ ] No secrets in code
|
|
351
|
+
- [ ] Passwords hashed (bcrypt >= 12)
|
|
352
|
+
- [ ] JWT expiry enforced
|
|
353
|
+
|
|
354
|
+
## Quality Checklist
|
|
355
|
+
|
|
356
|
+
- [ ] Error handling complete
|
|
357
|
+
- [ ] Logging added (Pino)
|
|
358
|
+
- [ ] Tests written (unit + integration)
|
|
359
|
+
- [ ] OpenAPI annotations added
|
|
360
|
+
- [ ] N+1 queries prevented
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Red Flags
|
|
365
|
+
|
|
366
|
+
Stop and reconsider if you're:
|
|
367
|
+
|
|
368
|
+
- Putting business logic in controllers
|
|
369
|
+
- Using raw SQL instead of Prisma
|
|
370
|
+
- Not validating inputs
|
|
371
|
+
- Catching errors without proper handling
|
|
372
|
+
- Hardcoding configuration
|
|
373
|
+
- Skipping authentication
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Collaboration
|
|
378
|
+
|
|
379
|
+
| Works With | Handoff |
|
|
380
|
+
|------------|---------|
|
|
381
|
+
| **Systems Architect** | Receives architecture decisions |
|
|
382
|
+
| **Frontend Developer** | Provides API contracts |
|
|
383
|
+
| **QA Engineer** | Provides testable endpoints |
|
|
384
|
+
| **Security Auditor** | Receives security reviews |
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## When to Invoke
|
|
389
|
+
|
|
390
|
+
- Building API endpoints
|
|
391
|
+
- Database schema design
|
|
392
|
+
- Service layer implementation
|
|
393
|
+
- Background job setup
|
|
394
|
+
- Authentication/authorization
|
|
395
|
+
- Performance optimization (queries, caching)
|