contextos-agents 1.5.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 (310) hide show
  1. package/.agents/AGENTS.md +421 -0
  2. package/.agents/adapters/aider/export.js +137 -0
  3. package/.agents/adapters/claude/export.js +55 -0
  4. package/.agents/adapters/copilot/export.js +107 -0
  5. package/.agents/adapters/cursor/export.js +210 -0
  6. package/.agents/adapters/gemini/export.js +115 -0
  7. package/.agents/adapters/shared.js +119 -0
  8. package/.agents/adapters/zed/export.js +111 -0
  9. package/.agents/core/profiles/backend.yaml +47 -0
  10. package/.agents/core/profiles/enterprise.yaml +46 -0
  11. package/.agents/core/profiles/frontend.yaml +46 -0
  12. package/.agents/core/profiles/hackathon.yaml +45 -0
  13. package/.agents/core/profiles/mvp.yaml +43 -0
  14. package/.agents/core/profiles/startup.yaml +48 -0
  15. package/.agents/core/skills/adapters/EXAMPLES.md +19 -0
  16. package/.agents/core/skills/adapters/SKILL.md +105 -0
  17. package/.agents/core/skills/adapters/TROUBLESHOOTING.md +7 -0
  18. package/.agents/core/skills/adapters/VALIDATION.json +12 -0
  19. package/.agents/core/skills/adapters/skill.yaml +10 -0
  20. package/.agents/core/skills/architecture-diagrams/SKILL.md +108 -0
  21. package/.agents/core/skills/architecture-diagrams/VALIDATION.json +12 -0
  22. package/.agents/core/skills/architecture-diagrams/skill.yaml +8 -0
  23. package/.agents/core/skills/brutalist-design/SKILL.md +150 -0
  24. package/.agents/core/skills/brutalist-design/VALIDATION.json +12 -0
  25. package/.agents/core/skills/brutalist-design/skill.yaml +8 -0
  26. package/.agents/core/skills/context-manager/EXAMPLES.md +19 -0
  27. package/.agents/core/skills/context-manager/SKILL.md +126 -0
  28. package/.agents/core/skills/context-manager/TROUBLESHOOTING.md +7 -0
  29. package/.agents/core/skills/context-manager/VALIDATION.json +12 -0
  30. package/.agents/core/skills/context-manager/skill.yaml +10 -0
  31. package/.agents/core/skills/context-os/EXAMPLES.md +21 -0
  32. package/.agents/core/skills/context-os/SKILL.md +169 -0
  33. package/.agents/core/skills/context-os/TROUBLESHOOTING.md +7 -0
  34. package/.agents/core/skills/context-os/VALIDATION.json +12 -0
  35. package/.agents/core/skills/context-os/packs.yaml +59 -0
  36. package/.agents/core/skills/context-os/references/context-rules.md +68 -0
  37. package/.agents/core/skills/context-os/references/pipeline.md +119 -0
  38. package/.agents/core/skills/context-os/references/project-graph.md +103 -0
  39. package/.agents/core/skills/context-os/rules.yaml +135 -0
  40. package/.agents/core/skills/context-os/skill.yaml +10 -0
  41. package/.agents/core/skills/database/EXAMPLES.md +74 -0
  42. package/.agents/core/skills/database/SKILL.md +101 -0
  43. package/.agents/core/skills/database/TROUBLESHOOTING.md +18 -0
  44. package/.agents/core/skills/database/VALIDATION.json +11 -0
  45. package/.agents/core/skills/database/skill.yaml +25 -0
  46. package/.agents/core/skills/ddd/EXAMPLES.md +42 -0
  47. package/.agents/core/skills/ddd/SKILL.md +247 -0
  48. package/.agents/core/skills/ddd/TROUBLESHOOTING.md +19 -0
  49. package/.agents/core/skills/ddd/VALIDATION.json +12 -0
  50. package/.agents/core/skills/ddd/ddd.md +178 -0
  51. package/.agents/core/skills/ddd/skill.yaml +10 -0
  52. package/.agents/core/skills/decisions/EXAMPLES.md +35 -0
  53. package/.agents/core/skills/decisions/SKILL.md +90 -0
  54. package/.agents/core/skills/decisions/TROUBLESHOOTING.md +13 -0
  55. package/.agents/core/skills/decisions/VALIDATION.json +12 -0
  56. package/.agents/core/skills/decisions/skill.yaml +10 -0
  57. package/.agents/core/skills/docker/EXAMPLES.md +56 -0
  58. package/.agents/core/skills/docker/SKILL.md +63 -0
  59. package/.agents/core/skills/docker/TROUBLESHOOTING.md +18 -0
  60. package/.agents/core/skills/docker/VALIDATION.json +11 -0
  61. package/.agents/core/skills/docker/skill.yaml +23 -0
  62. package/.agents/core/skills/engineering-workflow/EXAMPLES.md +57 -0
  63. package/.agents/core/skills/engineering-workflow/SKILL.md +343 -0
  64. package/.agents/core/skills/engineering-workflow/TROUBLESHOOTING.md +19 -0
  65. package/.agents/core/skills/engineering-workflow/VALIDATION.json +12 -0
  66. package/.agents/core/skills/engineering-workflow/skill.yaml +13 -0
  67. package/.agents/core/skills/fastapi/EXAMPLES.md +36 -0
  68. package/.agents/core/skills/fastapi/SKILL.md +148 -0
  69. package/.agents/core/skills/fastapi/TROUBLESHOOTING.md +19 -0
  70. package/.agents/core/skills/fastapi/VALIDATION.json +12 -0
  71. package/.agents/core/skills/fastapi/fastapi.md +112 -0
  72. package/.agents/core/skills/fastapi/skill.yaml +10 -0
  73. package/.agents/core/skills/gemini-precision/SKILL.md +169 -0
  74. package/.agents/core/skills/gemini-precision/VALIDATION.json +12 -0
  75. package/.agents/core/skills/gemini-precision/skill.yaml +9 -0
  76. package/.agents/core/skills/generators/EXAMPLES.md +19 -0
  77. package/.agents/core/skills/generators/SKILL.md +112 -0
  78. package/.agents/core/skills/generators/TROUBLESHOOTING.md +7 -0
  79. package/.agents/core/skills/generators/VALIDATION.json +12 -0
  80. package/.agents/core/skills/generators/skill.yaml +10 -0
  81. package/.agents/core/skills/generators/templates/API.md +77 -0
  82. package/.agents/core/skills/generators/templates/ARCHITECTURE.md +70 -0
  83. package/.agents/core/skills/generators/templates/DATABASE.md +42 -0
  84. package/.agents/core/skills/generators/templates/DECISION.md +46 -0
  85. package/.agents/core/skills/generators/templates/PRD.md +67 -0
  86. package/.agents/core/skills/generators/templates/PROJECT_GRAPH.md +56 -0
  87. package/.agents/core/skills/generators/templates/ROADMAP.md +51 -0
  88. package/.agents/core/skills/generators/templates/TASKS.md +43 -0
  89. package/.agents/core/skills/generators/templates/UI.md +73 -0
  90. package/.agents/core/skills/graphify/EXAMPLES.md +73 -0
  91. package/.agents/core/skills/graphify/SKILL.md +130 -0
  92. package/.agents/core/skills/graphify/VALIDATION.json +12 -0
  93. package/.agents/core/skills/graphify/skill.yaml +13 -0
  94. package/.agents/core/skills/gstack-roles/EXAMPLES.md +23 -0
  95. package/.agents/core/skills/gstack-roles/SKILL.md +152 -0
  96. package/.agents/core/skills/gstack-roles/TROUBLESHOOTING.md +13 -0
  97. package/.agents/core/skills/gstack-roles/VALIDATION.json +12 -0
  98. package/.agents/core/skills/gstack-roles/skill.yaml +12 -0
  99. package/.agents/core/skills/impeccable-design/EXAMPLES.md +26 -0
  100. package/.agents/core/skills/impeccable-design/SKILL.md +201 -0
  101. package/.agents/core/skills/impeccable-design/TROUBLESHOOTING.md +19 -0
  102. package/.agents/core/skills/impeccable-design/VALIDATION.json +12 -0
  103. package/.agents/core/skills/impeccable-design/skill.yaml +14 -0
  104. package/.agents/core/skills/interview-me/SKILL.md +97 -0
  105. package/.agents/core/skills/interview-me/VALIDATION.json +12 -0
  106. package/.agents/core/skills/interview-me/skill.yaml +8 -0
  107. package/.agents/core/skills/microservices/EXAMPLES.md +38 -0
  108. package/.agents/core/skills/microservices/SKILL.md +164 -0
  109. package/.agents/core/skills/microservices/TROUBLESHOOTING.md +19 -0
  110. package/.agents/core/skills/microservices/VALIDATION.json +12 -0
  111. package/.agents/core/skills/microservices/microservices.md +119 -0
  112. package/.agents/core/skills/microservices/skill.yaml +10 -0
  113. package/.agents/core/skills/minimalist-design/SKILL.md +113 -0
  114. package/.agents/core/skills/minimalist-design/VALIDATION.json +12 -0
  115. package/.agents/core/skills/minimalist-design/skill.yaml +8 -0
  116. package/.agents/core/skills/nestjs/EXAMPLES.md +40 -0
  117. package/.agents/core/skills/nestjs/SKILL.md +139 -0
  118. package/.agents/core/skills/nestjs/TROUBLESHOOTING.md +19 -0
  119. package/.agents/core/skills/nestjs/VALIDATION.json +12 -0
  120. package/.agents/core/skills/nestjs/nestjs.md +103 -0
  121. package/.agents/core/skills/nestjs/skill.yaml +10 -0
  122. package/.agents/core/skills/nextjs/EXAMPLES.md +40 -0
  123. package/.agents/core/skills/nextjs/SKILL.md +163 -0
  124. package/.agents/core/skills/nextjs/TROUBLESHOOTING.md +19 -0
  125. package/.agents/core/skills/nextjs/VALIDATION.json +12 -0
  126. package/.agents/core/skills/nextjs/nextjs.md +67 -0
  127. package/.agents/core/skills/nextjs/skill.yaml +10 -0
  128. package/.agents/core/skills/node/EXAMPLES.md +80 -0
  129. package/.agents/core/skills/node/SKILL.md +128 -0
  130. package/.agents/core/skills/node/TROUBLESHOOTING.md +19 -0
  131. package/.agents/core/skills/node/VALIDATION.json +12 -0
  132. package/.agents/core/skills/node/node.md +87 -0
  133. package/.agents/core/skills/node/skill.yaml +10 -0
  134. package/.agents/core/skills/performance/EXAMPLES.md +30 -0
  135. package/.agents/core/skills/performance/SKILL.md +75 -0
  136. package/.agents/core/skills/performance/TROUBLESHOOTING.md +19 -0
  137. package/.agents/core/skills/performance/VALIDATION.json +12 -0
  138. package/.agents/core/skills/performance/performance.md +52 -0
  139. package/.agents/core/skills/performance/skill.yaml +10 -0
  140. package/.agents/core/skills/ponytail-mindset/EXAMPLES.md +45 -0
  141. package/.agents/core/skills/ponytail-mindset/SKILL.md +193 -0
  142. package/.agents/core/skills/ponytail-mindset/TROUBLESHOOTING.md +19 -0
  143. package/.agents/core/skills/ponytail-mindset/VALIDATION.json +12 -0
  144. package/.agents/core/skills/ponytail-mindset/skill.yaml +14 -0
  145. package/.agents/core/skills/react/EXAMPLES.md +79 -0
  146. package/.agents/core/skills/react/SKILL.md +132 -0
  147. package/.agents/core/skills/react/TROUBLESHOOTING.md +19 -0
  148. package/.agents/core/skills/react/VALIDATION.json +12 -0
  149. package/.agents/core/skills/react/react.md +93 -0
  150. package/.agents/core/skills/react/skill.yaml +10 -0
  151. package/.agents/core/skills/react-best-practices/SKILL.md +155 -0
  152. package/.agents/core/skills/react-best-practices/VALIDATION.json +12 -0
  153. package/.agents/core/skills/react-best-practices/skill.yaml +10 -0
  154. package/.agents/core/skills/redesign-audit/SKILL.md +117 -0
  155. package/.agents/core/skills/redesign-audit/VALIDATION.json +12 -0
  156. package/.agents/core/skills/redesign-audit/skill.yaml +8 -0
  157. package/.agents/core/skills/security/EXAMPLES.md +64 -0
  158. package/.agents/core/skills/security/SKILL.md +158 -0
  159. package/.agents/core/skills/security/TROUBLESHOOTING.md +19 -0
  160. package/.agents/core/skills/security/VALIDATION.json +12 -0
  161. package/.agents/core/skills/security/security.md +106 -0
  162. package/.agents/core/skills/security/skill.yaml +10 -0
  163. package/.agents/core/skills/soft-design/SKILL.md +108 -0
  164. package/.agents/core/skills/soft-design/VALIDATION.json +12 -0
  165. package/.agents/core/skills/soft-design/skill.yaml +8 -0
  166. package/.agents/core/skills/state-management/EXAMPLES.md +56 -0
  167. package/.agents/core/skills/state-management/SKILL.md +48 -0
  168. package/.agents/core/skills/state-management/TROUBLESHOOTING.md +18 -0
  169. package/.agents/core/skills/state-management/VALIDATION.json +11 -0
  170. package/.agents/core/skills/state-management/skill.yaml +22 -0
  171. package/.agents/core/skills/subagent-orchestrator/SKILL.md +100 -0
  172. package/.agents/core/skills/subagent-orchestrator/VALIDATION.json +12 -0
  173. package/.agents/core/skills/subagent-orchestrator/skill.yaml +8 -0
  174. package/.agents/core/skills/system-design/EXAMPLES.md +75 -0
  175. package/.agents/core/skills/system-design/SKILL.md +419 -0
  176. package/.agents/core/skills/system-design/TROUBLESHOOTING.md +19 -0
  177. package/.agents/core/skills/system-design/VALIDATION.json +12 -0
  178. package/.agents/core/skills/system-design/skill.yaml +13 -0
  179. package/.agents/core/skills/system-design/system-design.md +112 -0
  180. package/.agents/core/skills/testing/EXAMPLES.md +71 -0
  181. package/.agents/core/skills/testing/SKILL.md +70 -0
  182. package/.agents/core/skills/testing/TROUBLESHOOTING.md +18 -0
  183. package/.agents/core/skills/testing/VALIDATION.json +11 -0
  184. package/.agents/core/skills/testing/skill.yaml +26 -0
  185. package/.agents/core/skills/typescript/EXAMPLES.md +64 -0
  186. package/.agents/core/skills/typescript/SKILL.md +112 -0
  187. package/.agents/core/skills/typescript/TROUBLESHOOTING.md +19 -0
  188. package/.agents/core/skills/typescript/VALIDATION.json +12 -0
  189. package/.agents/core/skills/typescript/skill.yaml +10 -0
  190. package/.agents/core/skills/typescript/typescript.md +71 -0
  191. package/.agents/core/skills/ui-design/EXAMPLES.md +21 -0
  192. package/.agents/core/skills/ui-design/SKILL.md +124 -0
  193. package/.agents/core/skills/ui-design/TROUBLESHOOTING.md +19 -0
  194. package/.agents/core/skills/ui-design/VALIDATION.json +12 -0
  195. package/.agents/core/skills/ui-design/skill.yaml +10 -0
  196. package/.agents/core/skills/ui-design/ui.md +88 -0
  197. package/.agents/core/skills/ui-ux-pro/EXAMPLES.md +62 -0
  198. package/.agents/core/skills/ui-ux-pro/SKILL.md +375 -0
  199. package/.agents/core/skills/ui-ux-pro/TROUBLESHOOTING.md +19 -0
  200. package/.agents/core/skills/ui-ux-pro/VALIDATION.json +12 -0
  201. package/.agents/core/skills/ui-ux-pro/skill.yaml +13 -0
  202. package/.agents/core/skills/ux-design/EXAMPLES.md +36 -0
  203. package/.agents/core/skills/ux-design/SKILL.md +116 -0
  204. package/.agents/core/skills/ux-design/TROUBLESHOOTING.md +19 -0
  205. package/.agents/core/skills/ux-design/VALIDATION.json +12 -0
  206. package/.agents/core/skills/ux-design/skill.yaml +10 -0
  207. package/.agents/core/skills/ux-design/ux.md +80 -0
  208. package/.agents/core/skills/vercel-optimize/SKILL.md +83 -0
  209. package/.agents/core/skills/vercel-optimize/VALIDATION.json +12 -0
  210. package/.agents/core/skills/vercel-optimize/skill.yaml +10 -0
  211. package/.agents/core/skills/web-accessibility/EXAMPLES.md +39 -0
  212. package/.agents/core/skills/web-accessibility/SKILL.md +170 -0
  213. package/.agents/core/skills/web-accessibility/TROUBLESHOOTING.md +19 -0
  214. package/.agents/core/skills/web-accessibility/VALIDATION.json +12 -0
  215. package/.agents/core/skills/web-accessibility/accessibility.md +63 -0
  216. package/.agents/core/skills/web-accessibility/skill.yaml +10 -0
  217. package/.agents/ctx.js +370 -0
  218. package/.agents/generated/claude/skills/adapters/SKILL.md +126 -0
  219. package/.agents/generated/claude/skills/architecture-diagrams/SKILL.md +101 -0
  220. package/.agents/generated/claude/skills/brutalist-design/SKILL.md +145 -0
  221. package/.agents/generated/claude/skills/context-manager/SKILL.md +147 -0
  222. package/.agents/generated/claude/skills/context-os/SKILL.md +191 -0
  223. package/.agents/generated/claude/skills/database/SKILL.md +191 -0
  224. package/.agents/generated/claude/skills/ddd/SKILL.md +305 -0
  225. package/.agents/generated/claude/skills/decisions/SKILL.md +134 -0
  226. package/.agents/generated/claude/skills/docker/SKILL.md +135 -0
  227. package/.agents/generated/claude/skills/engineering-workflow/SKILL.md +414 -0
  228. package/.agents/generated/claude/skills/fastapi/SKILL.md +200 -0
  229. package/.agents/generated/claude/skills/gemini-precision/SKILL.md +161 -0
  230. package/.agents/generated/claude/skills/generators/SKILL.md +133 -0
  231. package/.agents/generated/claude/skills/graphify/SKILL.md +198 -0
  232. package/.agents/generated/claude/skills/gstack-roles/SKILL.md +184 -0
  233. package/.agents/generated/claude/skills/impeccable-design/SKILL.md +241 -0
  234. package/.agents/generated/claude/skills/interview-me/SKILL.md +90 -0
  235. package/.agents/generated/claude/skills/microservices/SKILL.md +218 -0
  236. package/.agents/generated/claude/skills/minimalist-design/SKILL.md +108 -0
  237. package/.agents/generated/claude/skills/nestjs/SKILL.md +195 -0
  238. package/.agents/generated/claude/skills/nextjs/SKILL.md +219 -0
  239. package/.agents/generated/claude/skills/node/SKILL.md +224 -0
  240. package/.agents/generated/claude/skills/performance/SKILL.md +121 -0
  241. package/.agents/generated/claude/skills/ponytail-mindset/SKILL.md +252 -0
  242. package/.agents/generated/claude/skills/react/SKILL.md +227 -0
  243. package/.agents/generated/claude/skills/react-best-practices/SKILL.md +146 -0
  244. package/.agents/generated/claude/skills/redesign-audit/SKILL.md +112 -0
  245. package/.agents/generated/claude/skills/security/SKILL.md +237 -0
  246. package/.agents/generated/claude/skills/soft-design/SKILL.md +103 -0
  247. package/.agents/generated/claude/skills/state-management/SKILL.md +120 -0
  248. package/.agents/generated/claude/skills/subagent-orchestrator/SKILL.md +93 -0
  249. package/.agents/generated/claude/skills/system-design/SKILL.md +507 -0
  250. package/.agents/generated/claude/skills/testing/SKILL.md +157 -0
  251. package/.agents/generated/claude/skills/typescript/SKILL.md +192 -0
  252. package/.agents/generated/claude/skills/ui-design/SKILL.md +161 -0
  253. package/.agents/generated/claude/skills/ui-ux-pro/SKILL.md +451 -0
  254. package/.agents/generated/claude/skills/ux-design/SKILL.md +168 -0
  255. package/.agents/generated/claude/skills/vercel-optimize/SKILL.md +76 -0
  256. package/.agents/generated/claude/skills/web-accessibility/SKILL.md +225 -0
  257. package/.agents/generated/gemini/skills/adapters/SKILL.md +135 -0
  258. package/.agents/generated/gemini/skills/architecture-diagrams/SKILL.md +107 -0
  259. package/.agents/generated/gemini/skills/brutalist-design/SKILL.md +151 -0
  260. package/.agents/generated/gemini/skills/context-manager/SKILL.md +156 -0
  261. package/.agents/generated/gemini/skills/context-os/SKILL.md +200 -0
  262. package/.agents/generated/gemini/skills/database/SKILL.md +200 -0
  263. package/.agents/generated/gemini/skills/ddd/SKILL.md +314 -0
  264. package/.agents/generated/gemini/skills/decisions/SKILL.md +143 -0
  265. package/.agents/generated/gemini/skills/docker/SKILL.md +144 -0
  266. package/.agents/generated/gemini/skills/engineering-workflow/SKILL.md +423 -0
  267. package/.agents/generated/gemini/skills/fastapi/SKILL.md +209 -0
  268. package/.agents/generated/gemini/skills/gemini-precision/SKILL.md +167 -0
  269. package/.agents/generated/gemini/skills/generators/SKILL.md +142 -0
  270. package/.agents/generated/gemini/skills/graphify/SKILL.md +205 -0
  271. package/.agents/generated/gemini/skills/gstack-roles/SKILL.md +193 -0
  272. package/.agents/generated/gemini/skills/impeccable-design/SKILL.md +250 -0
  273. package/.agents/generated/gemini/skills/interview-me/SKILL.md +96 -0
  274. package/.agents/generated/gemini/skills/microservices/SKILL.md +227 -0
  275. package/.agents/generated/gemini/skills/minimalist-design/SKILL.md +114 -0
  276. package/.agents/generated/gemini/skills/nestjs/SKILL.md +204 -0
  277. package/.agents/generated/gemini/skills/nextjs/SKILL.md +298 -0
  278. package/.agents/generated/gemini/skills/node/SKILL.md +323 -0
  279. package/.agents/generated/gemini/skills/performance/SKILL.md +185 -0
  280. package/.agents/generated/gemini/skills/ponytail-mindset/SKILL.md +261 -0
  281. package/.agents/generated/gemini/skills/react/SKILL.md +332 -0
  282. package/.agents/generated/gemini/skills/react-best-practices/SKILL.md +152 -0
  283. package/.agents/generated/gemini/skills/redesign-audit/SKILL.md +118 -0
  284. package/.agents/generated/gemini/skills/security/SKILL.md +355 -0
  285. package/.agents/generated/gemini/skills/soft-design/SKILL.md +109 -0
  286. package/.agents/generated/gemini/skills/state-management/SKILL.md +129 -0
  287. package/.agents/generated/gemini/skills/subagent-orchestrator/SKILL.md +99 -0
  288. package/.agents/generated/gemini/skills/system-design/SKILL.md +631 -0
  289. package/.agents/generated/gemini/skills/testing/SKILL.md +166 -0
  290. package/.agents/generated/gemini/skills/typescript/SKILL.md +275 -0
  291. package/.agents/generated/gemini/skills/ui-design/SKILL.md +170 -0
  292. package/.agents/generated/gemini/skills/ui-ux-pro/SKILL.md +460 -0
  293. package/.agents/generated/gemini/skills/ux-design/SKILL.md +177 -0
  294. package/.agents/generated/gemini/skills/vercel-optimize/SKILL.md +82 -0
  295. package/.agents/generated/gemini/skills/web-accessibility/SKILL.md +300 -0
  296. package/.agents/mcp/runtime.py +454 -0
  297. package/.agents/mcp/server.mjs +189373 -0
  298. package/.agents/plugins.js +574 -0
  299. package/.agents/profiles.js +267 -0
  300. package/.agents/resolver.js +336 -0
  301. package/.agents/skills-index.json +200 -0
  302. package/.agents/skills.json +6 -0
  303. package/.agents/validate.js +500 -0
  304. package/LICENSE +21 -0
  305. package/README.md +415 -0
  306. package/benchmarks/gemini-issues.js +533 -0
  307. package/bin/index.js +458 -0
  308. package/package.json +70 -0
  309. package/registry.json +53 -0
  310. package/registry.schema.json +32 -0
