timsquad 2.1.0 → 3.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.
Files changed (438) hide show
  1. package/README.ko.md +288 -0
  2. package/README.md +170 -763
  3. package/dist/commands/compile.d.ts +3 -0
  4. package/dist/commands/compile.d.ts.map +1 -0
  5. package/dist/commands/compile.js +170 -0
  6. package/dist/commands/compile.js.map +1 -0
  7. package/dist/commands/daemon.d.ts +7 -0
  8. package/dist/commands/daemon.d.ts.map +1 -0
  9. package/dist/commands/daemon.js +229 -0
  10. package/dist/commands/daemon.js.map +1 -0
  11. package/dist/commands/feedback.d.ts +9 -0
  12. package/dist/commands/feedback.d.ts.map +1 -1
  13. package/dist/commands/feedback.js +235 -14
  14. package/dist/commands/feedback.js.map +1 -1
  15. package/dist/commands/full.js +2 -2
  16. package/dist/commands/full.js.map +1 -1
  17. package/dist/commands/init.d.ts.map +1 -1
  18. package/dist/commands/init.js +118 -22
  19. package/dist/commands/init.js.map +1 -1
  20. package/dist/commands/knowledge.d.ts +3 -0
  21. package/dist/commands/knowledge.d.ts.map +1 -0
  22. package/dist/commands/knowledge.js +316 -0
  23. package/dist/commands/knowledge.js.map +1 -0
  24. package/dist/commands/log.d.ts +27 -0
  25. package/dist/commands/log.d.ts.map +1 -1
  26. package/dist/commands/log.js +965 -0
  27. package/dist/commands/log.js.map +1 -1
  28. package/dist/commands/meta-index.d.ts +3 -0
  29. package/dist/commands/meta-index.d.ts.map +1 -0
  30. package/dist/commands/meta-index.js +401 -0
  31. package/dist/commands/meta-index.js.map +1 -0
  32. package/dist/commands/metrics.d.ts.map +1 -1
  33. package/dist/commands/metrics.js +239 -4
  34. package/dist/commands/metrics.js.map +1 -1
  35. package/dist/commands/retro.js +154 -6
  36. package/dist/commands/retro.js.map +1 -1
  37. package/dist/commands/skills.d.ts +12 -0
  38. package/dist/commands/skills.d.ts.map +1 -0
  39. package/dist/commands/skills.js +231 -0
  40. package/dist/commands/skills.js.map +1 -0
  41. package/dist/commands/upgrade.d.ts +8 -0
  42. package/dist/commands/upgrade.d.ts.map +1 -0
  43. package/dist/commands/upgrade.js +292 -0
  44. package/dist/commands/upgrade.js.map +1 -0
  45. package/dist/commands/workflow.d.ts +3 -0
  46. package/dist/commands/workflow.d.ts.map +1 -0
  47. package/dist/commands/workflow.js +607 -0
  48. package/dist/commands/workflow.js.map +1 -0
  49. package/dist/daemon/context-writer.d.ts +16 -0
  50. package/dist/daemon/context-writer.d.ts.map +1 -0
  51. package/dist/daemon/context-writer.js +35 -0
  52. package/dist/daemon/context-writer.js.map +1 -0
  53. package/dist/daemon/entry.d.ts +7 -0
  54. package/dist/daemon/entry.d.ts.map +1 -0
  55. package/dist/daemon/entry.js +17 -0
  56. package/dist/daemon/entry.js.map +1 -0
  57. package/dist/daemon/event-queue.d.ts +52 -0
  58. package/dist/daemon/event-queue.d.ts.map +1 -0
  59. package/dist/daemon/event-queue.js +255 -0
  60. package/dist/daemon/event-queue.js.map +1 -0
  61. package/dist/daemon/file-watcher.d.ts +19 -0
  62. package/dist/daemon/file-watcher.d.ts.map +1 -0
  63. package/dist/daemon/file-watcher.js +87 -0
  64. package/dist/daemon/file-watcher.js.map +1 -0
  65. package/dist/daemon/index.d.ts +29 -0
  66. package/dist/daemon/index.d.ts.map +1 -0
  67. package/dist/daemon/index.js +296 -0
  68. package/dist/daemon/index.js.map +1 -0
  69. package/dist/daemon/jsonl-watcher.d.ts +49 -0
  70. package/dist/daemon/jsonl-watcher.d.ts.map +1 -0
  71. package/dist/daemon/jsonl-watcher.js +258 -0
  72. package/dist/daemon/jsonl-watcher.js.map +1 -0
  73. package/dist/daemon/meta-cache.d.ts +63 -0
  74. package/dist/daemon/meta-cache.d.ts.map +1 -0
  75. package/dist/daemon/meta-cache.js +249 -0
  76. package/dist/daemon/meta-cache.js.map +1 -0
  77. package/dist/daemon/session-state.d.ts +19 -0
  78. package/dist/daemon/session-state.d.ts.map +1 -0
  79. package/dist/daemon/session-state.js +132 -0
  80. package/dist/daemon/session-state.js.map +1 -0
  81. package/dist/daemon/shutdown.d.ts +21 -0
  82. package/dist/daemon/shutdown.d.ts.map +1 -0
  83. package/dist/daemon/shutdown.js +164 -0
  84. package/dist/daemon/shutdown.js.map +1 -0
  85. package/dist/index.js +24 -3
  86. package/dist/index.js.map +1 -1
  87. package/dist/lib/agent-composer.d.ts +38 -0
  88. package/dist/lib/agent-composer.d.ts.map +1 -0
  89. package/dist/lib/agent-composer.js +128 -0
  90. package/dist/lib/agent-composer.js.map +1 -0
  91. package/dist/lib/agent-generator.d.ts +22 -0
  92. package/dist/lib/agent-generator.d.ts.map +1 -0
  93. package/dist/lib/agent-generator.js +150 -0
  94. package/dist/lib/agent-generator.js.map +1 -0
  95. package/dist/lib/ast-parser.d.ts +11 -0
  96. package/dist/lib/ast-parser.d.ts.map +1 -0
  97. package/dist/lib/ast-parser.js +282 -0
  98. package/dist/lib/ast-parser.js.map +1 -0
  99. package/dist/lib/compile-rules.d.ts +66 -0
  100. package/dist/lib/compile-rules.d.ts.map +1 -0
  101. package/dist/lib/compile-rules.js +114 -0
  102. package/dist/lib/compile-rules.js.map +1 -0
  103. package/dist/lib/compiler.d.ts +105 -0
  104. package/dist/lib/compiler.d.ts.map +1 -0
  105. package/dist/lib/compiler.js +368 -0
  106. package/dist/lib/compiler.js.map +1 -0
  107. package/dist/lib/config.d.ts +7 -2
  108. package/dist/lib/config.d.ts.map +1 -1
  109. package/dist/lib/config.js +34 -3
  110. package/dist/lib/config.js.map +1 -1
  111. package/dist/lib/meta-index.d.ts +19 -0
  112. package/dist/lib/meta-index.d.ts.map +1 -0
  113. package/dist/lib/meta-index.js +573 -0
  114. package/dist/lib/meta-index.js.map +1 -0
  115. package/dist/lib/project.js +1 -1
  116. package/dist/lib/project.js.map +1 -1
  117. package/dist/lib/skill-generator.d.ts +32 -0
  118. package/dist/lib/skill-generator.d.ts.map +1 -0
  119. package/dist/lib/skill-generator.js +187 -0
  120. package/dist/lib/skill-generator.js.map +1 -0
  121. package/dist/lib/template.d.ts +16 -2
  122. package/dist/lib/template.d.ts.map +1 -1
  123. package/dist/lib/template.js +115 -20
  124. package/dist/lib/template.js.map +1 -1
  125. package/dist/lib/ui-index.d.ts +12 -0
  126. package/dist/lib/ui-index.d.ts.map +1 -0
  127. package/dist/lib/ui-index.js +239 -0
  128. package/dist/lib/ui-index.js.map +1 -0
  129. package/dist/lib/ui-parser.d.ts +12 -0
  130. package/dist/lib/ui-parser.d.ts.map +1 -0
  131. package/dist/lib/ui-parser.js +472 -0
  132. package/dist/lib/ui-parser.js.map +1 -0
  133. package/dist/lib/update-check.d.ts +6 -0
  134. package/dist/lib/update-check.d.ts.map +1 -0
  135. package/dist/lib/update-check.js +121 -0
  136. package/dist/lib/update-check.js.map +1 -0
  137. package/dist/lib/upgrade-backup.d.ts +33 -0
  138. package/dist/lib/upgrade-backup.d.ts.map +1 -0
  139. package/dist/lib/upgrade-backup.js +101 -0
  140. package/dist/lib/upgrade-backup.js.map +1 -0
  141. package/dist/lib/version.d.ts +19 -0
  142. package/dist/lib/version.d.ts.map +1 -0
  143. package/dist/lib/version.js +35 -0
  144. package/dist/lib/version.js.map +1 -0
  145. package/dist/lib/workflow-state.d.ts +48 -0
  146. package/dist/lib/workflow-state.d.ts.map +1 -0
  147. package/dist/lib/workflow-state.js +67 -0
  148. package/dist/lib/workflow-state.js.map +1 -0
  149. package/dist/types/config.d.ts +103 -2
  150. package/dist/types/config.d.ts.map +1 -1
  151. package/dist/types/config.js +184 -9
  152. package/dist/types/config.js.map +1 -1
  153. package/dist/types/feedback.d.ts +7 -0
  154. package/dist/types/feedback.d.ts.map +1 -1
  155. package/dist/types/feedback.js +1 -1
  156. package/dist/types/feedback.js.map +1 -1
  157. package/dist/types/index.d.ts +3 -0
  158. package/dist/types/index.d.ts.map +1 -1
  159. package/dist/types/index.js +3 -0
  160. package/dist/types/index.js.map +1 -1
  161. package/dist/types/meta-index.d.ts +146 -0
  162. package/dist/types/meta-index.d.ts.map +1 -0
  163. package/dist/types/meta-index.js +7 -0
  164. package/dist/types/meta-index.js.map +1 -0
  165. package/dist/types/project.d.ts +19 -3
  166. package/dist/types/project.d.ts.map +1 -1
  167. package/dist/types/project.js +23 -0
  168. package/dist/types/project.js.map +1 -1
  169. package/dist/types/task-log.d.ts +208 -0
  170. package/dist/types/task-log.d.ts.map +1 -0
  171. package/dist/types/task-log.js +6 -0
  172. package/dist/types/task-log.js.map +1 -0
  173. package/dist/types/ui-meta.d.ts +118 -0
  174. package/dist/types/ui-meta.d.ts.map +1 -0
  175. package/dist/types/ui-meta.js +7 -0
  176. package/dist/types/ui-meta.js.map +1 -0
  177. package/package.json +12 -4
  178. package/templates/base/agents/base/tsq-architect.md +68 -0
  179. package/templates/base/agents/base/tsq-dba.md +56 -0
  180. package/templates/base/agents/base/tsq-designer.md +72 -0
  181. package/templates/base/agents/base/tsq-developer.md +67 -0
  182. package/templates/base/agents/base/tsq-qa.md +55 -0
  183. package/templates/base/agents/base/tsq-security.md +65 -0
  184. package/templates/base/agents/overlays/domain/general-web/_common.md +11 -0
  185. package/templates/base/agents/overlays/domain/mobile/_common.md +13 -0
  186. package/templates/base/agents/overlays/platform/claude-code.md +12 -0
  187. package/templates/base/config.template.yaml +213 -0
  188. package/templates/base/knowledge/checklists/accessibility.md +37 -0
  189. package/templates/base/knowledge/checklists/architecture-review.md +28 -0
  190. package/templates/base/knowledge/checklists/database-standards.md +84 -0
  191. package/templates/base/knowledge/checklists/design-reference.md +97 -0
  192. package/templates/base/knowledge/checklists/security.md +50 -0
  193. package/templates/base/knowledge/checklists/ssot-validation.md +19 -0
  194. package/templates/base/knowledge/domains/_template.md +16 -0
  195. package/templates/base/knowledge/platforms/_template.md +16 -0
  196. package/templates/base/knowledge/templates/sequence-report.md +44 -0
  197. package/templates/base/knowledge/templates/task-result.md +105 -0
  198. package/templates/base/skills/_template/SKILL.md +59 -0
  199. package/templates/base/skills/_template/references/_template.md +35 -0
  200. package/templates/base/skills/_template/rules/_sections.md +34 -0
  201. package/templates/base/skills/_template/rules/_template.md +32 -0
  202. package/templates/base/skills/_template/scripts/_template.sh +31 -0
  203. package/templates/base/skills/architecture/SKILL.md +54 -0
  204. package/templates/base/skills/architecture/references/adr-template.md +50 -0
  205. package/templates/base/skills/architecture/references/api-design.md +64 -0
  206. package/templates/base/skills/backend/node/SKILL.md +81 -0
  207. package/templates/base/skills/backend/node/rules/async-patterns.md +81 -0
  208. package/templates/base/skills/backend/node/rules/deployment.md +33 -0
  209. package/templates/base/skills/backend/node/rules/env-config.md +41 -0
  210. package/templates/base/skills/backend/node/rules/error-handling.md +83 -0
  211. package/templates/base/skills/backend/node/rules/hono-app-setup.md +98 -0
  212. package/templates/base/skills/backend/node/rules/jwt-auth.md +76 -0
  213. package/templates/base/skills/backend/node/rules/middleware.md +56 -0
  214. package/templates/base/skills/backend/node/rules/testing.md +82 -0
  215. package/templates/base/skills/coding/SKILL.md +47 -0
  216. package/templates/base/skills/coding/rules/patterns.md +81 -0
  217. package/templates/base/skills/controller/SKILL.md +111 -0
  218. package/templates/base/skills/controller/references/README.md +35 -0
  219. package/templates/base/skills/controller/rules/README.md +18 -0
  220. package/templates/base/skills/database/SKILL.md +98 -0
  221. package/templates/base/skills/database/prisma/SKILL.md +57 -0
  222. package/templates/base/skills/database/prisma/rules/queries.md +133 -0
  223. package/templates/base/skills/database/prisma/rules/schema-design.md +80 -0
  224. package/templates/base/skills/frontend/nextjs/SKILL.md +59 -0
  225. package/templates/base/skills/frontend/nextjs/rules/app-router.md +138 -0
  226. package/templates/base/skills/frontend/react/SKILL.md +86 -0
  227. package/templates/base/skills/frontend/react/rules/_sections.md +88 -0
  228. package/templates/base/skills/frontend/react/rules/anti-patterns.md +67 -0
  229. package/templates/base/skills/frontend/react/rules/async-api-routes.md +38 -0
  230. package/templates/base/skills/frontend/react/rules/async-defer-await.md +80 -0
  231. package/templates/base/skills/frontend/react/rules/async-dependencies.md +36 -0
  232. package/templates/base/skills/frontend/react/rules/async-parallel.md +28 -0
  233. package/templates/base/skills/frontend/react/rules/async-suspense-boundaries.md +99 -0
  234. package/templates/base/skills/frontend/react/rules/bundle-barrel-imports.md +59 -0
  235. package/templates/base/skills/frontend/react/rules/bundle-defer-third-party.md +49 -0
  236. package/templates/base/skills/frontend/react/rules/bundle-dynamic-imports.md +35 -0
  237. package/templates/base/skills/frontend/react/rules/component-conventions.md +74 -0
  238. package/templates/base/skills/frontend/react/rules/js-combine-iterations.md +32 -0
  239. package/templates/base/skills/frontend/react/rules/js-early-exit.md +50 -0
  240. package/templates/base/skills/frontend/react/rules/js-index-maps.md +37 -0
  241. package/templates/base/skills/frontend/react/rules/js-set-map-lookups.md +24 -0
  242. package/templates/base/skills/frontend/react/rules/rendering-conditional-render.md +40 -0
  243. package/templates/base/skills/frontend/react/rules/rendering-content-visibility.md +38 -0
  244. package/templates/base/skills/frontend/react/rules/rendering-hoist-jsx.md +46 -0
  245. package/templates/base/skills/frontend/react/rules/rerender-defer-reads.md +39 -0
  246. package/templates/base/skills/frontend/react/rules/rerender-derived-state.md +29 -0
  247. package/templates/base/skills/frontend/react/rules/rerender-memo.md +44 -0
  248. package/templates/base/skills/frontend/react/rules/rerender-transitions.md +40 -0
  249. package/templates/base/skills/frontend/react/rules/server-after-nonblocking.md +73 -0
  250. package/templates/base/skills/frontend/react/rules/server-cache-react.md +26 -0
  251. package/templates/base/skills/frontend/react/rules/server-parallel-fetching.md +79 -0
  252. package/templates/base/skills/frontend/react/rules/state-location.md +55 -0
  253. package/templates/base/skills/methodology/bdd/SKILL.md +69 -0
  254. package/templates/base/skills/methodology/bdd/rules/gherkin-patterns.md +113 -0
  255. package/templates/base/skills/methodology/ddd/SKILL.md +74 -0
  256. package/templates/base/skills/methodology/ddd/rules/strategic-patterns.md +98 -0
  257. package/templates/base/skills/methodology/debugging/SKILL.md +60 -0
  258. package/templates/base/skills/methodology/debugging/references/root-cause-tracing.md +84 -0
  259. package/templates/base/skills/methodology/tdd/SKILL.md +66 -0
  260. package/templates/base/skills/methodology/tdd/rules/real-world-example.md +88 -0
  261. package/templates/base/skills/methodology/tdd/rules/techniques.md +185 -0
  262. package/templates/base/skills/mobile/dart/SKILL.md +69 -0
  263. package/templates/base/skills/mobile/dart/rules/async-patterns.md +112 -0
  264. package/templates/base/skills/mobile/dart/rules/code-style.md +96 -0
  265. package/templates/base/skills/mobile/dart/rules/null-safety.md +84 -0
  266. package/templates/base/skills/mobile/dart/rules/type-system.md +111 -0
  267. package/templates/base/skills/mobile/flutter/SKILL.md +89 -0
  268. package/templates/base/skills/mobile/flutter/ci-cd/SKILL.md +82 -0
  269. package/templates/base/skills/mobile/flutter/ci-cd/references/ci-cd-pipeline.md +314 -0
  270. package/templates/base/skills/mobile/flutter/ci-cd/rules/code-signing.md +106 -0
  271. package/templates/base/skills/mobile/flutter/ci-cd/rules/codemagic-setup.md +116 -0
  272. package/templates/base/skills/mobile/flutter/ci-cd/rules/fastlane-setup.md +105 -0
  273. package/templates/base/skills/mobile/flutter/ci-cd/rules/github-actions.md +112 -0
  274. package/templates/base/skills/mobile/flutter/ci-cd/rules/store-deployment.md +106 -0
  275. package/templates/base/skills/mobile/flutter/ci-cd/rules/versioning.md +107 -0
  276. package/templates/base/skills/mobile/flutter/i18n/SKILL.md +78 -0
  277. package/templates/base/skills/mobile/flutter/i18n/references/i18n-architecture.md +225 -0
  278. package/templates/base/skills/mobile/flutter/i18n/rules/arb-files.md +182 -0
  279. package/templates/base/skills/mobile/flutter/i18n/rules/locale-switching.md +226 -0
  280. package/templates/base/skills/mobile/flutter/i18n/rules/localization-setup.md +137 -0
  281. package/templates/base/skills/mobile/flutter/i18n/rules/plural-gender.md +159 -0
  282. package/templates/base/skills/mobile/flutter/i18n/rules/text-direction.md +199 -0
  283. package/templates/base/skills/mobile/flutter/monitoring/SKILL.md +81 -0
  284. package/templates/base/skills/mobile/flutter/monitoring/references/monitoring-architecture.md +269 -0
  285. package/templates/base/skills/mobile/flutter/monitoring/rules/analytics.md +227 -0
  286. package/templates/base/skills/mobile/flutter/monitoring/rules/crashlytics-setup.md +195 -0
  287. package/templates/base/skills/mobile/flutter/monitoring/rules/logging.md +258 -0
  288. package/templates/base/skills/mobile/flutter/monitoring/rules/performance-monitoring.md +248 -0
  289. package/templates/base/skills/mobile/flutter/monitoring/rules/sentry-integration.md +249 -0
  290. package/templates/base/skills/mobile/flutter/networking/SKILL.md +88 -0
  291. package/templates/base/skills/mobile/flutter/networking/references/api-client-architecture.md +305 -0
  292. package/templates/base/skills/mobile/flutter/networking/rules/caching.md +212 -0
  293. package/templates/base/skills/mobile/flutter/networking/rules/connectivity.md +213 -0
  294. package/templates/base/skills/mobile/flutter/networking/rules/dio-setup.md +159 -0
  295. package/templates/base/skills/mobile/flutter/networking/rules/error-handling.md +209 -0
  296. package/templates/base/skills/mobile/flutter/networking/rules/interceptors.md +205 -0
  297. package/templates/base/skills/mobile/flutter/networking/rules/retrofit-patterns.md +194 -0
  298. package/templates/base/skills/mobile/flutter/push-notifications/SKILL.md +87 -0
  299. package/templates/base/skills/mobile/flutter/push-notifications/references/notification-architecture.md +340 -0
  300. package/templates/base/skills/mobile/flutter/push-notifications/references/platform-setup.md +286 -0
  301. package/templates/base/skills/mobile/flutter/push-notifications/rules/background-processing.md +308 -0
  302. package/templates/base/skills/mobile/flutter/push-notifications/rules/deep-linking.md +217 -0
  303. package/templates/base/skills/mobile/flutter/push-notifications/rules/fcm-setup.md +164 -0
  304. package/templates/base/skills/mobile/flutter/push-notifications/rules/local-notifications.md +262 -0
  305. package/templates/base/skills/mobile/flutter/push-notifications/rules/notification-handling.md +210 -0
  306. package/templates/base/skills/mobile/flutter/push-notifications/rules/notification-permissions.md +246 -0
  307. package/templates/base/skills/mobile/flutter/push-notifications/rules/rich-notifications.md +320 -0
  308. package/templates/base/skills/mobile/flutter/references/freezed-patterns.md +162 -0
  309. package/templates/base/skills/mobile/flutter/references/project-structure.md +170 -0
  310. package/templates/base/skills/mobile/flutter/rules/animations.md +112 -0
  311. package/templates/base/skills/mobile/flutter/rules/architecture.md +121 -0
  312. package/templates/base/skills/mobile/flutter/rules/navigation-routing.md +117 -0
  313. package/templates/base/skills/mobile/flutter/rules/performance.md +112 -0
  314. package/templates/base/skills/mobile/flutter/rules/platform-adaptive.md +126 -0
  315. package/templates/base/skills/mobile/flutter/rules/state-management.md +110 -0
  316. package/templates/base/skills/mobile/flutter/rules/testing.md +131 -0
  317. package/templates/base/skills/mobile/flutter/rules/widget-conventions.md +122 -0
  318. package/templates/base/skills/mobile/flutter/security/SKILL.md +86 -0
  319. package/templates/base/skills/mobile/flutter/security/references/mobile-security-checklist.md +168 -0
  320. package/templates/base/skills/mobile/flutter/security/rules/api-key-protection.md +206 -0
  321. package/templates/base/skills/mobile/flutter/security/rules/authentication.md +248 -0
  322. package/templates/base/skills/mobile/flutter/security/rules/data-protection.md +271 -0
  323. package/templates/base/skills/mobile/flutter/security/rules/obfuscation.md +213 -0
  324. package/templates/base/skills/mobile/flutter/security/rules/secure-storage.md +171 -0
  325. package/templates/base/skills/mobile/flutter/security/rules/ssl-pinning.md +197 -0
  326. package/templates/base/skills/planning/SKILL.md +58 -0
  327. package/templates/base/skills/planning/references/prd-guide.md +47 -0
  328. package/templates/base/skills/planning/references/requirements-guide.md +46 -0
  329. package/templates/base/skills/prompt-engineering/SKILL.md +103 -0
  330. package/templates/base/skills/retrospective/SKILL.md +102 -0
  331. package/templates/base/skills/security/SKILL.md +55 -0
  332. package/templates/base/skills/security/rules/owasp-examples.md +119 -0
  333. package/templates/base/skills/security/scripts/check-secrets.sh +55 -0
  334. package/templates/base/skills/testing/SKILL.md +63 -0
  335. package/templates/base/skills/testing/references/testing-patterns.md +103 -0
  336. package/templates/base/skills/tsq-protocol/SKILL.md +51 -0
  337. package/templates/base/skills/typescript/SKILL.md +67 -0
  338. package/templates/base/skills/typescript/rules/type-patterns.md +135 -0
  339. package/templates/base/skills/typescript/rules/utility-types.md +76 -0
  340. package/templates/base/skills/ui-design/SKILL.md +70 -0
  341. package/templates/{common → base}/timsquad/feedback/routing-rules.yaml +1 -1
  342. package/templates/{common → base}/timsquad/retrospective/metrics/metrics-schema.json +46 -1
  343. package/templates/platforms/claude-code/CLAUDE.md.template +89 -0
  344. package/templates/platforms/claude-code/rules/adr-rules.md +32 -0
  345. package/templates/platforms/claude-code/rules/feedback-routing.md +18 -0
  346. package/templates/platforms/claude-code/rules/phase-management.md +23 -0
  347. package/templates/platforms/claude-code/rules/reporting-format.md +26 -0
  348. package/templates/platforms/claude-code/rules/sequence-management.md +72 -0
  349. package/templates/platforms/claude-code/rules/workspace-sync.md +33 -0
  350. package/templates/platforms/claude-code/scripts/completion-guard.sh +57 -0
  351. package/templates/platforms/claude-code/scripts/phase-guard.sh +79 -0
  352. package/templates/platforms/claude-code/settings.json +98 -0
  353. package/templates/project-types/api-backend/config.yaml +227 -0
  354. package/templates/project-types/api-backend/process/workflow.xml +214 -0
  355. package/templates/project-types/fintech/config.yaml +151 -0
  356. package/templates/project-types/fintech/process/workflow.xml +316 -0
  357. package/templates/project-types/infra/config.yaml +327 -0
  358. package/templates/project-types/infra/process/workflow.xml +296 -0
  359. package/templates/project-types/mobile-app/config.yaml +123 -0
  360. package/templates/project-types/mobile-app/process/workflow.xml +191 -0
  361. package/templates/project-types/platform/config.yaml +254 -0
  362. package/templates/project-types/platform/process/workflow.xml +254 -0
  363. package/templates/project-types/web-app/config.yaml +198 -0
  364. package/templates/project-types/web-app/process/workflow.xml +210 -0
  365. package/templates/project-types/web-service/config.yaml +136 -0
  366. package/templates/project-types/web-service/process/workflow.xml +184 -0
  367. package/templates/common/CLAUDE.md.template +0 -254
  368. package/templates/common/claude/agents/tsq-dba.md +0 -311
  369. package/templates/common/claude/agents/tsq-designer.md +0 -323
  370. package/templates/common/claude/agents/tsq-developer.md +0 -177
  371. package/templates/common/claude/agents/tsq-planner.md +0 -190
  372. package/templates/common/claude/agents/tsq-prompter.md +0 -356
  373. package/templates/common/claude/agents/tsq-qa.md +0 -168
  374. package/templates/common/claude/agents/tsq-retro.md +0 -193
  375. package/templates/common/claude/agents/tsq-security.md +0 -221
  376. package/templates/common/claude/hooks/auto-metrics.sh +0 -165
  377. package/templates/common/claude/hooks/auto-worklog.sh +0 -245
  378. package/templates/common/claude/hooks/event-logger.sh +0 -208
  379. package/templates/common/claude/settings.json +0 -86
  380. package/templates/common/claude/skills/architecture/SKILL.md +0 -123
  381. package/templates/common/claude/skills/backend/node/SKILL.md +0 -1015
  382. package/templates/common/claude/skills/coding/SKILL.md +0 -171
  383. package/templates/common/claude/skills/database/prisma/SKILL.md +0 -357
  384. package/templates/common/claude/skills/frontend/nextjs/SKILL.md +0 -279
  385. package/templates/common/claude/skills/frontend/react/SKILL.md +0 -1729
  386. package/templates/common/claude/skills/methodology/bdd/SKILL.md +0 -234
  387. package/templates/common/claude/skills/methodology/ddd/SKILL.md +0 -311
  388. package/templates/common/claude/skills/methodology/tdd/SKILL.md +0 -512
  389. package/templates/common/claude/skills/planning/SKILL.md +0 -90
  390. package/templates/common/claude/skills/security/SKILL.md +0 -234
  391. package/templates/common/claude/skills/testing/SKILL.md +0 -146
  392. package/templates/common/claude/skills/typescript/SKILL.md +0 -435
  393. package/templates/common/config.template.yaml +0 -132
  394. /package/templates/{common → base}/timsquad/architectures/clean/ARCHITECTURE.md +0 -0
  395. /package/templates/{common → base}/timsquad/architectures/clean/backend.xml +0 -0
  396. /package/templates/{common → base}/timsquad/architectures/clean/frontend.xml +0 -0
  397. /package/templates/{common → base}/timsquad/architectures/fsd/ARCHITECTURE.md +0 -0
  398. /package/templates/{common → base}/timsquad/architectures/fsd/frontend.xml +0 -0
  399. /package/templates/{common → base}/timsquad/architectures/hexagonal/ARCHITECTURE.md +0 -0
  400. /package/templates/{common → base}/timsquad/architectures/hexagonal/backend.xml +0 -0
  401. /package/templates/{common → base}/timsquad/constraints/competency-framework.xml +0 -0
  402. /package/templates/{common → base}/timsquad/constraints/ssot-schema.xml +0 -0
  403. /package/templates/{common → base}/timsquad/feedback/feedback-router.sh +0 -0
  404. /package/templates/{common → base}/timsquad/generators/data-design.xml +0 -0
  405. /package/templates/{common → base}/timsquad/generators/prd.xml +0 -0
  406. /package/templates/{common → base}/timsquad/generators/requirements.xml +0 -0
  407. /package/templates/{common → base}/timsquad/generators/service-spec.xml +0 -0
  408. /package/templates/{common → base}/timsquad/logs/_example.md +0 -0
  409. /package/templates/{common → base}/timsquad/logs/_template.md +0 -0
  410. /package/templates/{common → base}/timsquad/patterns/cqrs.xml +0 -0
  411. /package/templates/{common → base}/timsquad/patterns/event-sourcing.xml +0 -0
  412. /package/templates/{common → base}/timsquad/patterns/repository.xml +0 -0
  413. /package/templates/{common → base}/timsquad/process/phase-checklist.yaml +0 -0
  414. /package/templates/{common → base}/timsquad/process/state-machine.xml +0 -0
  415. /package/templates/{common → base}/timsquad/process/validation-rules.xml +0 -0
  416. /package/templates/{common → base}/timsquad/process/workflow-base.xml +0 -0
  417. /package/templates/{common → base}/timsquad/retrospective/cycle-report.template.md +0 -0
  418. /package/templates/{common → base}/timsquad/retrospective/patterns/failure-patterns.md +0 -0
  419. /package/templates/{common → base}/timsquad/retrospective/patterns/success-patterns.md +0 -0
  420. /package/templates/{common → base}/timsquad/retrospective/retrospective-config.xml +0 -0
  421. /package/templates/{common → base}/timsquad/retrospective/retrospective-state.xml +0 -0
  422. /package/templates/{common → base}/timsquad/ssot/adr/ADR-000-template.md +0 -0
  423. /package/templates/{common → base}/timsquad/ssot/adr/ADR-001-example.md +0 -0
  424. /package/templates/{common → base}/timsquad/ssot/data-design.template.md +0 -0
  425. /package/templates/{common → base}/timsquad/ssot/deployment-spec.template.md +0 -0
  426. /package/templates/{common → base}/timsquad/ssot/env-config.template.md +0 -0
  427. /package/templates/{common → base}/timsquad/ssot/error-codes.template.md +0 -0
  428. /package/templates/{common → base}/timsquad/ssot/functional-spec.template.md +0 -0
  429. /package/templates/{common → base}/timsquad/ssot/glossary.template.md +0 -0
  430. /package/templates/{common → base}/timsquad/ssot/integration-spec.template.md +0 -0
  431. /package/templates/{common → base}/timsquad/ssot/planning.template.md +0 -0
  432. /package/templates/{common → base}/timsquad/ssot/prd.template.md +0 -0
  433. /package/templates/{common → base}/timsquad/ssot/requirements.template.md +0 -0
  434. /package/templates/{common → base}/timsquad/ssot/security-spec.template.md +0 -0
  435. /package/templates/{common → base}/timsquad/ssot/service-spec.template.md +0 -0
  436. /package/templates/{common → base}/timsquad/ssot/test-spec.template.md +0 -0
  437. /package/templates/{common → base}/timsquad/ssot/ui-ux-spec.template.md +0 -0
  438. /package/templates/{common → base}/timsquad/state/workspace.xml +0 -0
