@neyugn/agent-kits 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +514 -0
  3. package/README.vi.md +410 -0
  4. package/README.zh.md +410 -0
  5. package/dist/cli.d.ts +1 -0
  6. package/dist/cli.js +422 -0
  7. package/kits/coder/ARCHITECTURE.md +289 -0
  8. package/kits/coder/agents/ai-engineer.md +344 -0
  9. package/kits/coder/agents/backend-specialist.md +270 -0
  10. package/kits/coder/agents/cloud-architect.md +363 -0
  11. package/kits/coder/agents/code-reviewer.md +284 -0
  12. package/kits/coder/agents/data-engineer.md +401 -0
  13. package/kits/coder/agents/database-specialist.md +251 -0
  14. package/kits/coder/agents/debugger.md +209 -0
  15. package/kits/coder/agents/devops-engineer.md +281 -0
  16. package/kits/coder/agents/documentation-writer.md +296 -0
  17. package/kits/coder/agents/frontend-specialist.md +298 -0
  18. package/kits/coder/agents/i18n-specialist.md +348 -0
  19. package/kits/coder/agents/integration-specialist.md +314 -0
  20. package/kits/coder/agents/mobile-developer.md +271 -0
  21. package/kits/coder/agents/multi-tenant-architect.md +281 -0
  22. package/kits/coder/agents/orchestrator.md +263 -0
  23. package/kits/coder/agents/performance-analyst.md +327 -0
  24. package/kits/coder/agents/project-planner.md +277 -0
  25. package/kits/coder/agents/queue-specialist.md +282 -0
  26. package/kits/coder/agents/realtime-specialist.md +267 -0
  27. package/kits/coder/agents/security-auditor.md +253 -0
  28. package/kits/coder/agents/test-engineer.md +315 -0
  29. package/kits/coder/agents/ux-researcher.md +388 -0
  30. package/kits/coder/rules/.cursorrules +287 -0
  31. package/kits/coder/rules/CLAUDE.md +287 -0
  32. package/kits/coder/rules/CODEX.md +287 -0
  33. package/kits/coder/rules/GEMINI.md +287 -0
  34. package/kits/coder/scripts/checklist.py +318 -0
  35. package/kits/coder/scripts/kit_status.py +292 -0
  36. package/kits/coder/scripts/skills_manager.py +243 -0
  37. package/kits/coder/scripts/verify_all.py +391 -0
  38. package/kits/coder/skills/accessibility-patterns/SKILL.md +372 -0
  39. package/kits/coder/skills/accessibility-patterns/scripts/a11y_checker.py +211 -0
  40. package/kits/coder/skills/ai-rag-patterns/SKILL.md +444 -0
  41. package/kits/coder/skills/api-patterns/SKILL.md +316 -0
  42. package/kits/coder/skills/api-patterns/assets/.gitkeep +1 -0
  43. package/kits/coder/skills/api-patterns/references/deep-dive.md +21 -0
  44. package/kits/coder/skills/api-patterns/scripts/api_validator.py +253 -0
  45. package/kits/coder/skills/api-patterns/scripts/validate.py +56 -0
  46. package/kits/coder/skills/auth-patterns/SKILL.md +267 -0
  47. package/kits/coder/skills/aws-patterns/SKILL.md +576 -0
  48. package/kits/coder/skills/brainstorming/SKILL.md +370 -0
  49. package/kits/coder/skills/brainstorming/assets/.gitkeep +1 -0
  50. package/kits/coder/skills/brainstorming/references/deep-dive.md +21 -0
  51. package/kits/coder/skills/brainstorming/scripts/validate.py +56 -0
  52. package/kits/coder/skills/clean-code/SKILL.md +240 -0
  53. package/kits/coder/skills/clean-code/assets/.gitkeep +1 -0
  54. package/kits/coder/skills/clean-code/references/deep-dive.md +21 -0
  55. package/kits/coder/skills/clean-code/scripts/lint_runner.py +186 -0
  56. package/kits/coder/skills/clean-code/scripts/validate.py +56 -0
  57. package/kits/coder/skills/database-design/SKILL.md +255 -0
  58. package/kits/coder/skills/database-design/assets/.gitkeep +1 -0
  59. package/kits/coder/skills/database-design/references/deep-dive.md +21 -0
  60. package/kits/coder/skills/database-design/scripts/schema_validator.py +272 -0
  61. package/kits/coder/skills/database-design/scripts/validate.py +56 -0
  62. package/kits/coder/skills/docker-patterns/SKILL.md +240 -0
  63. package/kits/coder/skills/documentation-templates/SKILL.md +441 -0
  64. package/kits/coder/skills/e2e-testing/SKILL.md +457 -0
  65. package/kits/coder/skills/flutter-patterns/SKILL.md +330 -0
  66. package/kits/coder/skills/frontend-design/SKILL.md +127 -0
  67. package/kits/coder/skills/github-actions/SKILL.md +349 -0
  68. package/kits/coder/skills/gitlab-ci-patterns/SKILL.md +466 -0
  69. package/kits/coder/skills/graphql-patterns/SKILL.md +558 -0
  70. package/kits/coder/skills/i18n-localization/SKILL.md +345 -0
  71. package/kits/coder/skills/i18n-localization/scripts/i18n_checker.py +267 -0
  72. package/kits/coder/skills/kubernetes-patterns/SKILL.md +357 -0
  73. package/kits/coder/skills/mermaid-diagrams/SKILL.md +351 -0
  74. package/kits/coder/skills/mobile-design/SKILL.md +305 -0
  75. package/kits/coder/skills/monitoring-observability/SKILL.md +458 -0
  76. package/kits/coder/skills/multi-tenancy/SKILL.md +317 -0
  77. package/kits/coder/skills/multi-tenancy/assets/.gitkeep +1 -0
  78. package/kits/coder/skills/multi-tenancy/references/deep-dive.md +21 -0
  79. package/kits/coder/skills/multi-tenancy/scripts/validate.py +56 -0
  80. package/kits/coder/skills/nodejs-best-practices/SKILL.md +220 -0
  81. package/kits/coder/skills/performance-profiling/SKILL.md +333 -0
  82. package/kits/coder/skills/performance-profiling/assets/.gitkeep +1 -0
  83. package/kits/coder/skills/performance-profiling/references/deep-dive.md +21 -0
  84. package/kits/coder/skills/performance-profiling/scripts/validate.py +56 -0
  85. package/kits/coder/skills/plan-writing/SKILL.md +360 -0
  86. package/kits/coder/skills/plan-writing/assets/.gitkeep +1 -0
  87. package/kits/coder/skills/plan-writing/references/deep-dive.md +21 -0
  88. package/kits/coder/skills/plan-writing/scripts/validate.py +56 -0
  89. package/kits/coder/skills/postgres-patterns/SKILL.md +361 -0
  90. package/kits/coder/skills/prompt-engineering/SKILL.md +277 -0
  91. package/kits/coder/skills/queue-patterns/SKILL.md +359 -0
  92. package/kits/coder/skills/queue-patterns/assets/.gitkeep +1 -0
  93. package/kits/coder/skills/queue-patterns/references/deep-dive.md +21 -0
  94. package/kits/coder/skills/queue-patterns/scripts/validate.py +56 -0
  95. package/kits/coder/skills/react-native-patterns/SKILL.md +393 -0
  96. package/kits/coder/skills/react-patterns/SKILL.md +319 -0
  97. package/kits/coder/skills/realtime-patterns/SKILL.md +506 -0
  98. package/kits/coder/skills/realtime-patterns/assets/.gitkeep +1 -0
  99. package/kits/coder/skills/realtime-patterns/references/deep-dive.md +21 -0
  100. package/kits/coder/skills/realtime-patterns/scripts/validate.py +56 -0
  101. package/kits/coder/skills/redis-patterns/SKILL.md +484 -0
  102. package/kits/coder/skills/security-fundamentals/SKILL.md +363 -0
  103. package/kits/coder/skills/security-fundamentals/assets/.gitkeep +1 -0
  104. package/kits/coder/skills/security-fundamentals/references/deep-dive.md +21 -0
  105. package/kits/coder/skills/security-fundamentals/scripts/security_scan.py +326 -0
  106. package/kits/coder/skills/security-fundamentals/scripts/validate.py +56 -0
  107. package/kits/coder/skills/seo-patterns/SKILL.md +262 -0
  108. package/kits/coder/skills/seo-patterns/scripts/seo_checker.py +211 -0
  109. package/kits/coder/skills/systematic-debugging/SKILL.md +478 -0
  110. package/kits/coder/skills/systematic-debugging/assets/.gitkeep +1 -0
  111. package/kits/coder/skills/systematic-debugging/references/deep-dive.md +21 -0
  112. package/kits/coder/skills/systematic-debugging/scripts/validate.py +56 -0
  113. package/kits/coder/skills/tailwind-patterns/SKILL.md +395 -0
  114. package/kits/coder/skills/terraform-patterns/SKILL.md +470 -0
  115. package/kits/coder/skills/testing-patterns/SKILL.md +285 -0
  116. package/kits/coder/skills/testing-patterns/assets/.gitkeep +1 -0
  117. package/kits/coder/skills/testing-patterns/references/deep-dive.md +21 -0
  118. package/kits/coder/skills/testing-patterns/scripts/test_runner.py +219 -0
  119. package/kits/coder/skills/testing-patterns/scripts/validate.py +56 -0
  120. package/kits/coder/skills/typescript-patterns/SKILL.md +417 -0
  121. package/kits/coder/skills/ui-ux-pro-max/SKILL.md +364 -0
  122. package/kits/coder/skills/ui-ux-pro-max/data/charts.csv +26 -0
  123. package/kits/coder/skills/ui-ux-pro-max/data/colors.csv +97 -0
  124. package/kits/coder/skills/ui-ux-pro-max/data/icons.csv +101 -0
  125. package/kits/coder/skills/ui-ux-pro-max/data/landing.csv +31 -0
  126. package/kits/coder/skills/ui-ux-pro-max/data/products.csv +97 -0
  127. package/kits/coder/skills/ui-ux-pro-max/data/prompts.csv +24 -0
  128. package/kits/coder/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  129. package/kits/coder/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  130. package/kits/coder/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  131. package/kits/coder/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  132. package/kits/coder/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  133. package/kits/coder/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  134. package/kits/coder/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  135. package/kits/coder/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  136. package/kits/coder/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  137. package/kits/coder/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  138. package/kits/coder/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  139. package/kits/coder/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  140. package/kits/coder/skills/ui-ux-pro-max/data/styles.csv +59 -0
  141. package/kits/coder/skills/ui-ux-pro-max/data/typography.csv +58 -0
  142. package/kits/coder/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  143. package/kits/coder/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  144. package/kits/coder/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  145. package/kits/coder/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-314.pyc +0 -0
  146. package/kits/coder/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-314.pyc +0 -0
  147. package/kits/coder/skills/ui-ux-pro-max/scripts/core.py +257 -0
  148. package/kits/coder/skills/ui-ux-pro-max/scripts/design_system.py +488 -0
  149. package/kits/coder/skills/ui-ux-pro-max/scripts/search.py +76 -0
  150. package/kits/coder/workflows/.gitkeep +20 -0
  151. package/kits/coder/workflows/create.md +152 -0
  152. package/kits/coder/workflows/debug.md +223 -0
  153. package/kits/coder/workflows/deploy.md +283 -0
  154. package/kits/coder/workflows/orchestrate.md +243 -0
  155. package/kits/coder/workflows/plan.md +134 -0
  156. package/kits/coder/workflows/test.md +237 -0
  157. package/kits/coder/workflows/ui-ux-pro-max.md +109 -0
  158. package/package.json +49 -0