@@ -0,0 +1,507 @@
1
+ # system-design
2
+
3
+ ## Overview
4
+
5
+ Scalable system architecture blueprint based on the System Design Primer and DDIA. Enforces load balancing, multi-tier caching (Redis, CDN), database partitioning, CAP theorem tradeoffs, and rate limiting before code is written.
6
+
7
+ ## When to Use
8
+
9
+ Activate during the PLAN phase of any backend service, API design, database schema creation, or scalability optimization.
10
+
11
+ ## Rules & Patterns
12
+
13
+ Based on [donnemartin/system-design-primer](https://github.com/donnemartin/system-design-primer) — the most starred system design resource on GitHub.
14
+
15
+ ## Core Principle
16
+
17
+ > **Everything is a trade-off.** Before writing a single line of backend code, reason through the system at scale. A flat monolith that works now fails at 10× load.
18
+
19
+ ---
20
+
21
+ ## Mandatory Pre-Design Checklist
22
+
23
+ Before architecting any backend system, answer these questions:
24
+
25
+ 1. **Scale**: What is the expected QPS (queries per second)? Peak vs average?
26
+ 2. **Data volume**: How much data? Growth rate? 1GB? 1TB? 1PB?
27
+ 3. **Consistency vs Availability**: Can we tolerate eventual consistency? (CAP theorem)
28
+ 4. **Read/Write ratio**: Is it read-heavy (cache it!) or write-heavy (shard it!)?
29
+ 5. **Latency requirements**: Real-time (<100ms)? Near-real-time (<1s)? Batch?
30
+ 6. **Global distribution**: Single region or multi-region?
31
+ 7. **Deployment model**: Traditional servers, Serverless, or Edge functions?
32
+
33
+ ---
34
+
35
+ ## Core Architecture Patterns
36
+
37
+ ### Load Balancing
38
+
39
+ ```
40
+ Clients → Load Balancer → [App Server 1, App Server 2, App Server N]
41
+ ```
42
+
43
+ - Use **Round Robin** for stateless services
44
+ - Use **Least Connections** for varying request times
45
+ - Use **IP Hash** for session affinity (or move sessions to Redis)
46
+ - Always add **health checks** — remove unhealthy nodes automatically
47
+
48
+ **Rule**: Any service expecting > 1000 RPS needs a load balancer. No exceptions.
49
+
50
+ ### Caching Strategy
51
+
52
+ ```
53
+ App → [Cache Layer: Redis/Memcached] → Database
54
+ ```
55
+
56
+ Cache decision ladder (check in order):
57
+
58
+ 1. Is it read > write? → Cache it
59
+ 2. Is it expensive to compute? → Cache it
60
+ 3. Is it user-specific? → Cache with user key
61
+ 4. Is it global? → Shared cache, shorter TTL
62
+
63
+ **Cache patterns**:
64
+
65
+ - **Cache-aside** (lazy loading): check cache → miss → load DB → write cache
66
+ - **Write-through**: write to DB AND cache simultaneously (consistency > performance)
67
+ - **Write-behind**: write to cache → async flush to DB (performance > consistency)
68
+
69
+ **Invalidation**: Use TTL + event-driven invalidation. Never stale-forever.
70
+
71
+ **Modern framework-native caching (Next.js App Router)**:
72
+ Before spinning up a dedicated Redis instance for caching API responses, check if Next.js built-in mechanisms are sufficient:
73
+
74
+ - `revalidatePath('/dashboard')` — invalidate all cache for a route
75
+ - `revalidateTag('user-profile')` — fine-grained tagged cache invalidation
76
+ - `unstable_cache()` — server-side data caching with TTL
77
+
78
+ ```typescript
79
+ // [GOOD] Use Next.js native caching first
80
+ import { revalidateTag } from 'next/cache'
81
+
82
+ const getUser = unstable_cache(
83
+ async (id: string) => db.users.findById(id),
84
+ ['user'],
85
+ { tags: ['user-profile'], revalidate: 3600 }
86
+ )
87
+
88
+ // Invalidate on mutation:
89
+ await db.users.update(id, data)
90
+ revalidateTag('user-profile')
91
+
92
+ // [BAD] Don't add Redis for simple SSR caching when Next.js handles it
93
+ ```
94
+
95
+ ### Database Architecture
96
+
97
+ #### When to use SQL vs NoSQL
98
+
99
+ | Scenario | Use SQL | Use NoSQL |
100
+ | ---------- | --------- | ----------- |
101
+ | Complex joins, ACID transactions | [PASS] | [FAIL] |
102
+ | Flexible/evolving schema | [FAIL] | [PASS] |
103
+ | Horizontal scaling needed | Careful | [PASS] |
104
+ | Simple key-value lookup | Overkill | [PASS] |
105
+ | Full-text search | Use Elasticsearch | Use Elasticsearch |
106
+ | Time-series data | TimescaleDB | InfluxDB |
107
+
108
+ #### Scaling Databases
109
+
110
+ **Vertical scaling**: Bigger machine. Easy but has ceiling.
111
+ **Read replicas**: Route SELECT to replicas, writes to primary.
112
+ **Sharding (horizontal partitioning)**:
113
+
114
+ - Hash sharding: `user_id % N` — even distribution, hard to rebalance
115
+ - Range sharding: user_id 1-1M on shard 1 — easy range queries, hotspots risk
116
+ - Directory-based: lookup table maps key → shard — flexible, but lookup is overhead
117
+
118
+ **Denormalization**: For read-heavy systems, duplicate data to avoid joins.
119
+ **Rule**: Don't shard until you've maxed out read replicas.
120
+
121
+ ### Message Queues & Async Processing
122
+
123
+ ```
124
+ Producer → [Queue: Redis/RabbitMQ/Kafka] → Consumer Workers
125
+ ```
126
+
127
+ Use queues when:
128
+
129
+ - Operation takes > 200ms (email, PDF generation, ML inference)
130
+ - You need retry logic on failure
131
+ - You need to decouple services
132
+ - Traffic spikes need to be absorbed
133
+
134
+ **Kafka** = durability + replay + high throughput (events/analytics)
135
+ **Redis Queue** = simplicity + low latency (jobs/tasks)
136
+ **RabbitMQ** = complex routing + acknowledgements
137
+
138
+ ### Microservices vs Monolith
139
+
140
+ **Start with a monolith** unless you have > 10 engineers or proven scale need.
141
+
142
+ When to split into microservices:
143
+
144
+ - Independent deployment cycles needed
145
+ - Different scaling requirements per service
146
+ - Team autonomy (Conway's Law)
147
+ - Clear service boundaries (DDD bounded contexts)
148
+
149
+ **Rule**: A microservice should be able to be rewritten in 2 weeks by 2 engineers.
150
+
151
+ Service communication:
152
+
153
+ - **Sync (REST/gRPC)**: when caller needs immediate response
154
+ - **Async (events/queue)**: when caller can tolerate delay, or decoupling is needed
155
+ - **BFF / Server Actions**: for web apps, prefer typed client-server contracts (see below)
156
+
157
+ ---
158
+
159
+ ## Modern Stack Patterns (Serverless, Edge, Next.js)
160
+
161
+ ### Serverless & Edge Architecture
162
+
163
+ When deploying to serverless (Vercel Functions, AWS Lambda) or edge (Vercel Edge, Cloudflare Workers), the classical "App Server + Load Balancer" model changes:
164
+
165
+ **Cold Start Problem**:
166
+
167
+ - Serverless functions spin up from zero on first request — this can add 100–1000ms
168
+ - **Never** do heavy initialization at module level (DB connections, config loading, crypto keys)
169
+ - **Always** initialize lazily inside the handler, or use a connection pooling service
170
+
171
+ ```typescript
172
+ // [BAD] Wrong: Module-level initialization (runs on cold start, hangs the function)
173
+ const db = new DatabaseClient({ ... }) // top of file
174
+
175
+ // [GOOD] Correct: Lazy initialization with caching
176
+ let db: DatabaseClient | null = null
177
+ function getDb() {
178
+ if (!db) db = new DatabaseClient({ ... })
179
+ return db
180
+ }
181
+ ```
182
+
183
+ **DB Connection Pooling in Serverless**:
184
+
185
+ - Traditional in-process pools (pg-pool, knex) do NOT work in serverless — each invocation is ephemeral
186
+ - Use **Prisma Accelerate**, **PlanetScale**, **Neon** pooling, or **Supabase** — they handle pooling at the infrastructure level
187
+ - Rule: If deploying to Vercel/serverless, NEVER assume `max_connections` is managed by your app process
188
+
189
+ **Edge Functions limitations**:
190
+
191
+ - No Node.js APIs (no `fs`, no `crypto.randomBytes`, limited DNS)
192
+ - Latency must be < 50ms — no heavy DB queries
193
+ - Use edge for: auth token verification, A/B testing, geo-routing, lightweight transformations
194
+
195
+ ### BFF Pattern & Server Actions (Type-Safe Client-Server)
196
+
197
+ When building web apps, prefer typed client-server communication over generic REST endpoints:
198
+
199
+ **Option 1: Server Actions (Next.js App Router)**
200
+ For mutations that touch the database directly, skip the API route entirely:
201
+
202
+ ```typescript
203
+ // [GOOD] Server Action: No API route needed, fully type-safe
204
+ "use server"
205
+ export async function updateUser(id: string, data: UpdateUserInput) {
206
+ // Input validation (always!)
207
+ const validated = UpdateUserSchema.parse(data)
208
+
209
+ // Auth check (always before data access!)
210
+ const session = await getSession()
211
+ if (session.userId !== id && !session.isAdmin) {
212
+ throw new Error("Forbidden")
213
+ }
214
+
215
+ return db.users.update(id, validated)
216
+ }
217
+
218
+ // [BAD] Over-engineering: Don't create /api/users/[id] + fetch wrapper for simple mutations
219
+ ```
220
+
221
+ **Option 2: tRPC (Full-stack type safety)**
222
+ For complex APIs with many routes, use tRPC to get end-to-end type safety from DB to UI without code generation.
223
+
224
+ **Option 3: REST (When appropriate)**
225
+ When building a public API consumed by external clients or mobile apps — use REST with OpenAPI spec.
226
+
227
+ **Decision rule**:
228
+
229
+ - Internal web-to-DB mutation → **Server Action**
230
+ - Internal complex API → **tRPC**
231
+ - Public/mobile API → **REST + OpenAPI**
232
+
233
+ ### Domain-Driven Design (DDD) — Business Logic Isolation
234
+
235
+ **Rule**: NEVER write business logic inside API route handlers, Server Actions, or controllers. Always extract to dedicated services/use-cases.
236
+
237
+ ```
238
+ [FAIL] Wrong structure:
239
+ app/api/orders/route.ts ← contains: validation + auth + business logic + DB query
240
+
241
+ [PASS] Correct structure:
242
+ app/api/orders/route.ts ← only: parse request, call service, return response
243
+ src/services/order.service.ts ← all business logic, testable without HTTP context
244
+ src/repositories/order.repo.ts ← all DB queries
245
+ ```
246
+
247
+ Example:
248
+
249
+ ```typescript
250
+ // [BAD] Business logic in route (untestable, bloated)
251
+ export async function POST(req: Request) {
252
+ const data = await req.json()
253
+ if (data.quantity <= 0) return new Response("Invalid", { status: 400 })
254
+ const inventory = await db.inventory.findById(data.productId)
255
+ if (inventory.stock < data.quantity) return new Response("Out of stock", { status: 400 })
256
+ const total = inventory.price * data.quantity
257
+ // ... 40 more lines
258
+ }
259
+
260
+ // [GOOD] Thin route, fat service
261
+ export async function POST(req: Request) {
262
+ const data = await req.json()
263
+ const result = await orderService.createOrder(data)
264
+ return Response.json(result)
265
+ }
266
+
267
+ // orderService.createOrder() — pure function, fully unit-testable without HTTP
268
+ ```
269
+
270
+ ---
271
+
272
+ ## Scalability Design Patterns
273
+
274
+ ### CDN (Content Delivery Network)
275
+
276
+ - Serve static assets (JS, CSS, images) from CDN edge nodes
277
+ - Cache API responses that don't change per-user
278
+ - Reduce origin server load by 80%+
279
+
280
+ ### Rate Limiting
281
+
282
+ Always implement for public APIs:
283
+
284
+ ```
285
+ - Token bucket: smooth bursts, allows brief spikes
286
+ - Leaky bucket: strict rate, no bursts
287
+ - Fixed window: simple, vulnerable to boundary spikes
288
+ - Sliding window: most accurate, slightly more complex
289
+ ```
290
+
291
+ Store rate limit state in Redis (not in-process — it doesn't survive restarts).
292
+
293
+ ### Circuit Breaker
294
+
295
+ Prevent cascade failures:
296
+
297
+ ```
298
+ CLOSED (normal) → [failures > threshold] → OPEN (fail fast)
299
+ ↑ ↓
300
+ └────── [timeout] ← HALF-OPEN (test request) ──┘
301
+ ```
302
+
303
+ ### Database Connection Pooling
304
+
305
+ - **Traditional servers**: Use pg-pool, knex, Prisma connection pool
306
+ - **Serverless**: Use Prisma Accelerate, PlanetScale, Neon, or Supabase pooling — NOT in-process pools
307
+
308
+ ---
309
+
310
+ ## CAP Theorem in Practice
311
+
312
+ **You can only guarantee 2 of 3**: Consistency, Availability, Partition Tolerance
313
+
314
+ | System | Chooses | Example |
315
+ | -------- | --------- | --------- |
316
+ | Traditional SQL | CP | PostgreSQL |
317
+ | Distributed NoSQL | AP | DynamoDB, Cassandra |
318
+ | Cache | AP (tunable) | Redis with replication |
319
+
320
+ **For most apps**: Choose AP. Accept eventual consistency. Use optimistic locking for critical writes.
321
+
322
+ ---
323
+
324
+ ## Designing Data-Intensive Applications (DDIA) Patterns
325
+
326
+ Based on _Designing Data-Intensive Applications_ (Martin Kleppmann) and [ciembor/agent-rules-books](https://github.com/ciembor/agent-rules-books).
327
+
328
+ ### 1. The Dual-Write Problem & Transactional Outbox
329
+
330
+ **The Anti-Pattern**: Updating the database and sending a message to a broker (Kafka, RabbitMQ, SQS) in two separate operations. If one fails, the system enters an inconsistent state.
331
+
332
+ **The Solution**: Write the business entity AND an event record to an `outbox` table in the SAME database transaction:
333
+
334
+ ```sql
335
+ BEGIN TRANSACTION;
336
+ UPDATE orders SET status = 'PAID' WHERE id = 'ord_123';
337
+ INSERT INTO outbox_events (id, aggregate_type, aggregate_id, event_type, payload, created_at)
338
+ VALUES ('evt_456', 'Order', 'ord_123', 'OrderPaid', '{"amount": 99.00}', NOW());
339
+ COMMIT;
340
+ ```
341
+
342
+ A background process (polling worker or Debezium CDC) reads `outbox_events`, delivers them to the message broker, and marks them as published.
343
+
344
+ ### 2. Idempotency Invariant for Mutations
345
+
346
+ All write operations exposed over HTTP or queues MUST support deduplication:
347
+
348
+ - Accept an `Idempotency-Key` header (UUID or client-generated hash).
349
+ - Store key with status in Redis or DB with a TTL (e.g., 24 hours).
350
+ - If the key is already `COMPLETED`, return the cached response immediately without re-executing.
351
+ - If `IN_PROGRESS`, return HTTP `409 Conflict` or queue retry.
352
+
353
+ ### 3. Read-Your-Own-Writes Consistency
354
+
355
+ When using read replicas, replication lag (even 50ms) causes users to not see their own changes immediately after saving:
356
+
357
+ - **Rule**: Route user reads to the primary database for `N` seconds (e.g., 5s) following any mutation by that user.
358
+ - Route all other queries and background jobs to read replicas.
359
+
360
+ ---
361
+
362
+ ## Architecture Decision Template
363
+
364
+ When proposing any backend architecture, include:
365
+
366
+ ```markdown
367
+ ## System Design Decision
368
+
369
+ **Scale Target**: [X RPS, Y GB data, Z users]
370
+ **Deployment Model**: [Traditional servers | Serverless | Edge]
371
+ **CAP Choice**: [CP/AP] because [reason]
372
+ **Read/Write Ratio**: [X:Y]
373
+
374
+ ### Components
375
+ - **API Layer**: [REST/tRPC/Server Actions] — [why this choice]
376
+ - **Cache**: [Next.js native | Redis] for [what] with [TTL/tags strategy]
377
+ - **Database**: [SQL/NoSQL] - [pooling solution for serverless if applicable]
378
+ - **Async**: [Queue tech] for [what operations]
379
+
380
+ ### Business Logic Isolation
381
+ - Services: [list key service files]
382
+ - Repositories: [list key repo files]
383
+ - Routes/Actions: [thin handlers only]
384
+
385
+ ### Trade-offs Accepted
386
+ - [Trade-off 1]: [Why acceptable]
387
+ - [Trade-off 2]: [Why acceptable]
388
+
389
+ ### Scaling Path
390
+ 1. Now (MVP): [simple setup]
391
+ 2. At 10× load: [first scaling step]
392
+ 3. At 100× load: [next scaling step]
393
+ ```
394
+
395
+
396
+ ## Code Examples
397
+
398
+ See `EXAMPLES.md` for detailed code examples.
399
+
400
+ ## Validation Checklist
401
+
402
+ What to verify during the review phase before completing the task.
403
+
404
+ ## Common Mistakes
405
+
406
+ Anti-patterns and things to explicitly avoid. See `TROUBLESHOOTING.md`.
407
+
408
+ ## Integration Notes
409
+
410
+ How this skill interacts with other skills.
411
+
412
+
413
+ # system-design Examples — Anti-patterns vs ContextOS Standard
414
+
415
+ ## Example 1: Database Caching Strategy
416
+
417
+ ### Anti-pattern: Cache-Aside with Unbounded Thundering Herd
418
+
419
+ ```typescript
420
+ // BAD: When cache expires, 10,000 concurrent requests hit PostgreSQL simultaneously
421
+ async function getUserProfile(id: string) {
422
+ const cached = await redis.get(`user:${id}`);
423
+ if (cached) return JSON.parse(cached);
424
+ const user = await db.user.findUnique({ where: { id } });
425
+ await redis.set(`user:${id}`, JSON.stringify(user), 'EX', 300);
426
+ return user;
427
+ }
428
+ ```
429
+
430
+ ### Best practice: ContextOS Standard (Mutex Lock / Single-Flight Pattern)
431
+
432
+ ```typescript
433
+ // GOOD: Only one worker fetches from DB on cache miss; others wait
434
+ import { singleflight } from './singleflight';
435
+
436
+ async function getUserProfile(id: string) {
437
+ const cached = await redis.get(`user:${id}`);
438
+ if (cached) return JSON.parse(cached);
439
+
440
+ return singleflight.do(`user:${id}`, async () => {
441
+ const fresh = await redis.get(`user:${id}`);
442
+ if (fresh) return JSON.parse(fresh);
443
+
444
+ const user = await db.user.findUnique({ where: { id } });
445
+ if (user) {
446
+ await redis.set(`user:${id}`, JSON.stringify(user), 'EX', 300);
447
+ }
448
+ return user;
449
+ });
450
+ }
451
+ ```
452
+
453
+ ---
454
+
455
+ ## Example 2: Outbox Pattern for Distributed Consistency
456
+
457
+ ### Anti-pattern: Dual-Write Anti-pattern (Direct DB write + Kafka publish)
458
+
459
+ ```typescript
460
+ // BAD: If Kafka publish fails, DB change is committed but event is lost forever
461
+ async function createOrder(data: OrderInput) {
462
+ const order = await db.order.create({ data });
463
+ await kafkaProducer.send({ topic: 'orders', messages: [{ value: JSON.stringify(order) }] });
464
+ return order;
465
+ }
466
+ ```
467
+
468
+ ### Best practice: ContextOS Standard (Transactional Outbox)
469
+
470
+ ```typescript
471
+ // GOOD: Order and Outbox record committed in a single atomic DB transaction
472
+ async function createOrder(data: OrderInput) {
473
+ return await db.$transaction(async (tx) => {
474
+ const order = await tx.order.create({ data });
475
+ await tx.outbox.create({
476
+ data: {
477
+ aggregateType: 'Order',
478
+ aggregateId: order.id,
479
+ eventType: 'OrderCreated',
480
+ payload: JSON.stringify(order),
481
+ status: 'PENDING',
482
+ },
483
+ });
484
+ return order;
485
+ });
486
+ }
487
+ ```
488
+
489
+ # system-design Troubleshooting & Common Mistakes
490
+
491
+ ## 1. Serverless Connection Exhaustion
492
+
493
+ - **Symptom**: "FATAL: remaining connection slots are reserved for non-replication superuser connections" under modest traffic.
494
+ - **Root Cause**: Serverless/Edge functions opening new DB connection pools per invoked instance.
495
+ - **Fix**: Use a connection pooler like PgBouncer or managed pooling (Supabase connection pool, AWS RDS Proxy, Prisma Accelerate).
496
+
497
+ ## 2. Cache Invalidation Drift
498
+
499
+ - **Symptom**: Users see stale, outdated data after making updates.
500
+ - **Root Cause**: Updates to database do not invalidate related cache keys, or TTLs are set to infinite.
501
+ - **Fix**: Invalidate cache keys explicitly on write in the same transactional flow, and always set defensive TTLs.
502
+
503
+ ## 3. Lack of Rate Limiting and Backpressure
504
+
505
+ - **Symptom**: Backend crashes or slows to a crawl during traffic spikes or bot scraping.
506
+ - **Root Cause**: Unthrottled public endpoints without token-bucket or sliding-window rate limiting.
507
+ - **Fix**: Add rate-limiting middleware (Redis-backed sliding window) at the API gateway / Edge layer.
@@ -0,0 +1,157 @@
1
+ # Testing
2
+
3
+ ## Overview
4
+
5
+ Testing strategy across unit, component, integration, and end-to-end testing suites using Vitest, React Testing Library, and Playwright.
6
+
7
+ ## When to Use
8
+
9
+ Activate for any task involving unit tests, integration tests, E2E testing, TDD/BDD workflows, or fixing regression bugs.
10
+
11
+ ## Rules & Patterns
12
+
13
+ ### ️ The ContextOS Testing Pyramid
14
+
15
+ ```
16
+ /\
17
+ /E2E\ 10% — Playwright (Critical user journeys, auth, checkout)
18
+ /-----\
19
+ / Integ \ 20% — API & Component Integration (RTL + MSW / Supertest)
20
+ /---------\
21
+ / Unit \ 70% — Pure functions, Domain Entities, Utils (Vitest)
22
+ /-------------\
23
+ ```
24
+
25
+ ### Negative Constraints (What NOT to Do)
26
+
27
+ 1. **NEVER mock internal implementation details**: Mock ONLY external I/O boundaries (HTTP network requests via MSW, Database via test containers or in-memory DB).
28
+ 2. **NEVER test implementation details**: In React Testing Library, query by user-facing roles (`getByRole`, `getByLabelText`), NEVER by CSS selectors or internal component state.
29
+ 3. **NEVER write assertions without an expected failure mode**: Each test must test a single logical behavior and fail if that behavior breaks.
30
+ 4. **NEVER leave flaky tests or arbitrary sleep (`await delay(1000)`)**: Always use `waitFor()` or explicit event triggers with timeouts.
31
+ 5. **NEVER share mutable state between tests**: Every test must have isolated state via `beforeEach()` setup and clean reset.
32
+
33
+ ### AAA Standard Pattern
34
+
35
+ ```typescript
36
+ describe('Feature / Unit', () => {
37
+ it('should achieve expected outcome when given specific condition', async () => {
38
+ // 1. ARRANGE
39
+ const user = createTestUser({ role: 'admin' });
40
+ // 2. ACT
41
+ const result = await processOrder(user, sampleCart);
42
+ // 3. ASSERT
43
+ expect(result.status).toBe('confirmed');
44
+ });
45
+ });
46
+ ```
47
+
48
+ ## Code Examples
49
+
50
+ See `EXAMPLES.md` for detailed anti-patterns and production testing code.
51
+
52
+ ## Validation Checklist
53
+
54
+ - [ ] Tests follow Arrange-Act-Assert (AAA) structure
55
+ - [ ] No brittle CSS selectors or private state inspections
56
+ - [ ] Mocks isolated strictly to network/IO boundaries (MSW)
57
+ - [ ] Fast execution (< 5s for unit suite) with zero flaky sleeps
58
+
59
+ ## Common Mistakes
60
+
61
+ - Over-mocking modules instead of running real pure logic. See `TROUBLESHOOTING.md`.
62
+
63
+ ## Integration Notes
64
+
65
+ Interacts directly with `engineering-workflow` (Verify phase), `react`, and `typescript`.
66
+
67
+
68
+ # Testing Examples — Anti-patterns vs ContextOS Standard
69
+
70
+ ## Example 1: React Component Testing
71
+
72
+ ### Anti-pattern: Anti-pattern (Brittle query & implementation coupling)
73
+
74
+ ```typescript
75
+ // BAD: querying by CSS class or test-id and testing internal state
76
+ test('submits form', async () => {
77
+ const wrapper = render(<LoginForm />);
78
+ const input = wrapper.container.querySelector('.email-input');
79
+ fireEvent.change(input, { target: { value: 'user@test.com' } });
80
+ fireEvent.click(wrapper.container.querySelector('#submit-btn'));
81
+ expect(wrapper.state().isSubmitted).toBe(true); // Brittle!
82
+ });
83
+ ```
84
+
85
+ ### Best practice: ContextOS Standard (User-centric role queries & userEvent)
86
+
87
+ ```typescript
88
+ // GOOD: user-facing roles, userEvent, async wait
89
+ import { render, screen } from '@testing-library/react';
90
+ import userEvent from '@testing-library/user-event';
91
+ import { LoginForm } from './LoginForm';
92
+
93
+ test('submits form with valid user credentials', async () => {
94
+ const user = userEvent.setup();
95
+ const onSubmit = vi.fn();
96
+ render(<LoginForm onSubmit={onSubmit} />);
97
+
98
+ await user.type(screen.getByLabelText(/email address/i), 'user@test.com');
99
+ await user.type(screen.getByLabelText(/password/i), 'SecureP@ss123!');
100
+ await user.click(screen.getByRole('button', { name: /sign in/i }));
101
+
102
+ expect(onSubmit).toHaveBeenCalledWith({
103
+ email: 'user@test.com',
104
+ password: 'SecureP@ss123!'
105
+ });
106
+ expect(screen.queryByRole('alert')).not.toBeInTheDocument();
107
+ });
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Example 2: API Mocking with MSW (Mock Service Worker)
113
+
114
+ ### Anti-pattern: Anti-pattern (Hardcoded global fetch monkey-patching)
115
+
116
+ ```typescript
117
+ // BAD: globally overwriting fetch breaks other tests and hides actual contract
118
+ global.fetch = vi.fn().mockResolvedValue({
119
+ json: () => Promise.resolve({ data: 'ok' })
120
+ });
121
+ ```
122
+
123
+ ### Best practice: ContextOS Standard (Network boundary mocking)
124
+
125
+ ```typescript
126
+ // GOOD: declarative MSW network handler
127
+ import { http, HttpResponse } from 'msw';
128
+ import { setupServer } from 'msw/node';
129
+
130
+ export const server = setupServer(
131
+ http.get('/api/users/:id', ({ params }) => {
132
+ if (params.id === '404') {
133
+ return new HttpResponse(null, { status: 404 });
134
+ }
135
+ return HttpResponse.json({ id: params.id, name: 'Alice Smith' });
136
+ })
137
+ );
138
+ ```
139
+
140
+ # Testing Troubleshooting Guide
141
+
142
+ ## Common Issues & Fixes
143
+
144
+ ### 1. `act(...)` warning in React Testing Library
145
+
146
+ - **Cause**: An asynchronous state update triggered after the test completed.
147
+ - **Fix**: Ensure all async operations are awaited using `await waitFor(() => ...)` or `await screen.findByRole(...)`.
148
+
149
+ ### 2. Tests pass in isolation but fail in concurrent test runs
150
+
151
+ - **Cause**: Shared in-memory state or un-reset singleton.
152
+ - **Fix**: Reset all mocks and in-memory databases in `beforeEach(() => vi.clearAllMocks())` and `afterEach(() => cleanup())`.
153
+
154
+ ### 3. Playwright timeout waiting for selector
155
+
156
+ - **Cause**: Element is animating or blocked behind a modal/overlay.
157
+ - **Fix**: Use web-first assertions like `await expect(page.getByRole('button')).toBeVisible()` which automatically retry until timeout.