@@ -0,0 +1,212 @@
1
+ ---
2
+ title: HTTP Caching Strategy
3
+ impact: MEDIUM
4
+ impactDescription: "캐시 미사용 → 불필요한 네트워크 호출, 느린 로딩, 데이터 요금 낭비"
5
+ tags: cache, dio-cache-interceptor, etag, offline, performance
6
+ ---
7
+
8
+ ## HTTP Caching Strategy
9
+
10
+ **Impact: MEDIUM (캐시 미사용 → 불필요한 네트워크 호출, 느린 로딩, 데이터 요금 낭비)**
11
+
12
+ dio_cache_interceptor로 HTTP 응답 캐시.
13
+ ETag/Last-Modified 검증, 오프라인 fallback, 정책별 캐시 전략.
14
+
15
+ ### 의존성
16
+
17
+ ```yaml
18
+ # pubspec.yaml
19
+ dependencies:
20
+ dio: ^5.7.0
21
+ dio_cache_interceptor: ^3.5.0
22
+ dio_cache_interceptor_hive_store: ^3.2.0 # 영구 저장소
23
+ ```
24
+
25
+ ### 캐시 인터셉터 설정
26
+
27
+ **Incorrect (캐시 없이 매번 네트워크 호출):**
28
+ ```dart
29
+ final dio = Dio();
30
+ // → 동일 데이터 반복 요청, 배터리 + 데이터 낭비
31
+ // → 오프라인 시 데이터 표시 불가
32
+ ```
33
+
34
+ **Correct (dio_cache_interceptor 통합):**
35
+ ```dart
36
+ /// 캐시 저장소 초기화
37
+ Future<CacheStore> initCacheStore() async {
38
+ final dir = await getApplicationDocumentsDirectory();
39
+ return HiveCacheStore(
40
+ '${dir.path}/http_cache',
41
+ hiveBoxName: 'dio_cache',
42
+ );
43
+ }
44
+
45
+ /// 캐시 옵션 팩토리
46
+ class CacheConfig {
47
+ /// 기본 캐시 정책 — 네트워크 우선, 실패 시 캐시
48
+ static CacheOptions defaultPolicy(CacheStore store) {
49
+ return CacheOptions(
50
+ store: store,
51
+ policy: CachePolicy.request, // 네트워크 요청 + 캐시 갱신
52
+ maxStale: const Duration(days: 7), // 오프라인 시 7일간 캐시 유효
53
+ hitCacheOnErrorExcept: [401, 403], // 에러 시 캐시 반환 (인증 에러 제외)
54
+ );
55
+ }
56
+
57
+ /// 강제 캐시 — 네트워크 미사용 (빠른 로딩)
58
+ static CacheOptions forceCache(CacheStore store) {
59
+ return CacheOptions(
60
+ store: store,
61
+ policy: CachePolicy.forceCache,
62
+ );
63
+ }
64
+
65
+ /// 캐시 무시 — 항상 최신 데이터
66
+ static CacheOptions noCache(CacheStore store) {
67
+ return CacheOptions(
68
+ store: store,
69
+ policy: CachePolicy.noCache,
70
+ );
71
+ }
72
+
73
+ /// stale-while-revalidate — 캐시 먼저 반환, 백그라운드 갱신
74
+ static CacheOptions refreshIfStale(CacheStore store) {
75
+ return CacheOptions(
76
+ store: store,
77
+ policy: CachePolicy.refreshForceCache,
78
+ maxStale: const Duration(hours: 1),
79
+ );
80
+ }
81
+ }
82
+
83
+ /// Dio에 캐시 인터셉터 추가
84
+ final cacheStoreProvider = FutureProvider<CacheStore>((ref) async {
85
+ return await initCacheStore();
86
+ });
87
+
88
+ final cacheDioProvider = Provider<Dio>((ref) {
89
+ final dio = ref.watch(dioProvider);
90
+ final cacheStore = ref.watch(cacheStoreProvider).valueOrNull;
91
+
92
+ if (cacheStore != null) {
93
+ final cacheOptions = CacheConfig.defaultPolicy(cacheStore);
94
+ dio.interceptors.add(
95
+ DioCacheInterceptor(options: cacheOptions),
96
+ );
97
+ }
98
+
99
+ return dio;
100
+ });
101
+ ```
102
+
103
+ ### 요청별 캐시 정책 오버라이드
104
+
105
+ ```dart
106
+ /// API에서 요청별 캐시 정책 지정
107
+ class ProductRepository {
108
+ final Dio _dio;
109
+ final CacheStore _cacheStore;
110
+
111
+ ProductRepository({required Dio dio, required CacheStore cacheStore})
112
+ : _dio = dio,
113
+ _cacheStore = cacheStore;
114
+
115
+ /// 상품 목록 — 기본 캐시 (네트워크 + 캐시 갱신)
116
+ Future<Result<List<Product>>> getProducts() async {
117
+ try {
118
+ final response = await _dio.get('/products');
119
+ return Success(_parseProducts(response.data));
120
+ } on DioException catch (e) {
121
+ return Failure(NetworkFailure.fromDioException(e));
122
+ }
123
+ }
124
+
125
+ /// 상품 상세 — 캐시 우선 (자주 변경되지 않음)
126
+ Future<Result<Product>> getProduct(String id) async {
127
+ try {
128
+ final response = await _dio.get(
129
+ '/products/$id',
130
+ options: CacheConfig.refreshIfStale(_cacheStore).toOptions(),
131
+ );
132
+ return Success(Product.fromJson(response.data));
133
+ } on DioException catch (e) {
134
+ return Failure(NetworkFailure.fromDioException(e));
135
+ }
136
+ }
137
+
138
+ /// 결제 정보 — 캐시 금지 (항상 최신)
139
+ Future<Result<PaymentInfo>> getPaymentInfo() async {
140
+ try {
141
+ final response = await _dio.get(
142
+ '/payment/info',
143
+ options: CacheConfig.noCache(_cacheStore).toOptions(),
144
+ );
145
+ return Success(PaymentInfo.fromJson(response.data));
146
+ } on DioException catch (e) {
147
+ return Failure(NetworkFailure.fromDioException(e));
148
+ }
149
+ }
150
+ }
151
+ ```
152
+
153
+ ### ETag / Last-Modified 활용
154
+
155
+ ```dart
156
+ // dio_cache_interceptor가 자동 처리하는 HTTP 헤더:
157
+ //
158
+ // 서버 응답:
159
+ // ETag: "abc123"
160
+ // Last-Modified: Wed, 15 Jan 2026 10:00:00 GMT
161
+ // Cache-Control: max-age=3600
162
+ //
163
+ // 클라이언트 재요청 (자동):
164
+ // If-None-Match: "abc123"
165
+ // If-Modified-Since: Wed, 15 Jan 2026 10:00:00 GMT
166
+ //
167
+ // 서버 응답:
168
+ // 304 Not Modified → 캐시된 데이터 사용 (전송 비용 없음)
169
+ // 200 OK → 새 데이터로 캐시 갱신
170
+
171
+ // 서버가 ETag/Last-Modified를 지원하면 자동으로 최적화됨
172
+ // 별도 클라이언트 코드 필요 없음
173
+ ```
174
+
175
+ ### 캐시 관리
176
+
177
+ ```dart
178
+ /// 캐시 클리어 (로그아웃 시, 디버깅 시)
179
+ class CacheManager {
180
+ final CacheStore _store;
181
+
182
+ CacheManager({required CacheStore store}) : _store = store;
183
+
184
+ /// 전체 캐시 클리어
185
+ Future<void> clearAll() async {
186
+ await _store.clean();
187
+ }
188
+
189
+ /// 특정 URL 캐시 삭제
190
+ Future<void> invalidate(String url) async {
191
+ await _store.delete(CacheOptions.defaultCacheKeyBuilder(
192
+ RequestOptions(path: url),
193
+ ));
194
+ }
195
+ }
196
+
197
+ final cacheManagerProvider = Provider<CacheManager>((ref) {
198
+ final store = ref.watch(cacheStoreProvider).valueOrNull;
199
+ if (store == null) throw StateError('Cache store not initialized');
200
+ return CacheManager(store: store);
201
+ });
202
+ ```
203
+
204
+ ### 규칙
205
+
206
+ - GET 요청에만 캐시 적용 — POST/PUT/DELETE는 캐시 금지
207
+ - 기본 정책: 네트워크 우선 + 실패 시 캐시 fallback (`hitCacheOnErrorExcept`)
208
+ - 결제/인증 관련 API는 `CachePolicy.noCache` 강제
209
+ - `maxStale: 7일` — 오프라인 시 캐시 유효 기간
210
+ - 인증 에러(401, 403)는 캐시 반환 제외 — 만료 토큰으로 캐시된 데이터 방지
211
+ - 로그아웃 시 전체 캐시 클리어 — 사용자 데이터 잔류 방지
212
+ - HiveCacheStore 사용 — 앱 재시작 후에도 캐시 유지 (메모리 캐시보다 안정)
@@ -0,0 +1,213 @@
1
+ ---
2
+ title: Connectivity & Offline Queue
3
+ impact: HIGH
4
+ impactDescription: "오프라인 미처리 → 요청 유실, 무한 로딩, 사용자 혼란"
5
+ tags: connectivity, offline, queue, retry, connectivity-plus
6
+ ---
7
+
8
+ ## Connectivity & Offline Queue
9
+
10
+ **Impact: HIGH (오프라인 미처리 → 요청 유실, 무한 로딩, 사용자 혼란)**
11
+
12
+ connectivity_plus로 네트워크 상태 실시간 감지.
13
+ 오프라인 시 요청 큐잉, 연결 복구 시 자동 재시도.
14
+
15
+ ### 의존성
16
+
17
+ ```yaml
18
+ # pubspec.yaml
19
+ dependencies:
20
+ connectivity_plus: ^6.1.0
21
+ flutter_riverpod: ^2.6.0
22
+ ```
23
+
24
+ ### ConnectivityNotifier
25
+
26
+ **Incorrect (단발 체크만):**
27
+ ```dart
28
+ Future<bool> isOnline() async {
29
+ final result = await Connectivity().checkConnectivity();
30
+ return result != ConnectivityResult.none;
31
+ // → 상태 변화 미감지, UI 갱신 없음
32
+ }
33
+ ```
34
+
35
+ **Correct (Riverpod + 실시간 스트림):**
36
+ ```dart
37
+ /// 연결 상태 열거형
38
+ enum NetworkStatus { online, offline }
39
+
40
+ /// 연결 상태 Provider — 앱 전역 스트림
41
+ final connectivityProvider =
42
+ StreamNotifierProvider<ConnectivityNotifier, NetworkStatus>(
43
+ ConnectivityNotifier.new,
44
+ );
45
+
46
+ class ConnectivityNotifier extends StreamNotifier<NetworkStatus> {
47
+ @override
48
+ Stream<NetworkStatus> build() {
49
+ return Connectivity().onConnectivityChanged.map((results) {
50
+ final hasConnection = results.any((r) => r != ConnectivityResult.none);
51
+ return hasConnection ? NetworkStatus.online : NetworkStatus.offline;
52
+ });
53
+ }
54
+ }
55
+
56
+ /// 현재 온라인 여부 (동기 체크용)
57
+ final isOnlineProvider = Provider<bool>((ref) {
58
+ final status = ref.watch(connectivityProvider).valueOrNull;
59
+ return status == NetworkStatus.online;
60
+ });
61
+ ```
62
+
63
+ ### 오프라인 배너 UI
64
+
65
+ ```dart
66
+ /// 오프라인 상태 배너 — 앱 최상단에 배치
67
+ class OfflineBanner extends ConsumerWidget {
68
+ const OfflineBanner({super.key});
69
+
70
+ @override
71
+ Widget build(BuildContext context, WidgetRef ref) {
72
+ final isOnline = ref.watch(isOnlineProvider);
73
+
74
+ if (isOnline) return const SizedBox.shrink();
75
+
76
+ return MaterialBanner(
77
+ content: const Text('인터넷 연결이 끊어졌습니다'),
78
+ leading: const Icon(Icons.wifi_off, color: Colors.white),
79
+ backgroundColor: Colors.red.shade700,
80
+ actions: [
81
+ TextButton(
82
+ onPressed: () async {
83
+ // 수동 재시도
84
+ final result = await Connectivity().checkConnectivity();
85
+ if (result.any((r) => r != ConnectivityResult.none)) {
86
+ ref.invalidate(connectivityProvider);
87
+ }
88
+ },
89
+ child: const Text('재시도', style: TextStyle(color: Colors.white)),
90
+ ),
91
+ ],
92
+ );
93
+ }
94
+ }
95
+ ```
96
+
97
+ ### 오프라인 요청 큐
98
+
99
+ ```dart
100
+ /// 오프라인 시 보류된 요청
101
+ class PendingRequest {
102
+ final String id;
103
+ final RequestOptions options;
104
+ final DateTime createdAt;
105
+ final int retryCount;
106
+
107
+ const PendingRequest({
108
+ required this.id,
109
+ required this.options,
110
+ required this.createdAt,
111
+ this.retryCount = 0,
112
+ });
113
+
114
+ bool get isExpired =>
115
+ DateTime.now().difference(createdAt) > const Duration(hours: 1);
116
+ }
117
+
118
+ /// 오프라인 큐 매니저
119
+ class OfflineQueueManager {
120
+ final Dio _dio;
121
+ final List<PendingRequest> _queue = [];
122
+ bool _isProcessing = false;
123
+
124
+ OfflineQueueManager({required Dio dio}) : _dio = dio;
125
+
126
+ /// 오프라인 시 큐에 추가
127
+ void enqueue(RequestOptions options) {
128
+ _queue.add(PendingRequest(
129
+ id: const Uuid().v4(),
130
+ options: options,
131
+ createdAt: DateTime.now(),
132
+ ));
133
+ }
134
+
135
+ /// 연결 복구 시 큐 처리
136
+ Future<void> processQueue() async {
137
+ if (_isProcessing || _queue.isEmpty) return;
138
+ _isProcessing = true;
139
+
140
+ try {
141
+ // 만료된 요청 제거
142
+ _queue.removeWhere((r) => r.isExpired);
143
+
144
+ final pending = List<PendingRequest>.from(_queue);
145
+ for (final request in pending) {
146
+ try {
147
+ await _dio.fetch(request.options);
148
+ _queue.remove(request);
149
+ } on DioException {
150
+ // 실패 → 큐에 유지, 다음 복구 시 재시도
151
+ break; // 첫 실패 시 중단 (아직 불안정할 수 있음)
152
+ }
153
+ }
154
+ } finally {
155
+ _isProcessing = false;
156
+ }
157
+ }
158
+
159
+ int get pendingCount => _queue.length;
160
+ bool get hasPending => _queue.isNotEmpty;
161
+ }
162
+
163
+ /// Provider
164
+ final offlineQueueProvider = Provider<OfflineQueueManager>((ref) {
165
+ final queue = OfflineQueueManager(dio: ref.watch(dioProvider));
166
+
167
+ // 온라인 복구 시 자동 처리
168
+ ref.listen(connectivityProvider, (prev, next) {
169
+ if (next.valueOrNull == NetworkStatus.online) {
170
+ queue.processQueue();
171
+ }
172
+ });
173
+
174
+ return queue;
175
+ });
176
+ ```
177
+
178
+ ### Connectivity Interceptor
179
+
180
+ ```dart
181
+ /// Dio 인터셉터로 오프라인 감지 (선택적)
182
+ class ConnectivityInterceptor extends Interceptor {
183
+ final OfflineQueueManager _queueManager;
184
+ final Ref _ref;
185
+
186
+ ConnectivityInterceptor({
187
+ required OfflineQueueManager queueManager,
188
+ required Ref ref,
189
+ }) : _queueManager = queueManager,
190
+ _ref = ref;
191
+
192
+ @override
193
+ void onError(DioException err, ErrorInterceptorHandler handler) {
194
+ if (err.type == DioExceptionType.connectionError) {
195
+ // POST/PUT 요청을 큐에 추가 (GET은 캐시 fallback)
196
+ if (err.requestOptions.method != 'GET') {
197
+ _queueManager.enqueue(err.requestOptions);
198
+ }
199
+ }
200
+ handler.next(err);
201
+ }
202
+ }
203
+ ```
204
+
205
+ ### 규칙
206
+
207
+ - `connectivity_plus` 스트림으로 실시간 감지 — 단발 체크 금지
208
+ - 오프라인 배너를 앱 최상단에 항상 표시
209
+ - 오프라인 큐: POST/PUT/DELETE 요청만 큐잉 (GET은 캐시 fallback)
210
+ - 만료된 큐 요청 자동 제거 (1시간 기본)
211
+ - 연결 복구 시 큐 자동 처리 — `ref.listen(connectivityProvider)` 활용
212
+ - 큐 처리 중 실패 시 중단 (네트워크 아직 불안정할 수 있음)
213
+ - Wi-Fi 연결 ≠ 인터넷 접속 — 실제 HTTP 핑으로 검증 고려
@@ -0,0 +1,159 @@
1
+ ---
2
+ title: Dio Setup & Configuration
3
+ impact: CRITICAL
4
+ impactDescription: "잘못된 Dio 설정 → 타임아웃 누락, 인스턴스 중복 생성, 메모리 낭비"
5
+ tags: dio, http, setup, riverpod, baseOptions
6
+ ---
7
+
8
+ ## Dio Setup & Configuration
9
+
10
+ **Impact: CRITICAL (잘못된 Dio 설정 → 타임아웃 누락, 인스턴스 중복 생성, 메모리 낭비)**
11
+
12
+ Dio 싱글톤 인스턴스 관리, BaseOptions 설정, 환경별 분리.
13
+ 모든 네트워크 통신의 기반이 되는 핵심 인프라.
14
+
15
+ ### 의존성
16
+
17
+ ```yaml
18
+ # pubspec.yaml
19
+ dependencies:
20
+ dio: ^5.7.0
21
+ flutter_riverpod: ^2.6.0
22
+ # 또는 riverpod (non-Flutter)
23
+ ```
24
+
25
+ ### Dio 인스턴스 관리
26
+
27
+ **Incorrect (매번 새 인스턴스 생성):**
28
+ ```dart
29
+ class UserRepository {
30
+ Future<User> getUser(String id) async {
31
+ // 매 호출마다 Dio 생성 → 인터셉터 미적용, 커넥션 풀 미활용
32
+ final dio = Dio();
33
+ final response = await dio.get('https://api.example.com/users/$id');
34
+ return User.fromJson(response.data);
35
+ }
36
+ }
37
+ ```
38
+
39
+ **Correct (Riverpod Provider로 싱글톤 관리):**
40
+ ```dart
41
+ /// 환경 설정
42
+ enum AppEnvironment { dev, staging, prod }
43
+
44
+ class AppConfig {
45
+ final AppEnvironment environment;
46
+ final String baseUrl;
47
+
48
+ const AppConfig({required this.environment, required this.baseUrl});
49
+
50
+ static const dev = AppConfig(
51
+ environment: AppEnvironment.dev,
52
+ baseUrl: 'https://dev-api.example.com/v1',
53
+ );
54
+
55
+ static const staging = AppConfig(
56
+ environment: AppEnvironment.staging,
57
+ baseUrl: 'https://staging-api.example.com/v1',
58
+ );
59
+
60
+ static const prod = AppConfig(
61
+ environment: AppEnvironment.prod,
62
+ baseUrl: 'https://api.example.com/v1',
63
+ );
64
+ }
65
+
66
+ /// 앱 설정 Provider
67
+ final appConfigProvider = Provider<AppConfig>((ref) {
68
+ // main.dart에서 ProviderScope overrides로 주입
69
+ return AppConfig.dev;
70
+ });
71
+
72
+ /// Dio Provider — 앱 전역 싱글톤
73
+ final dioProvider = Provider<Dio>((ref) {
74
+ final config = ref.watch(appConfigProvider);
75
+
76
+ final dio = Dio(BaseOptions(
77
+ baseUrl: config.baseUrl,
78
+ connectTimeout: const Duration(seconds: 15),
79
+ receiveTimeout: const Duration(seconds: 15),
80
+ sendTimeout: const Duration(seconds: 15),
81
+ headers: {
82
+ 'Content-Type': 'application/json',
83
+ 'Accept': 'application/json',
84
+ },
85
+ validateStatus: (status) => status != null && status < 500,
86
+ ));
87
+
88
+ // 인터셉터 체인 (순서 중요)
89
+ dio.interceptors.addAll([
90
+ ref.watch(authInterceptorProvider),
91
+ ref.watch(retryInterceptorProvider),
92
+ if (config.environment == AppEnvironment.dev)
93
+ ref.watch(loggingInterceptorProvider),
94
+ ref.watch(errorTransformInterceptorProvider),
95
+ ]);
96
+
97
+ return dio;
98
+ });
99
+ ```
100
+
101
+ ### main.dart 환경 주입
102
+
103
+ ```dart
104
+ Future<void> main() async {
105
+ WidgetsFlutterBinding.ensureInitialized();
106
+
107
+ // 환경 결정 (빌드 플래그, .env 등)
108
+ const config = String.fromEnvironment('ENV') == 'prod'
109
+ ? AppConfig.prod
110
+ : AppConfig.dev;
111
+
112
+ runApp(
113
+ ProviderScope(
114
+ overrides: [
115
+ appConfigProvider.overrideWithValue(config),
116
+ ],
117
+ child: const MyApp(),
118
+ ),
119
+ );
120
+ }
121
+ ```
122
+
123
+ ### BaseOptions 상세
124
+
125
+ ```dart
126
+ BaseOptions(
127
+ // 서버 기본 URL — 환경별 분리 필수
128
+ baseUrl: 'https://api.example.com/v1',
129
+
130
+ // 타임아웃 — 15초 권장 (모바일 네트워크 고려)
131
+ connectTimeout: const Duration(seconds: 15),
132
+ receiveTimeout: const Duration(seconds: 15),
133
+ sendTimeout: const Duration(seconds: 15),
134
+
135
+ // 기본 헤더
136
+ headers: {
137
+ 'Content-Type': 'application/json',
138
+ 'Accept': 'application/json',
139
+ 'X-App-Version': appVersion, // 서버 호환성 체크용
140
+ 'X-Platform': Platform.isIOS ? 'ios' : 'android',
141
+ },
142
+
143
+ // 응답 타입
144
+ responseType: ResponseType.json,
145
+
146
+ // 상태 코드 검증 — 5xx는 DioException으로 처리
147
+ validateStatus: (status) => status != null && status < 500,
148
+ )
149
+ ```
150
+
151
+ ### 규칙
152
+
153
+ - Dio 인스턴스는 Riverpod Provider로 싱글톤 관리 — 직접 생성 금지
154
+ - `connectTimeout`, `receiveTimeout`, `sendTimeout` 모두 15초 설정
155
+ - `baseUrl` 은 환경별 분리 (dev/staging/prod) — 하드코딩 금지
156
+ - `Content-Type: application/json` 기본 헤더
157
+ - `validateStatus` — 5xx만 에러, 4xx는 응답 데이터로 처리
158
+ - Interceptor 등록은 Dio Provider 내에서 순서대로
159
+ - Logging 인터셉터는 dev 환경에서만 활성화