@@ -0,0 +1,317 @@
1
+ ---
2
+ name: multi-tenancy
3
+ description: Multi-tenant architecture principles and decision-making. Use when designing tenant isolation, data partitioning, context propagation, or building SaaS applications. Covers database strategies, resource isolation, and compliance patterns.
4
+ version: 1.0.0
5
+ tags: [architecture, saas, isolation, tenancy, compliance]
6
+ ---
7
+
8
+ # Multi-Tenancy - SaaS Architecture Skill
9
+
10
+ > **Purpose:** Enable AI agents to design and implement robust multi-tenant systems with proper isolation, context propagation, and scalability.
11
+
12
+ ---
13
+
14
+ ## 📑 Navigation
15
+
16
+ - [Philosophy](#-philosophy)
17
+ - [Isolation Strategies](#-isolation-strategies)
18
+ - [Context Propagation](#-context-propagation)
19
+ - [Decision Frameworks](#-decision-frameworks)
20
+ - [Anti-Patterns](#-anti-patterns)
21
+ - [Checklist](#-implementation-checklist)
22
+
23
+ ---
24
+
25
+ ## 💡 Philosophy
26
+
27
+ > **"Multi-tenancy is trust architecture—design for distrust, verify always."**
28
+
29
+ | Principle | Implementation |
30
+ | -------------------------- | -------------------------------------------- |
31
+ | **Defense in Depth** | Multiple isolation layers (app + DB + infra) |
32
+ | **Context Everywhere** | Tenant ID flows through every layer |
33
+ | **Fail Closed** | Missing tenant context = deny access |
34
+ | **Explicit Over Implicit** | Never infer tenant, always verify |
35
+ | **Audit Everything** | Log all cross-boundary access |
36
+
37
+ ---
38
+
39
+ ## 🔄 ISOLATION STRATEGIES
40
+
41
+ ### Database Isolation Spectrum
42
+
43
+ | Strategy | Isolation | Cost | Complexity | When to Use |
44
+ | --------------------- | --------- | ------ | ---------- | ------------------------------------------- |
45
+ | **Shared DB + RLS** | Medium | Low | Low | Startups, <100 tenants, cost-sensitive |
46
+ | **Schema-per-Tenant** | High | Medium | Medium | 100-1000 tenants, moderate compliance |
47
+ | **DB-per-Tenant** | Highest | High | High | Enterprise, HIPAA/Financial, data residency |
48
+
49
+ ### Row-Level Security (RLS) Pattern
50
+
51
+ ```sql
52
+ -- 1. Enable RLS on tenant tables
53
+ ALTER TABLE conversations ENABLE ROW LEVEL SECURITY;
54
+ ALTER TABLE messages ENABLE ROW LEVEL SECURITY;
55
+ ALTER TABLE users ENABLE ROW LEVEL SECURITY;
56
+
57
+ -- 2. Create isolation policy
58
+ CREATE POLICY tenant_isolation ON conversations
59
+ FOR ALL
60
+ USING (tenant_id = current_setting('app.tenant_id')::uuid);
61
+
62
+ -- 3. Set context at connection start
63
+ SET app.tenant_id = 'tenant-uuid-here';
64
+ ```
65
+
66
+ ### Schema-per-Tenant Pattern
67
+
68
+ ```
69
+ Database: app_db
70
+ ├── tenant_acme/ # Schema for ACME Corp
71
+ │ ├── users
72
+ │ ├── conversations
73
+ │ └── ...
74
+ ├── tenant_globex/ # Schema for Globex Inc
75
+ │ ├── users
76
+ │ ├── conversations
77
+ │ └── ...
78
+ └── public/ # Shared lookup tables
79
+ ├── plans
80
+ └── features
81
+ ```
82
+
83
+ ### DB-per-Tenant Pattern
84
+
85
+ ```
86
+ Master Database (shared)
87
+ ├── tenants # Tenant registry
88
+ │ ├── id, name, slug
89
+ │ ├── db_connection_string
90
+ │ └── redis_db_index
91
+ └── plans
92
+
93
+ Tenant Databases (isolated)
94
+ ├── acme_db # Full isolation
95
+ ├── globex_db # Full isolation
96
+ └── ...
97
+ ```
98
+
99
+ ---
100
+
101
+ ## 🔀 CONTEXT PROPAGATION
102
+
103
+ ### Request Lifecycle
104
+
105
+ ```
106
+ ┌─────────────────────────────────────────────────────────┐
107
+ │ 1. TENANT RESOLUTION (Middleware) │
108
+ ├─────────────────────────────────────────────────────────┤
109
+ │ Extract from: subdomain | header | JWT claim | path │
110
+ │ Validate: tenant exists & active │
111
+ │ Cache: Redis TTL 5-15 mins │
112
+ │ Attach: to request-scoped context │
113
+ └─────────────────────────────────────────────────────────┘
114
+
115
+
116
+ ┌─────────────────────────────────────────────────────────┐
117
+ │ 2. REQUEST-SCOPED CONTEXT │
118
+ ├─────────────────────────────────────────────────────────┤
119
+ │ context = { │
120
+ │ tenantId: "acme", │
121
+ │ tenantConfig: { features, limits, dbPool }, │
122
+ │ userId: "user123", │
123
+ │ requestId: "req-uuid" │
124
+ │ } │
125
+ └─────────────────────────────────────────────────────────┘
126
+
127
+
128
+ ┌─────────────────────────────────────────────────────────┐
129
+ │ 3. SERVICE LAYER (Tenant-Aware) │
130
+ ├─────────────────────────────────────────────────────────┤
131
+ │ All queries automatically filtered by tenant_id │
132
+ │ Repository base class includes tenant filter │
133
+ └─────────────────────────────────────────────────────────┘
134
+ ```
135
+
136
+ ### Context Technologies by Platform
137
+
138
+ | Platform | Mechanism | Pattern |
139
+ | --------------- | ----------------------------- | ------------------------- |
140
+ | **Node.js** | `AsyncLocalStorage` | Thread-safe async context |
141
+ | **Python** | `contextvars` | Async context manager |
142
+ | **Java/Spring** | `ThreadLocal` + Request scope | Bean scoping |
143
+ | **.NET** | `AsyncLocal<T>` | Async flow context |
144
+ | **Go** | `context.Context` | Explicit propagation |
145
+
146
+ ### Background Job Context
147
+
148
+ ```typescript
149
+ // ❌ WRONG: Context lost in background job
150
+ queue.add("sendEmail", { userId, templateId });
151
+
152
+ // ✅ CORRECT: Tenant context preserved
153
+ queue.add("sendEmail", {
154
+ tenantId, // ALWAYS include
155
+ userId,
156
+ templateId,
157
+ correlationId, // For tracing
158
+ });
159
+
160
+ // Job processor
161
+ async function processJob(job) {
162
+ const { tenantId, ...data } = job.data;
163
+ await setTenantContext(tenantId); // Restore context
164
+ // Process with tenant context...
165
+ }
166
+ ```
167
+
168
+ ---
169
+
170
+ ## 🧭 DECISION FRAMEWORKS
171
+
172
+ ### Isolation Level Decision Tree
173
+
174
+ ```
175
+ START
176
+
177
+
178
+ ┌──────────────────────────┐
179
+ │ Compliance Requirements? │
180
+ │ (HIPAA, PCIDSS, SOC2) │
181
+ └──────────────────────────┘
182
+
183
+ ├── Yes → DB-per-Tenant + Dedicated Compute
184
+
185
+
186
+ ┌──────────────────────────┐
187
+ │ Enterprise Customers? │
188
+ │ (Paying for isolation) │
189
+ └──────────────────────────┘
190
+
191
+ ├── Yes → Hybrid (Shared for SMB, Dedicated for Enterprise)
192
+
193
+
194
+ ┌──────────────────────────┐
195
+ │ Expected Tenant Count? │
196
+ └──────────────────────────┘
197
+
198
+ ├── <100 → Shared DB + RLS
199
+ ├── 100-1000 → Schema-per-Tenant
200
+ └── >1000 → Shared DB + RLS + Good Sharding
201
+ ```
202
+
203
+ ### Resource Isolation Matrix
204
+
205
+ | Resource | Shared Strategy | Isolated Strategy |
206
+ | -------------- | ------------------------- | -------------------- |
207
+ | **Database** | RLS + tenant_id column | DB-per-tenant |
208
+ | **Redis** | Key prefix `{tenant}:` | DB index per tenant |
209
+ | **S3/Storage** | Prefix `tenants/{id}/` | Bucket per tenant |
210
+ | **Queue** | tenant_id in job data | Queue per tenant |
211
+ | **WebSocket** | Room prefix `tenant:{id}` | Namespace per tenant |
212
+
213
+ ### Tenant Identification Priority
214
+
215
+ | Method | Security | When to Use |
216
+ | ----------------- | -------- | -------------------------------- |
217
+ | **JWT Claim** | High | API calls with auth |
218
+ | **Subdomain** | High | `acme.app.com` |
219
+ | **Custom Header** | Medium | Internal services, microservices |
220
+ | **Path Segment** | Low | `/api/tenants/{id}/...` (avoid) |
221
+ | **Query Param** | Very Low | Never use for tenant ID |
222
+
223
+ ---
224
+
225
+ ## ❌ ANTI-PATTERNS
226
+
227
+ ### Critical Mistakes
228
+
229
+ | Anti-Pattern | Risk | Correct Approach |
230
+ | --------------------------------- | ---------------------------------- | --------------------------------------------- |
231
+ | **Trust client tenant ID** | Data breach | Validate from auth token/subdomain |
232
+ | **No RLS on shared tables** | SQL injection → full DB exposure | Enable RLS as defense in depth |
233
+ | **Global cache without prefix** | Cross-tenant data leakage | Always prefix: `{tenant}:{key}` |
234
+ | **Background job without tenant** | Orphaned operations, wrong context | Include tenant_id in EVERY job |
235
+ | **Single connection pool** | Noisy neighbor, unclear isolation | Pool per tenant or connection tagging |
236
+ | **Tenant ID in URL path** | Tampering risk | Subdomain or header (cleaner, safer) |
237
+ | **No audit logging** | Cannot detect breaches | Log all cross-boundary access |
238
+ | **Skipping context in async** | Context lost in callbacks | Use AsyncLocalStorage or explicit propagation |
239
+
240
+ ### Code Smells
241
+
242
+ ```typescript
243
+ // ❌ SMELL: Direct query without tenant filter
244
+ const users = await db.query("SELECT * FROM users");
245
+
246
+ // ✅ CORRECT: Always include tenant filter
247
+ const users = await db.query("SELECT * FROM users WHERE tenant_id = $1", [
248
+ tenantId,
249
+ ]);
250
+
251
+ // ❌ SMELL: Trusting user input for tenant
252
+ const tenantId = req.query.tenant; // NEVER
253
+
254
+ // ✅ CORRECT: Extract from verified source
255
+ const tenantId = req.headers["x-tenant-id"]; // From gateway
256
+ // OR
257
+ const tenantId = extractFromJWT(req.auth.token);
258
+ // OR
259
+ const tenantId = extractFromSubdomain(req.hostname);
260
+ ```
261
+
262
+ ---
263
+
264
+ ## ✅ IMPLEMENTATION CHECKLIST
265
+
266
+ ### Tenant Resolution
267
+
268
+ - [ ] Tenant extracted from trusted source (subdomain/header/JWT)
269
+ - [ ] Tenant existence validated against master DB
270
+ - [ ] Tenant config cached with appropriate TTL (5-15 mins)
271
+ - [ ] Invalid/missing tenant returns 404/401 (not 500)
272
+ - [ ] Tenant context attached to request early in middleware
273
+
274
+ ### Data Isolation
275
+
276
+ - [ ] RLS enabled on ALL tenant tables (defense in depth)
277
+ - [ ] All repositories include tenant filter by default
278
+ - [ ] Database connection tagged with tenant context
279
+ - [ ] Cross-tenant queries explicitly blocked at service layer
280
+ - [ ] tenant_id column is NOT NULL + indexed
281
+
282
+ ### Context Propagation
283
+
284
+ - [ ] Request-scoped context mechanism in place
285
+ - [ ] Context flows through async boundaries
286
+ - [ ] Background jobs include tenant_id + correlation_id
287
+ - [ ] WebSocket connections have tenant context
288
+ - [ ] Logs include tenant_id for every entry
289
+
290
+ ### Resource Isolation
291
+
292
+ - [ ] Cache keys prefixed: `{tenant}:{key}`
293
+ - [ ] Storage paths include tenant: `tenants/{id}/...`
294
+ - [ ] Rate limiting applied per tenant
295
+ - [ ] Queue jobs tagged with tenant context
296
+ - [ ] Metrics labeled by tenant for monitoring
297
+
298
+ ### Compliance & Security
299
+
300
+ - [ ] Audit logs for all data access
301
+ - [ ] No cross-tenant data exposure in errors
302
+ - [ ] Data residency requirements met
303
+ - [ ] Tenant offboarding procedure documented
304
+ - [ ] Regular penetration testing includes tenant isolation
305
+
306
+ ---
307
+
308
+ ## 📚 References
309
+
310
+ - [Azure Multi-Tenant Architecture Patterns](https://docs.microsoft.com/en-us/azure/architecture/guide/multitenant/overview)
311
+ - [PostgreSQL Row Level Security](https://www.postgresql.org/docs/current/ddl-rowsecurity.html)
312
+ - [SaaS Tenant Isolation Strategies](https://aws.amazon.com/blogs/apn/multi-tenant-saas-database-tenancy-patterns/)
313
+ - [AsyncLocalStorage (Node.js)](https://nodejs.org/api/async_context.html)
314
+
315
+ ---
316
+
317
+ > **Remember:** In multi-tenant systems, ONE missed tenant filter = ALL customer data exposed. Verify tenant context at every boundary, filter everywhere, and audit continuously.
@@ -0,0 +1 @@
1
+ # Assets directory - add templates, images, etc.
@@ -0,0 +1,21 @@
1
+ # Reference Documentation for Multi Tenancy
2
+
3
+ [TODO: Add detailed reference content here]
4
+
5
+ ## Overview
6
+
7
+ [Detailed explanation of concepts]
8
+
9
+ ## Deep Dive Topics
10
+
11
+ ### Topic 1
12
+
13
+ [Content]
14
+
15
+ ### Topic 2
16
+
17
+ [Content]
18
+
19
+ ## Examples
20
+
21
+ [Real-world examples]
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Example validator for multi-tenancy
4
+
5
+ Usage:
6
+ python validate.py <project_path>
7
+ """
8
+
9
+ import sys
10
+ from pathlib import Path
11
+
12
+
13
+ def validate(project_path: str) -> dict:
14
+ """Main validation logic"""
15
+ results = {
16
+ 'errors': [],
17
+ 'warnings': [],
18
+ 'passed': []
19
+ }
20
+
21
+ # TODO: Add validation logic
22
+ results['passed'].append('Placeholder validation passed')
23
+
24
+ return results
25
+
26
+
27
+ def print_results(results: dict):
28
+ """Pretty print results"""
29
+ print("\n🔍 Validation Results\n")
30
+
31
+ if results['errors']:
32
+ print(f"❌ Errors ({len(results['errors'])})")
33
+ for error in results['errors']:
34
+ print(f" - {error}")
35
+
36
+ if results['warnings']:
37
+ print(f"\n⚠️ Warnings ({len(results['warnings'])})")
38
+ for warning in results['warnings']:
39
+ print(f" - {warning}")
40
+
41
+ if results['passed']:
42
+ print(f"\n✅ Passed ({len(results['passed'])})")
43
+ for passed in results['passed']:
44
+ print(f" - {passed}")
45
+
46
+
47
+ if __name__ == "__main__":
48
+ if len(sys.argv) < 2:
49
+ print("Usage: python validate.py <project_path>")
50
+ sys.exit(1)
51
+
52
+ project_path = sys.argv[1]
53
+ results = validate(project_path)
54
+ print_results(results)
55
+
56
+ sys.exit(1 if results['errors'] else 0)
@@ -0,0 +1,220 @@
1
+ ---
2
+ name: nodejs-best-practices
3
+ description: Node.js development principles. Express/Fastify patterns, async handling, error management, security.
4
+ allowed-tools: Read, Write, Edit, Glob, Grep, Bash
5
+ ---
6
+
7
+ # Node.js Best Practices
8
+
9
+ > JavaScript on the server, done right.
10
+
11
+ ---
12
+
13
+ ## Core Principles
14
+
15
+ 1. **Async by default** - Never block the event loop
16
+ 2. **Error handling is mandatory** - Catch everything, crash gracefully
17
+ 3. **Security first** - Validate input, sanitize output
18
+ 4. **Observability built-in** - Log structured, trace distributed
19
+
20
+ ---
21
+
22
+ ## 🔧 Framework Selection
23
+
24
+ | Framework | Best For |
25
+ | ----------- | --------------------------- |
26
+ | **Express** | Simple APIs, custom needs |
27
+ | **Fastify** | Performance, schema-first |
28
+ | **NestJS** | Enterprise, DDD, TypeScript |
29
+ | **Hono** | Edge runtime, lightweight |
30
+
31
+ ---
32
+
33
+ ## 📁 Project Structure
34
+
35
+ ```
36
+ src/
37
+ ├── modules/
38
+ │ ├── user/
39
+ │ │ ├── user.controller.ts
40
+ │ │ ├── user.service.ts
41
+ │ │ ├── user.repository.ts
42
+ │ │ └── user.dto.ts
43
+ │ └── auth/
44
+ ├── common/
45
+ │ ├── middleware/
46
+ │ ├── guards/
47
+ │ └── decorators/
48
+ ├── config/
49
+ ├── lib/
50
+ └── app.ts
51
+ ```
52
+
53
+ ---
54
+
55
+ ## ⚡ Async Patterns
56
+
57
+ ### Error Handling Wrapper
58
+
59
+ ```typescript
60
+ const asyncHandler =
61
+ (fn: RequestHandler) => (req: Request, res: Response, next: NextFunction) =>
62
+ Promise.resolve(fn(req, res, next)).catch(next);
63
+
64
+ // Usage
65
+ app.get(
66
+ "/users",
67
+ asyncHandler(async (req, res) => {
68
+ const users = await userService.findAll();
69
+ res.json(users);
70
+ }),
71
+ );
72
+ ```
73
+
74
+ ### Promise Concurrency
75
+
76
+ ```typescript
77
+ // ✅ Parallel when independent
78
+ const [users, posts] = await Promise.all([getUsers(), getPosts()]);
79
+
80
+ // ✅ Sequential when dependent
81
+ const user = await getUser(id);
82
+ const posts = await getPostsByUser(user.id);
83
+
84
+ // ✅ Limit concurrency for bulk
85
+ import pLimit from "p-limit";
86
+ const limit = pLimit(5);
87
+ await Promise.all(items.map((i) => limit(() => process(i))));
88
+ ```
89
+
90
+ ---
91
+
92
+ ## 🔒 Security
93
+
94
+ ### Input Validation (Zod)
95
+
96
+ ```typescript
97
+ import { z } from "zod";
98
+
99
+ const createUserSchema = z.object({
100
+ email: z.string().email(),
101
+ name: z.string().min(2).max(100),
102
+ password: z.string().min(8).max(100),
103
+ });
104
+
105
+ // Middleware
106
+ app.post(
107
+ "/users",
108
+ asyncHandler(async (req, res) => {
109
+ const data = createUserSchema.parse(req.body);
110
+ // data is now typed and validated
111
+ }),
112
+ );
113
+ ```
114
+
115
+ ### Rate Limiting
116
+
117
+ ```typescript
118
+ import rateLimit from "express-rate-limit";
119
+
120
+ const limiter = rateLimit({
121
+ windowMs: 15 * 60 * 1000, // 15 minutes
122
+ max: 100,
123
+ standardHeaders: true,
124
+ });
125
+
126
+ app.use("/api/", limiter);
127
+ ```
128
+
129
+ ---
130
+
131
+ ## 🛠️ Error Handling
132
+
133
+ ### Error Class
134
+
135
+ ```typescript
136
+ class AppError extends Error {
137
+ constructor(
138
+ public statusCode: number,
139
+ public code: string,
140
+ message: string,
141
+ ) {
142
+ super(message);
143
+ Error.captureStackTrace(this, this.constructor);
144
+ }
145
+ }
146
+
147
+ // Usage
148
+ throw new AppError(404, "USER_NOT_FOUND", "User not found");
149
+ ```
150
+
151
+ ### Global Handler
152
+
153
+ ```typescript
154
+ app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
155
+ if (err instanceof AppError) {
156
+ return res.status(err.statusCode).json({
157
+ error: { code: err.code, message: err.message },
158
+ });
159
+ }
160
+
161
+ console.error(err);
162
+ res.status(500).json({
163
+ error: { code: "INTERNAL_ERROR", message: "Something went wrong" },
164
+ });
165
+ });
166
+ ```
167
+
168
+ ---
169
+
170
+ ## 📊 Observability
171
+
172
+ ### Structured Logging
173
+
174
+ ```typescript
175
+ import pino from "pino";
176
+
177
+ const logger = pino({
178
+ level: process.env.LOG_LEVEL || "info",
179
+ transport:
180
+ process.env.NODE_ENV === "development"
181
+ ? { target: "pino-pretty" }
182
+ : undefined,
183
+ });
184
+
185
+ // Usage
186
+ logger.info({ userId: user.id }, "User created");
187
+ logger.error({ err, requestId }, "Request failed");
188
+ ```
189
+
190
+ ---
191
+
192
+ ## ✅ Checklist
193
+
194
+ - [ ] Never `throw` in async without catching
195
+ - [ ] All inputs validated and sanitized
196
+ - [ ] Rate limiting on public endpoints
197
+ - [ ] Structured logging configured
198
+ - [ ] Health check endpoint
199
+ - [ ] Graceful shutdown handling
200
+
201
+ ---
202
+
203
+ ## ❌ Anti-Patterns
204
+
205
+ | Don't | Do |
206
+ | ------------------------------ | --------------------------- |
207
+ | `async` without error handling | Wrap with asyncHandler |
208
+ | Callback APIs | Promisify or use async libs |
209
+ | `console.log` in production | Structured logging |
210
+ | Sync file operations | Use async fs methods |
211
+ | Throwing strings | Custom Error classes |
212
+
213
+ ---
214
+
215
+ ## 🔗 Related Skills
216
+
217
+ - `api-patterns` - API design
218
+ - `auth-patterns` - Authentication
219
+ - `testing-patterns` - Testing
220
+ - `docker-patterns` - Containerization