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,258 @@
1
+ ---
2
+ title: Structured Logging & Sensitive Data Masking
3
+ impact: MEDIUM
4
+ impactDescription: "로그 미관리 → 프로덕션 디버깅 불가, 민감 데이터 유출 위험"
5
+ tags: logger, structured-logging, masking, remote-logging, log-level
6
+ ---
7
+
8
+ ## Structured Logging & Sensitive Data Masking
9
+
10
+ **Impact: MEDIUM (로그 미관리 → 프로덕션 디버깅 불가, 민감 데이터 유출 위험)**
11
+
12
+ logger 패키지를 활용한 레벨별 로깅, JSON 구조화된 로그 출력,
13
+ 릴리스 빌드 레벨 필터, 원격 로깅 연동, 민감 데이터 마스킹.
14
+
15
+ ### 의존성
16
+
17
+ ```yaml
18
+ # pubspec.yaml
19
+ dependencies:
20
+ logger: ^2.5.0
21
+ ```
22
+
23
+ ### 기본 설정
24
+
25
+ **Incorrect (print/debugPrint 직접 사용):**
26
+ ```dart
27
+ print('User logged in: ${user.email}');
28
+ debugPrint('API response: ${response.data}');
29
+ // → 레벨 구분 없음, 릴리스에서 제거 불가, PII 노출
30
+ ```
31
+
32
+ **Correct (구조화된 로거):**
33
+ ```dart
34
+ class AppLogger {
35
+ static final AppLogger instance = AppLogger._();
36
+ AppLogger._();
37
+
38
+ late final Logger _logger;
39
+ final List<LogOutput> _outputs = [];
40
+
41
+ void initialize({bool isRelease = false}) {
42
+ _logger = Logger(
43
+ filter: isRelease ? ProductionFilter() : DevelopFilter(),
44
+ printer: isRelease
45
+ ? JsonPrinter() // 프로덕션: JSON 구조화
46
+ : PrettyPrinter( // 개발: 색상 + 포맷팅
47
+ methodCount: 2,
48
+ errorMethodCount: 8,
49
+ lineLength: 120,
50
+ colors: true,
51
+ printEmojis: false,
52
+ dateTimeFormat: DateTimeFormat.onlyTimeAndSinceStart,
53
+ ),
54
+ output: MultiOutput(_outputs),
55
+ );
56
+ }
57
+
58
+ void addOutput(LogOutput output) => _outputs.add(output);
59
+
60
+ void verbose(String message, [dynamic error, StackTrace? stack]) =>
61
+ _logger.t(message, error: error, stackTrace: stack);
62
+
63
+ void debug(String message, [dynamic error, StackTrace? stack]) =>
64
+ _logger.d(message, error: error, stackTrace: stack);
65
+
66
+ void info(String message, [dynamic error, StackTrace? stack]) =>
67
+ _logger.i(message, error: error, stackTrace: stack);
68
+
69
+ void warning(String message, [dynamic error, StackTrace? stack]) =>
70
+ _logger.w(message, error: error, stackTrace: stack);
71
+
72
+ void error(String message, [dynamic error, StackTrace? stack]) =>
73
+ _logger.e(message, error: error, stackTrace: stack);
74
+
75
+ void fatal(String message, [dynamic error, StackTrace? stack]) =>
76
+ _logger.f(message, error: error, stackTrace: stack);
77
+ }
78
+
79
+ // 사용
80
+ final log = AppLogger.instance;
81
+ log.info('User logged in', null, null);
82
+ log.error('API call failed', exception, stackTrace);
83
+ ```
84
+
85
+ ### 릴리스 빌드 필터
86
+
87
+ ```dart
88
+ /// 프로덕션: warning 이상만 출력
89
+ class ProductionFilter extends LogFilter {
90
+ @override
91
+ bool shouldLog(LogEvent event) {
92
+ return event.level.index >= Level.warning.index;
93
+ }
94
+ }
95
+
96
+ /// 개발: 모든 레벨 출력
97
+ class DevelopFilter extends LogFilter {
98
+ @override
99
+ bool shouldLog(LogEvent event) {
100
+ return true;
101
+ }
102
+ }
103
+ ```
104
+
105
+ ### JSON 구조화 프린터
106
+
107
+ ```dart
108
+ /// 프로덕션용 JSON 출력 (원격 로깅 시스템과 호환)
109
+ class JsonPrinter extends LogPrinter {
110
+ @override
111
+ List<String> log(LogEvent event) {
112
+ final output = {
113
+ 'timestamp': DateTime.now().toUtc().toIso8601String(),
114
+ 'level': event.level.name,
115
+ 'message': event.message,
116
+ };
117
+
118
+ if (event.error != null) {
119
+ output['error'] = event.error.toString();
120
+ }
121
+ if (event.stackTrace != null) {
122
+ output['stackTrace'] = event.stackTrace.toString();
123
+ }
124
+
125
+ return [jsonEncode(output)];
126
+ }
127
+ }
128
+ ```
129
+
130
+ ### 원격 로깅
131
+
132
+ ```dart
133
+ /// Sentry breadcrumb로 원격 로깅
134
+ class SentryLogOutput extends LogOutput {
135
+ @override
136
+ void output(OutputEvent event) {
137
+ // warning 이상만 Sentry breadcrumb으로 전송
138
+ if (event.level.index < Level.warning.index) return;
139
+
140
+ final level = switch (event.level) {
141
+ Level.warning => SentryLevel.warning,
142
+ Level.error => SentryLevel.error,
143
+ Level.fatal => SentryLevel.fatal,
144
+ _ => SentryLevel.info,
145
+ };
146
+
147
+ Sentry.addBreadcrumb(Breadcrumb(
148
+ message: event.lines.join('\n'),
149
+ level: level,
150
+ category: 'app.log',
151
+ timestamp: DateTime.now().toUtc(),
152
+ ));
153
+ }
154
+ }
155
+
156
+ /// Crashlytics 커스텀 로그
157
+ class CrashlyticsLogOutput extends LogOutput {
158
+ @override
159
+ void output(OutputEvent event) {
160
+ if (event.level.index < Level.info.index) return;
161
+
162
+ // Crashlytics log → 크래시 발생 시 컨텍스트로 포함 (최대 64KB)
163
+ FirebaseCrashlytics.instance.log(
164
+ event.lines.join('\n'),
165
+ );
166
+ }
167
+ }
168
+
169
+ // 초기화 시 출력 추가
170
+ void initializeLogging() {
171
+ final log = AppLogger.instance;
172
+ log.initialize(isRelease: kReleaseMode);
173
+
174
+ if (kReleaseMode) {
175
+ log.addOutput(SentryLogOutput());
176
+ log.addOutput(CrashlyticsLogOutput());
177
+ }
178
+ }
179
+ ```
180
+
181
+ ### 민감 데이터 마스킹
182
+
183
+ ```dart
184
+ /// 민감 데이터 마스킹 유틸리티
185
+ class LogSanitizer {
186
+ static final _patterns = <RegExp, String>{
187
+ // 이메일
188
+ RegExp(r'[\w.+-]+@[\w-]+\.[\w.]+'):
189
+ '***@***.***',
190
+ // 전화번호
191
+ RegExp(r'\+?\d{10,15}'):
192
+ '***-****-****',
193
+ // 토큰/키 (Bearer, API key 등)
194
+ RegExp(r'(Bearer\s+|token[=:]\s*|api[_-]?key[=:]\s*)[A-Za-z0-9\-._~+/]+=*',
195
+ caseSensitive: false):
196
+ r'$1[REDACTED]',
197
+ // 카드 번호 (16자리)
198
+ RegExp(r'\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b'):
199
+ '****-****-****-****',
200
+ };
201
+
202
+ /// 문자열 내 민감 데이터 마스킹
203
+ static String sanitize(String input) {
204
+ var result = input;
205
+ for (final entry in _patterns.entries) {
206
+ result = result.replaceAll(entry.key, entry.value);
207
+ }
208
+ return result;
209
+ }
210
+
211
+ /// Map 내 민감 키 마스킹
212
+ static Map<String, dynamic> sanitizeMap(Map<String, dynamic> data) {
213
+ const sensitiveKeys = {
214
+ 'password', 'token', 'secret', 'api_key', 'apiKey',
215
+ 'authorization', 'credit_card', 'ssn', 'email', 'phone',
216
+ };
217
+
218
+ return data.map((key, value) {
219
+ if (sensitiveKeys.contains(key.toLowerCase())) {
220
+ return MapEntry(key, '[REDACTED]');
221
+ }
222
+ if (value is String) {
223
+ return MapEntry(key, sanitize(value));
224
+ }
225
+ if (value is Map<String, dynamic>) {
226
+ return MapEntry(key, sanitizeMap(value));
227
+ }
228
+ return MapEntry(key, value);
229
+ });
230
+ }
231
+ }
232
+
233
+ // HTTP 로깅에 마스킹 적용
234
+ class SanitizedLogInterceptor extends Interceptor {
235
+ @override
236
+ void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
237
+ final sanitizedHeaders = LogSanitizer.sanitizeMap(
238
+ options.headers.cast<String, dynamic>(),
239
+ );
240
+ AppLogger.instance.debug(
241
+ 'HTTP ${options.method} ${options.uri}\n'
242
+ 'Headers: $sanitizedHeaders',
243
+ );
244
+ handler.next(options);
245
+ }
246
+ }
247
+ ```
248
+
249
+ ### 규칙
250
+
251
+ - `print`/`debugPrint` 직접 사용 금지 → `AppLogger` 래퍼 사용
252
+ - 릴리스 빌드 → verbose/debug 레벨 비활성화 (ProductionFilter)
253
+ - 프로덕션 → JSON 구조화 출력 (원격 로깅 시스템 호환)
254
+ - 원격 로깅 → Sentry breadcrumb + Crashlytics log 연동
255
+ - warning 이상 → 원격 전송, info → Crashlytics 컨텍스트만
256
+ - 민감 데이터 → `LogSanitizer`로 마스킹 (토큰, PII, 카드번호)
257
+ - HTTP 로깅 → 헤더/바디 마스킹 후 출력
258
+ - 로그 레벨 가이드: verbose(개발 추적), debug(디버깅), info(흐름), warning(주의), error(복구 가능), fatal(복구 불가)
@@ -0,0 +1,248 @@
1
+ ---
2
+ title: Performance Monitoring & Custom Traces
3
+ impact: HIGH
4
+ impactDescription: "성능 미측정 → 느린 화면 방치, ANR/프리징 원인 파악 불가"
5
+ tags: firebase-performance, trace, http-metric, frame, startup
6
+ ---
7
+
8
+ ## Performance Monitoring & Custom Traces
9
+
10
+ **Impact: HIGH (성능 미측정 → 느린 화면 방치, ANR/프리징 원인 파악 불가)**
11
+
12
+ Firebase Performance Monitoring 초기화, custom trace, HTTP metric 수집,
13
+ 프레임 렌더링 모니터링, 앱 시작 시간 추적.
14
+
15
+ ### 의존성
16
+
17
+ ```yaml
18
+ # pubspec.yaml
19
+ dependencies:
20
+ firebase_core: ^3.8.0
21
+ firebase_performance: ^0.10.0
22
+ firebase_performance_dio: ^0.6.0 # dio 사용 시
23
+ ```
24
+
25
+ ### 초기화
26
+
27
+ ```dart
28
+ Future<void> main() async {
29
+ WidgetsFlutterBinding.ensureInitialized();
30
+ await Firebase.initializeApp();
31
+
32
+ // Performance Monitoring은 별도 초기화 불필요 (Firebase init 시 자동 활성화)
33
+ // 디버그 모드에서 비활성화 (선택)
34
+ if (kDebugMode) {
35
+ await FirebasePerformance.instance
36
+ .setPerformanceCollectionEnabled(false);
37
+ }
38
+
39
+ runApp(const ProviderScope(child: MyApp()));
40
+ }
41
+ ```
42
+
43
+ ### Custom Trace
44
+
45
+ **Incorrect (시작/종료 미매칭):**
46
+ ```dart
47
+ final trace = FirebasePerformance.instance.newTrace('load_data');
48
+ await trace.start();
49
+ await fetchData();
50
+ // trace.stop() 누락 → 데이터 미전송, 메모리 누수
51
+ ```
52
+
53
+ **Correct (안전한 trace 래핑):**
54
+ ```dart
55
+ class PerformanceService {
56
+ final FirebasePerformance _performance = FirebasePerformance.instance;
57
+
58
+ /// 안전한 trace 실행 (자동 start/stop)
59
+ Future<T> trace<T>(
60
+ String name,
61
+ Future<T> Function() operation, {
62
+ Map<String, String>? attributes,
63
+ Map<String, int>? metrics,
64
+ }) async {
65
+ final trace = _performance.newTrace(name);
66
+
67
+ // 속성 설정 (최대 5개)
68
+ attributes?.forEach((key, value) {
69
+ trace.putAttribute(key, value);
70
+ });
71
+
72
+ await trace.start();
73
+ try {
74
+ final result = await operation();
75
+
76
+ // 메트릭 설정 (최대 32개)
77
+ metrics?.forEach((key, value) {
78
+ trace.setMetric(key, value);
79
+ });
80
+
81
+ return result;
82
+ } catch (e) {
83
+ trace.putAttribute('error', e.runtimeType.toString());
84
+ rethrow;
85
+ } finally {
86
+ await trace.stop(); // 항상 stop 보장
87
+ }
88
+ }
89
+ }
90
+
91
+ // 사용 예시
92
+ final perfService = ref.read(performanceServiceProvider);
93
+ final matches = await perfService.trace(
94
+ 'fetch_matches',
95
+ () => matchRepository.getMatches(page: 1),
96
+ attributes: {'sport': 'tennis', 'region': 'sg'},
97
+ metrics: {'page': 1},
98
+ );
99
+ ```
100
+
101
+ ### 핵심 플로우 trace 예시
102
+
103
+ ```dart
104
+ /// 앱 시작 시간 추적
105
+ class AppStartupTrace {
106
+ static Trace? _trace;
107
+
108
+ static Future<void> start() async {
109
+ _trace = FirebasePerformance.instance.newTrace('app_startup');
110
+ await _trace?.start();
111
+ }
112
+
113
+ static Future<void> markMilestone(String name) async {
114
+ _trace?.putAttribute(name, DateTime.now().toIso8601String());
115
+ }
116
+
117
+ static Future<void> stop() async {
118
+ await _trace?.stop();
119
+ _trace = null;
120
+ }
121
+ }
122
+
123
+ // main.dart
124
+ Future<void> main() async {
125
+ await AppStartupTrace.start();
126
+ WidgetsFlutterBinding.ensureInitialized();
127
+ await AppStartupTrace.markMilestone('binding_initialized');
128
+
129
+ await Firebase.initializeApp();
130
+ await AppStartupTrace.markMilestone('firebase_initialized');
131
+
132
+ runApp(const ProviderScope(child: MyApp()));
133
+ }
134
+
135
+ // 첫 화면 렌더링 완료 시
136
+ class HomeScreen extends ConsumerStatefulWidget {
137
+ @override
138
+ ConsumerState<HomeScreen> createState() => _HomeScreenState();
139
+
140
+ @override
141
+ void initState() {
142
+ super.initState();
143
+ WidgetsBinding.instance.addPostFrameCallback((_) {
144
+ AppStartupTrace.stop(); // 첫 프레임 렌더링 완료
145
+ });
146
+ }
147
+ }
148
+ ```
149
+
150
+ ### HTTP Metric (Dio Interceptor)
151
+
152
+ ```dart
153
+ /// Dio에 Performance interceptor 추가
154
+ final dio = Dio()
155
+ ..interceptors.add(
156
+ DioFirebasePerformanceInterceptor(), // firebase_performance_dio
157
+ );
158
+
159
+ /// 또는 수동 HTTP metric
160
+ class PerformanceInterceptor extends Interceptor {
161
+ final Map<String, HttpMetric> _metrics = {};
162
+
163
+ @override
164
+ void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
165
+ final metric = FirebasePerformance.instance.newHttpMetric(
166
+ options.uri.toString(),
167
+ _toHttpMethod(options.method),
168
+ );
169
+ metric.start();
170
+ _metrics[options.hashCode.toString()] = metric;
171
+ handler.next(options);
172
+ }
173
+
174
+ @override
175
+ void onResponse(Response response, ResponseInterceptorHandler handler) {
176
+ final metric = _metrics.remove(response.requestOptions.hashCode.toString());
177
+ if (metric != null) {
178
+ metric
179
+ ..responseContentType = response.headers.value('content-type')
180
+ ..httpResponseCode = response.statusCode
181
+ ..responsePayloadSize = response.data.toString().length;
182
+ metric.stop();
183
+ }
184
+ handler.next(response);
185
+ }
186
+
187
+ @override
188
+ void onError(DioException err, ErrorInterceptorHandler handler) {
189
+ final metric = _metrics.remove(err.requestOptions.hashCode.toString());
190
+ if (metric != null) {
191
+ metric.httpResponseCode = err.response?.statusCode;
192
+ metric.putAttribute('error', err.type.name);
193
+ metric.stop();
194
+ }
195
+ handler.next(err);
196
+ }
197
+
198
+ HttpMethod _toHttpMethod(String method) {
199
+ return switch (method.toUpperCase()) {
200
+ 'GET' => HttpMethod.Get,
201
+ 'POST' => HttpMethod.Post,
202
+ 'PUT' => HttpMethod.Put,
203
+ 'DELETE' => HttpMethod.Delete,
204
+ 'PATCH' => HttpMethod.Patch,
205
+ _ => HttpMethod.Get,
206
+ };
207
+ }
208
+ }
209
+ ```
210
+
211
+ ### 프레임 렌더링 모니터링
212
+
213
+ ```dart
214
+ /// 느린 프레임 감지 (개발/QA용)
215
+ class FrameMonitor {
216
+ static void start() {
217
+ if (!kDebugMode) return;
218
+
219
+ WidgetsBinding.instance.addTimingsCallback((timings) {
220
+ for (final timing in timings) {
221
+ // 60fps 기준: 16.67ms 이상이면 느린 프레임
222
+ final buildDuration = timing.buildDuration.inMilliseconds;
223
+ final rasterDuration = timing.rasterDuration.inMilliseconds;
224
+ final totalDuration = timing.totalSpan.inMilliseconds;
225
+
226
+ if (totalDuration > 16) {
227
+ debugPrint(
228
+ 'Slow frame: total=${totalDuration}ms '
229
+ 'build=${buildDuration}ms raster=${rasterDuration}ms',
230
+ );
231
+ }
232
+ }
233
+ });
234
+ }
235
+ }
236
+ ```
237
+
238
+ ### 규칙
239
+
240
+ - Custom trace → `start()`/`stop()` 반드시 매칭 (try-finally 패턴)
241
+ - Trace 이름 → 소문자 + 언더스코어, 100자 이하
242
+ - Trace 속성 → 최대 5개 (key 32자, value 100자)
243
+ - Trace 메트릭 → 최대 32개 (정수값)
244
+ - HTTP metric → dio interceptor 또는 수동 래핑으로 API 응답 시간 수집
245
+ - 앱 시작 trace → main() 시작 ~ 첫 프레임 렌더링 완료
246
+ - 핵심 플로우 (로그인, 검색, 매치 생성) → custom trace 적용
247
+ - 디버그 모드 → `setPerformanceCollectionEnabled(false)` (선택)
248
+ - 프레임 모니터링 → 16ms (60fps) / 8ms (120fps) 초과 시 경고