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.
- package/README.ko.md +288 -0
- package/README.md +170 -763
- package/dist/commands/compile.d.ts +3 -0
- package/dist/commands/compile.d.ts.map +1 -0
- package/dist/commands/compile.js +170 -0
- package/dist/commands/compile.js.map +1 -0
- package/dist/commands/daemon.d.ts +7 -0
- package/dist/commands/daemon.d.ts.map +1 -0
- package/dist/commands/daemon.js +229 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/feedback.d.ts +9 -0
- package/dist/commands/feedback.d.ts.map +1 -1
- package/dist/commands/feedback.js +235 -14
- package/dist/commands/feedback.js.map +1 -1
- package/dist/commands/full.js +2 -2
- package/dist/commands/full.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +118 -22
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/knowledge.d.ts +3 -0
- package/dist/commands/knowledge.d.ts.map +1 -0
- package/dist/commands/knowledge.js +316 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/log.d.ts +27 -0
- package/dist/commands/log.d.ts.map +1 -1
- package/dist/commands/log.js +965 -0
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/meta-index.d.ts +3 -0
- package/dist/commands/meta-index.d.ts.map +1 -0
- package/dist/commands/meta-index.js +401 -0
- package/dist/commands/meta-index.js.map +1 -0
- package/dist/commands/metrics.d.ts.map +1 -1
- package/dist/commands/metrics.js +239 -4
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/retro.js +154 -6
- package/dist/commands/retro.js.map +1 -1
- package/dist/commands/skills.d.ts +12 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +231 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/upgrade.d.ts +8 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +292 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/workflow.d.ts +3 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +607 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/daemon/context-writer.d.ts +16 -0
- package/dist/daemon/context-writer.d.ts.map +1 -0
- package/dist/daemon/context-writer.js +35 -0
- package/dist/daemon/context-writer.js.map +1 -0
- package/dist/daemon/entry.d.ts +7 -0
- package/dist/daemon/entry.d.ts.map +1 -0
- package/dist/daemon/entry.js +17 -0
- package/dist/daemon/entry.js.map +1 -0
- package/dist/daemon/event-queue.d.ts +52 -0
- package/dist/daemon/event-queue.d.ts.map +1 -0
- package/dist/daemon/event-queue.js +255 -0
- package/dist/daemon/event-queue.js.map +1 -0
- package/dist/daemon/file-watcher.d.ts +19 -0
- package/dist/daemon/file-watcher.d.ts.map +1 -0
- package/dist/daemon/file-watcher.js +87 -0
- package/dist/daemon/file-watcher.js.map +1 -0
- package/dist/daemon/index.d.ts +29 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +296 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/jsonl-watcher.d.ts +49 -0
- package/dist/daemon/jsonl-watcher.d.ts.map +1 -0
- package/dist/daemon/jsonl-watcher.js +258 -0
- package/dist/daemon/jsonl-watcher.js.map +1 -0
- package/dist/daemon/meta-cache.d.ts +63 -0
- package/dist/daemon/meta-cache.d.ts.map +1 -0
- package/dist/daemon/meta-cache.js +249 -0
- package/dist/daemon/meta-cache.js.map +1 -0
- package/dist/daemon/session-state.d.ts +19 -0
- package/dist/daemon/session-state.d.ts.map +1 -0
- package/dist/daemon/session-state.js +132 -0
- package/dist/daemon/session-state.js.map +1 -0
- package/dist/daemon/shutdown.d.ts +21 -0
- package/dist/daemon/shutdown.d.ts.map +1 -0
- package/dist/daemon/shutdown.js +164 -0
- package/dist/daemon/shutdown.js.map +1 -0
- package/dist/index.js +24 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-composer.d.ts +38 -0
- package/dist/lib/agent-composer.d.ts.map +1 -0
- package/dist/lib/agent-composer.js +128 -0
- package/dist/lib/agent-composer.js.map +1 -0
- package/dist/lib/agent-generator.d.ts +22 -0
- package/dist/lib/agent-generator.d.ts.map +1 -0
- package/dist/lib/agent-generator.js +150 -0
- package/dist/lib/agent-generator.js.map +1 -0
- package/dist/lib/ast-parser.d.ts +11 -0
- package/dist/lib/ast-parser.d.ts.map +1 -0
- package/dist/lib/ast-parser.js +282 -0
- package/dist/lib/ast-parser.js.map +1 -0
- package/dist/lib/compile-rules.d.ts +66 -0
- package/dist/lib/compile-rules.d.ts.map +1 -0
- package/dist/lib/compile-rules.js +114 -0
- package/dist/lib/compile-rules.js.map +1 -0
- package/dist/lib/compiler.d.ts +105 -0
- package/dist/lib/compiler.d.ts.map +1 -0
- package/dist/lib/compiler.js +368 -0
- package/dist/lib/compiler.js.map +1 -0
- package/dist/lib/config.d.ts +7 -2
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +34 -3
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/meta-index.d.ts +19 -0
- package/dist/lib/meta-index.d.ts.map +1 -0
- package/dist/lib/meta-index.js +573 -0
- package/dist/lib/meta-index.js.map +1 -0
- package/dist/lib/project.js +1 -1
- package/dist/lib/project.js.map +1 -1
- package/dist/lib/skill-generator.d.ts +32 -0
- package/dist/lib/skill-generator.d.ts.map +1 -0
- package/dist/lib/skill-generator.js +187 -0
- package/dist/lib/skill-generator.js.map +1 -0
- package/dist/lib/template.d.ts +16 -2
- package/dist/lib/template.d.ts.map +1 -1
- package/dist/lib/template.js +115 -20
- package/dist/lib/template.js.map +1 -1
- package/dist/lib/ui-index.d.ts +12 -0
- package/dist/lib/ui-index.d.ts.map +1 -0
- package/dist/lib/ui-index.js +239 -0
- package/dist/lib/ui-index.js.map +1 -0
- package/dist/lib/ui-parser.d.ts +12 -0
- package/dist/lib/ui-parser.d.ts.map +1 -0
- package/dist/lib/ui-parser.js +472 -0
- package/dist/lib/ui-parser.js.map +1 -0
- package/dist/lib/update-check.d.ts +6 -0
- package/dist/lib/update-check.d.ts.map +1 -0
- package/dist/lib/update-check.js +121 -0
- package/dist/lib/update-check.js.map +1 -0
- package/dist/lib/upgrade-backup.d.ts +33 -0
- package/dist/lib/upgrade-backup.d.ts.map +1 -0
- package/dist/lib/upgrade-backup.js +101 -0
- package/dist/lib/upgrade-backup.js.map +1 -0
- package/dist/lib/version.d.ts +19 -0
- package/dist/lib/version.d.ts.map +1 -0
- package/dist/lib/version.js +35 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/lib/workflow-state.d.ts +48 -0
- package/dist/lib/workflow-state.d.ts.map +1 -0
- package/dist/lib/workflow-state.js +67 -0
- package/dist/lib/workflow-state.js.map +1 -0
- package/dist/types/config.d.ts +103 -2
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +184 -9
- package/dist/types/config.js.map +1 -1
- package/dist/types/feedback.d.ts +7 -0
- package/dist/types/feedback.d.ts.map +1 -1
- package/dist/types/feedback.js +1 -1
- package/dist/types/feedback.js.map +1 -1
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/meta-index.d.ts +146 -0
- package/dist/types/meta-index.d.ts.map +1 -0
- package/dist/types/meta-index.js +7 -0
- package/dist/types/meta-index.js.map +1 -0
- package/dist/types/project.d.ts +19 -3
- package/dist/types/project.d.ts.map +1 -1
- package/dist/types/project.js +23 -0
- package/dist/types/project.js.map +1 -1
- package/dist/types/task-log.d.ts +208 -0
- package/dist/types/task-log.d.ts.map +1 -0
- package/dist/types/task-log.js +6 -0
- package/dist/types/task-log.js.map +1 -0
- package/dist/types/ui-meta.d.ts +118 -0
- package/dist/types/ui-meta.d.ts.map +1 -0
- package/dist/types/ui-meta.js +7 -0
- package/dist/types/ui-meta.js.map +1 -0
- package/package.json +12 -4
- package/templates/base/agents/base/tsq-architect.md +68 -0
- package/templates/base/agents/base/tsq-dba.md +56 -0
- package/templates/base/agents/base/tsq-designer.md +72 -0
- package/templates/base/agents/base/tsq-developer.md +67 -0
- package/templates/base/agents/base/tsq-qa.md +55 -0
- package/templates/base/agents/base/tsq-security.md +65 -0
- package/templates/base/agents/overlays/domain/general-web/_common.md +11 -0
- package/templates/base/agents/overlays/domain/mobile/_common.md +13 -0
- package/templates/base/agents/overlays/platform/claude-code.md +12 -0
- package/templates/base/config.template.yaml +213 -0
- package/templates/base/knowledge/checklists/accessibility.md +37 -0
- package/templates/base/knowledge/checklists/architecture-review.md +28 -0
- package/templates/base/knowledge/checklists/database-standards.md +84 -0
- package/templates/base/knowledge/checklists/design-reference.md +97 -0
- package/templates/base/knowledge/checklists/security.md +50 -0
- package/templates/base/knowledge/checklists/ssot-validation.md +19 -0
- package/templates/base/knowledge/domains/_template.md +16 -0
- package/templates/base/knowledge/platforms/_template.md +16 -0
- package/templates/base/knowledge/templates/sequence-report.md +44 -0
- package/templates/base/knowledge/templates/task-result.md +105 -0
- package/templates/base/skills/_template/SKILL.md +59 -0
- package/templates/base/skills/_template/references/_template.md +35 -0
- package/templates/base/skills/_template/rules/_sections.md +34 -0
- package/templates/base/skills/_template/rules/_template.md +32 -0
- package/templates/base/skills/_template/scripts/_template.sh +31 -0
- package/templates/base/skills/architecture/SKILL.md +54 -0
- package/templates/base/skills/architecture/references/adr-template.md +50 -0
- package/templates/base/skills/architecture/references/api-design.md +64 -0
- package/templates/base/skills/backend/node/SKILL.md +81 -0
- package/templates/base/skills/backend/node/rules/async-patterns.md +81 -0
- package/templates/base/skills/backend/node/rules/deployment.md +33 -0
- package/templates/base/skills/backend/node/rules/env-config.md +41 -0
- package/templates/base/skills/backend/node/rules/error-handling.md +83 -0
- package/templates/base/skills/backend/node/rules/hono-app-setup.md +98 -0
- package/templates/base/skills/backend/node/rules/jwt-auth.md +76 -0
- package/templates/base/skills/backend/node/rules/middleware.md +56 -0
- package/templates/base/skills/backend/node/rules/testing.md +82 -0
- package/templates/base/skills/coding/SKILL.md +47 -0
- package/templates/base/skills/coding/rules/patterns.md +81 -0
- package/templates/base/skills/controller/SKILL.md +111 -0
- package/templates/base/skills/controller/references/README.md +35 -0
- package/templates/base/skills/controller/rules/README.md +18 -0
- package/templates/base/skills/database/SKILL.md +98 -0
- package/templates/base/skills/database/prisma/SKILL.md +57 -0
- package/templates/base/skills/database/prisma/rules/queries.md +133 -0
- package/templates/base/skills/database/prisma/rules/schema-design.md +80 -0
- package/templates/base/skills/frontend/nextjs/SKILL.md +59 -0
- package/templates/base/skills/frontend/nextjs/rules/app-router.md +138 -0
- package/templates/base/skills/frontend/react/SKILL.md +86 -0
- package/templates/base/skills/frontend/react/rules/_sections.md +88 -0
- package/templates/base/skills/frontend/react/rules/anti-patterns.md +67 -0
- package/templates/base/skills/frontend/react/rules/async-api-routes.md +38 -0
- package/templates/base/skills/frontend/react/rules/async-defer-await.md +80 -0
- package/templates/base/skills/frontend/react/rules/async-dependencies.md +36 -0
- package/templates/base/skills/frontend/react/rules/async-parallel.md +28 -0
- package/templates/base/skills/frontend/react/rules/async-suspense-boundaries.md +99 -0
- package/templates/base/skills/frontend/react/rules/bundle-barrel-imports.md +59 -0
- package/templates/base/skills/frontend/react/rules/bundle-defer-third-party.md +49 -0
- package/templates/base/skills/frontend/react/rules/bundle-dynamic-imports.md +35 -0
- package/templates/base/skills/frontend/react/rules/component-conventions.md +74 -0
- package/templates/base/skills/frontend/react/rules/js-combine-iterations.md +32 -0
- package/templates/base/skills/frontend/react/rules/js-early-exit.md +50 -0
- package/templates/base/skills/frontend/react/rules/js-index-maps.md +37 -0
- package/templates/base/skills/frontend/react/rules/js-set-map-lookups.md +24 -0
- package/templates/base/skills/frontend/react/rules/rendering-conditional-render.md +40 -0
- package/templates/base/skills/frontend/react/rules/rendering-content-visibility.md +38 -0
- package/templates/base/skills/frontend/react/rules/rendering-hoist-jsx.md +46 -0
- package/templates/base/skills/frontend/react/rules/rerender-defer-reads.md +39 -0
- package/templates/base/skills/frontend/react/rules/rerender-derived-state.md +29 -0
- package/templates/base/skills/frontend/react/rules/rerender-memo.md +44 -0
- package/templates/base/skills/frontend/react/rules/rerender-transitions.md +40 -0
- package/templates/base/skills/frontend/react/rules/server-after-nonblocking.md +73 -0
- package/templates/base/skills/frontend/react/rules/server-cache-react.md +26 -0
- package/templates/base/skills/frontend/react/rules/server-parallel-fetching.md +79 -0
- package/templates/base/skills/frontend/react/rules/state-location.md +55 -0
- package/templates/base/skills/methodology/bdd/SKILL.md +69 -0
- package/templates/base/skills/methodology/bdd/rules/gherkin-patterns.md +113 -0
- package/templates/base/skills/methodology/ddd/SKILL.md +74 -0
- package/templates/base/skills/methodology/ddd/rules/strategic-patterns.md +98 -0
- package/templates/base/skills/methodology/debugging/SKILL.md +60 -0
- package/templates/base/skills/methodology/debugging/references/root-cause-tracing.md +84 -0
- package/templates/base/skills/methodology/tdd/SKILL.md +66 -0
- package/templates/base/skills/methodology/tdd/rules/real-world-example.md +88 -0
- package/templates/base/skills/methodology/tdd/rules/techniques.md +185 -0
- package/templates/base/skills/mobile/dart/SKILL.md +69 -0
- package/templates/base/skills/mobile/dart/rules/async-patterns.md +112 -0
- package/templates/base/skills/mobile/dart/rules/code-style.md +96 -0
- package/templates/base/skills/mobile/dart/rules/null-safety.md +84 -0
- package/templates/base/skills/mobile/dart/rules/type-system.md +111 -0
- package/templates/base/skills/mobile/flutter/SKILL.md +89 -0
- package/templates/base/skills/mobile/flutter/ci-cd/SKILL.md +82 -0
- package/templates/base/skills/mobile/flutter/ci-cd/references/ci-cd-pipeline.md +314 -0
- package/templates/base/skills/mobile/flutter/ci-cd/rules/code-signing.md +106 -0
- package/templates/base/skills/mobile/flutter/ci-cd/rules/codemagic-setup.md +116 -0
- package/templates/base/skills/mobile/flutter/ci-cd/rules/fastlane-setup.md +105 -0
- package/templates/base/skills/mobile/flutter/ci-cd/rules/github-actions.md +112 -0
- package/templates/base/skills/mobile/flutter/ci-cd/rules/store-deployment.md +106 -0
- package/templates/base/skills/mobile/flutter/ci-cd/rules/versioning.md +107 -0
- package/templates/base/skills/mobile/flutter/i18n/SKILL.md +78 -0
- package/templates/base/skills/mobile/flutter/i18n/references/i18n-architecture.md +225 -0
- package/templates/base/skills/mobile/flutter/i18n/rules/arb-files.md +182 -0
- package/templates/base/skills/mobile/flutter/i18n/rules/locale-switching.md +226 -0
- package/templates/base/skills/mobile/flutter/i18n/rules/localization-setup.md +137 -0
- package/templates/base/skills/mobile/flutter/i18n/rules/plural-gender.md +159 -0
- package/templates/base/skills/mobile/flutter/i18n/rules/text-direction.md +199 -0
- package/templates/base/skills/mobile/flutter/monitoring/SKILL.md +81 -0
- package/templates/base/skills/mobile/flutter/monitoring/references/monitoring-architecture.md +269 -0
- package/templates/base/skills/mobile/flutter/monitoring/rules/analytics.md +227 -0
- package/templates/base/skills/mobile/flutter/monitoring/rules/crashlytics-setup.md +195 -0
- package/templates/base/skills/mobile/flutter/monitoring/rules/logging.md +258 -0
- package/templates/base/skills/mobile/flutter/monitoring/rules/performance-monitoring.md +248 -0
- package/templates/base/skills/mobile/flutter/monitoring/rules/sentry-integration.md +249 -0
- package/templates/base/skills/mobile/flutter/networking/SKILL.md +88 -0
- package/templates/base/skills/mobile/flutter/networking/references/api-client-architecture.md +305 -0
- package/templates/base/skills/mobile/flutter/networking/rules/caching.md +212 -0
- package/templates/base/skills/mobile/flutter/networking/rules/connectivity.md +213 -0
- package/templates/base/skills/mobile/flutter/networking/rules/dio-setup.md +159 -0
- package/templates/base/skills/mobile/flutter/networking/rules/error-handling.md +209 -0
- package/templates/base/skills/mobile/flutter/networking/rules/interceptors.md +205 -0
- package/templates/base/skills/mobile/flutter/networking/rules/retrofit-patterns.md +194 -0
- package/templates/base/skills/mobile/flutter/push-notifications/SKILL.md +87 -0
- package/templates/base/skills/mobile/flutter/push-notifications/references/notification-architecture.md +340 -0
- package/templates/base/skills/mobile/flutter/push-notifications/references/platform-setup.md +286 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/background-processing.md +308 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/deep-linking.md +217 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/fcm-setup.md +164 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/local-notifications.md +262 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/notification-handling.md +210 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/notification-permissions.md +246 -0
- package/templates/base/skills/mobile/flutter/push-notifications/rules/rich-notifications.md +320 -0
- package/templates/base/skills/mobile/flutter/references/freezed-patterns.md +162 -0
- package/templates/base/skills/mobile/flutter/references/project-structure.md +170 -0
- package/templates/base/skills/mobile/flutter/rules/animations.md +112 -0
- package/templates/base/skills/mobile/flutter/rules/architecture.md +121 -0
- package/templates/base/skills/mobile/flutter/rules/navigation-routing.md +117 -0
- package/templates/base/skills/mobile/flutter/rules/performance.md +112 -0
- package/templates/base/skills/mobile/flutter/rules/platform-adaptive.md +126 -0
- package/templates/base/skills/mobile/flutter/rules/state-management.md +110 -0
- package/templates/base/skills/mobile/flutter/rules/testing.md +131 -0
- package/templates/base/skills/mobile/flutter/rules/widget-conventions.md +122 -0
- package/templates/base/skills/mobile/flutter/security/SKILL.md +86 -0
- package/templates/base/skills/mobile/flutter/security/references/mobile-security-checklist.md +168 -0
- package/templates/base/skills/mobile/flutter/security/rules/api-key-protection.md +206 -0
- package/templates/base/skills/mobile/flutter/security/rules/authentication.md +248 -0
- package/templates/base/skills/mobile/flutter/security/rules/data-protection.md +271 -0
- package/templates/base/skills/mobile/flutter/security/rules/obfuscation.md +213 -0
- package/templates/base/skills/mobile/flutter/security/rules/secure-storage.md +171 -0
- package/templates/base/skills/mobile/flutter/security/rules/ssl-pinning.md +197 -0
- package/templates/base/skills/planning/SKILL.md +58 -0
- package/templates/base/skills/planning/references/prd-guide.md +47 -0
- package/templates/base/skills/planning/references/requirements-guide.md +46 -0
- package/templates/base/skills/prompt-engineering/SKILL.md +103 -0
- package/templates/base/skills/retrospective/SKILL.md +102 -0
- package/templates/base/skills/security/SKILL.md +55 -0
- package/templates/base/skills/security/rules/owasp-examples.md +119 -0
- package/templates/base/skills/security/scripts/check-secrets.sh +55 -0
- package/templates/base/skills/testing/SKILL.md +63 -0
- package/templates/base/skills/testing/references/testing-patterns.md +103 -0
- package/templates/base/skills/tsq-protocol/SKILL.md +51 -0
- package/templates/base/skills/typescript/SKILL.md +67 -0
- package/templates/base/skills/typescript/rules/type-patterns.md +135 -0
- package/templates/base/skills/typescript/rules/utility-types.md +76 -0
- package/templates/base/skills/ui-design/SKILL.md +70 -0
- package/templates/{common → base}/timsquad/feedback/routing-rules.yaml +1 -1
- package/templates/{common → base}/timsquad/retrospective/metrics/metrics-schema.json +46 -1
- package/templates/platforms/claude-code/CLAUDE.md.template +89 -0
- package/templates/platforms/claude-code/rules/adr-rules.md +32 -0
- package/templates/platforms/claude-code/rules/feedback-routing.md +18 -0
- package/templates/platforms/claude-code/rules/phase-management.md +23 -0
- package/templates/platforms/claude-code/rules/reporting-format.md +26 -0
- package/templates/platforms/claude-code/rules/sequence-management.md +72 -0
- package/templates/platforms/claude-code/rules/workspace-sync.md +33 -0
- package/templates/platforms/claude-code/scripts/completion-guard.sh +57 -0
- package/templates/platforms/claude-code/scripts/phase-guard.sh +79 -0
- package/templates/platforms/claude-code/settings.json +98 -0
- package/templates/project-types/api-backend/config.yaml +227 -0
- package/templates/project-types/api-backend/process/workflow.xml +214 -0
- package/templates/project-types/fintech/config.yaml +151 -0
- package/templates/project-types/fintech/process/workflow.xml +316 -0
- package/templates/project-types/infra/config.yaml +327 -0
- package/templates/project-types/infra/process/workflow.xml +296 -0
- package/templates/project-types/mobile-app/config.yaml +123 -0
- package/templates/project-types/mobile-app/process/workflow.xml +191 -0
- package/templates/project-types/platform/config.yaml +254 -0
- package/templates/project-types/platform/process/workflow.xml +254 -0
- package/templates/project-types/web-app/config.yaml +198 -0
- package/templates/project-types/web-app/process/workflow.xml +210 -0
- package/templates/project-types/web-service/config.yaml +136 -0
- package/templates/project-types/web-service/process/workflow.xml +184 -0
- package/templates/common/CLAUDE.md.template +0 -254
- package/templates/common/claude/agents/tsq-dba.md +0 -311
- package/templates/common/claude/agents/tsq-designer.md +0 -323
- package/templates/common/claude/agents/tsq-developer.md +0 -177
- package/templates/common/claude/agents/tsq-planner.md +0 -190
- package/templates/common/claude/agents/tsq-prompter.md +0 -356
- package/templates/common/claude/agents/tsq-qa.md +0 -168
- package/templates/common/claude/agents/tsq-retro.md +0 -193
- package/templates/common/claude/agents/tsq-security.md +0 -221
- package/templates/common/claude/hooks/auto-metrics.sh +0 -165
- package/templates/common/claude/hooks/auto-worklog.sh +0 -245
- package/templates/common/claude/hooks/event-logger.sh +0 -208
- package/templates/common/claude/settings.json +0 -86
- package/templates/common/claude/skills/architecture/SKILL.md +0 -123
- package/templates/common/claude/skills/backend/node/SKILL.md +0 -1015
- package/templates/common/claude/skills/coding/SKILL.md +0 -171
- package/templates/common/claude/skills/database/prisma/SKILL.md +0 -357
- package/templates/common/claude/skills/frontend/nextjs/SKILL.md +0 -279
- package/templates/common/claude/skills/frontend/react/SKILL.md +0 -1729
- package/templates/common/claude/skills/methodology/bdd/SKILL.md +0 -234
- package/templates/common/claude/skills/methodology/ddd/SKILL.md +0 -311
- package/templates/common/claude/skills/methodology/tdd/SKILL.md +0 -512
- package/templates/common/claude/skills/planning/SKILL.md +0 -90
- package/templates/common/claude/skills/security/SKILL.md +0 -234
- package/templates/common/claude/skills/testing/SKILL.md +0 -146
- package/templates/common/claude/skills/typescript/SKILL.md +0 -435
- package/templates/common/config.template.yaml +0 -132
- /package/templates/{common → base}/timsquad/architectures/clean/ARCHITECTURE.md +0 -0
- /package/templates/{common → base}/timsquad/architectures/clean/backend.xml +0 -0
- /package/templates/{common → base}/timsquad/architectures/clean/frontend.xml +0 -0
- /package/templates/{common → base}/timsquad/architectures/fsd/ARCHITECTURE.md +0 -0
- /package/templates/{common → base}/timsquad/architectures/fsd/frontend.xml +0 -0
- /package/templates/{common → base}/timsquad/architectures/hexagonal/ARCHITECTURE.md +0 -0
- /package/templates/{common → base}/timsquad/architectures/hexagonal/backend.xml +0 -0
- /package/templates/{common → base}/timsquad/constraints/competency-framework.xml +0 -0
- /package/templates/{common → base}/timsquad/constraints/ssot-schema.xml +0 -0
- /package/templates/{common → base}/timsquad/feedback/feedback-router.sh +0 -0
- /package/templates/{common → base}/timsquad/generators/data-design.xml +0 -0
- /package/templates/{common → base}/timsquad/generators/prd.xml +0 -0
- /package/templates/{common → base}/timsquad/generators/requirements.xml +0 -0
- /package/templates/{common → base}/timsquad/generators/service-spec.xml +0 -0
- /package/templates/{common → base}/timsquad/logs/_example.md +0 -0
- /package/templates/{common → base}/timsquad/logs/_template.md +0 -0
- /package/templates/{common → base}/timsquad/patterns/cqrs.xml +0 -0
- /package/templates/{common → base}/timsquad/patterns/event-sourcing.xml +0 -0
- /package/templates/{common → base}/timsquad/patterns/repository.xml +0 -0
- /package/templates/{common → base}/timsquad/process/phase-checklist.yaml +0 -0
- /package/templates/{common → base}/timsquad/process/state-machine.xml +0 -0
- /package/templates/{common → base}/timsquad/process/validation-rules.xml +0 -0
- /package/templates/{common → base}/timsquad/process/workflow-base.xml +0 -0
- /package/templates/{common → base}/timsquad/retrospective/cycle-report.template.md +0 -0
- /package/templates/{common → base}/timsquad/retrospective/patterns/failure-patterns.md +0 -0
- /package/templates/{common → base}/timsquad/retrospective/patterns/success-patterns.md +0 -0
- /package/templates/{common → base}/timsquad/retrospective/retrospective-config.xml +0 -0
- /package/templates/{common → base}/timsquad/retrospective/retrospective-state.xml +0 -0
- /package/templates/{common → base}/timsquad/ssot/adr/ADR-000-template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/adr/ADR-001-example.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/data-design.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/deployment-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/env-config.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/error-codes.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/functional-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/glossary.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/integration-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/planning.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/prd.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/requirements.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/security-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/service-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/test-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/ssot/ui-ux-spec.template.md +0 -0
- /package/templates/{common → base}/timsquad/state/workspace.xml +0 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: BDD Gherkin & Implementation Patterns
|
|
3
|
+
impact: HIGH
|
|
4
|
+
tags: bdd, gherkin, testing
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# BDD Gherkin & Implementation Patterns
|
|
8
|
+
|
|
9
|
+
## Feature File 예시
|
|
10
|
+
|
|
11
|
+
```gherkin
|
|
12
|
+
Feature: 사용자 로그인
|
|
13
|
+
사용자가 이메일과 비밀번호로 로그인할 수 있다
|
|
14
|
+
|
|
15
|
+
Background:
|
|
16
|
+
Given 회원가입된 사용자가 존재한다
|
|
17
|
+
| email | password |
|
|
18
|
+
| user@test.com | password1 |
|
|
19
|
+
|
|
20
|
+
Scenario: 올바른 자격 증명으로 로그인 성공
|
|
21
|
+
Given 로그인 페이지에 접속한다
|
|
22
|
+
When 이메일 "user@test.com"을 입력한다
|
|
23
|
+
And 비밀번호 "password1"을 입력한다
|
|
24
|
+
And 로그인 버튼을 클릭한다
|
|
25
|
+
Then 대시보드 페이지로 이동한다
|
|
26
|
+
And "로그인 성공" 메시지가 표시된다
|
|
27
|
+
|
|
28
|
+
Scenario: 잘못된 비밀번호로 로그인 실패
|
|
29
|
+
Given 로그인 페이지에 접속한다
|
|
30
|
+
When 이메일 "user@test.com"을 입력한다
|
|
31
|
+
And 비밀번호 "wrongpassword"를 입력한다
|
|
32
|
+
And 로그인 버튼을 클릭한다
|
|
33
|
+
Then 로그인 페이지에 머무른다
|
|
34
|
+
And "이메일 또는 비밀번호가 올바르지 않습니다" 에러가 표시된다
|
|
35
|
+
|
|
36
|
+
Scenario Outline: 다양한 잘못된 입력
|
|
37
|
+
When 이메일 "<email>"을 입력한다
|
|
38
|
+
And 비밀번호 "<password>"를 입력한다
|
|
39
|
+
And 로그인 버튼을 클릭한다
|
|
40
|
+
Then "<error>" 에러가 표시된다
|
|
41
|
+
|
|
42
|
+
Examples:
|
|
43
|
+
| email | password | error |
|
|
44
|
+
| | pass | 이메일을 입력해주세요 |
|
|
45
|
+
| invalid-email | pass | 올바른 이메일 형식이 아닙니다 |
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Step Definitions (Playwright + Cucumber)
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { Given, When, Then } from '@cucumber/cucumber';
|
|
52
|
+
import { expect } from '@playwright/test';
|
|
53
|
+
|
|
54
|
+
Given('로그인 페이지에 접속한다', async function() {
|
|
55
|
+
await this.page.goto('/login');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
When('이메일 {string}을 입력한다', async function(email: string) {
|
|
59
|
+
await this.page.fill('[data-testid="email-input"]', email);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
When('로그인 버튼을 클릭한다', async function() {
|
|
63
|
+
await this.page.click('[data-testid="login-button"]');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
Then('대시보드 페이지로 이동한다', async function() {
|
|
67
|
+
await expect(this.page).toHaveURL('/dashboard');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
Then('{string} 메시지가 표시된다', async function(message: string) {
|
|
71
|
+
await expect(this.page.locator('[data-testid="toast"]')).toContainText(message);
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## API BDD (Vitest + SuperTest)
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
describe('Feature: 사용자 등록 API', () => {
|
|
79
|
+
describe('Scenario: 유효한 정보로 회원가입', () => {
|
|
80
|
+
it('Given 유효한 사용자 정보가 있다', () => {
|
|
81
|
+
ctx.userData = { email: 'new@test.com', password: 'SecurePass123!', name: '홍길동' };
|
|
82
|
+
});
|
|
83
|
+
it('When POST /api/users 요청을 보낸다', async () => {
|
|
84
|
+
ctx.response = await request(app).post('/api/users').send(ctx.userData);
|
|
85
|
+
});
|
|
86
|
+
it('Then 201 상태 코드를 반환한다', () => {
|
|
87
|
+
expect(ctx.response.status).toBe(201);
|
|
88
|
+
});
|
|
89
|
+
it('And 생성된 사용자 ID를 반환한다', () => {
|
|
90
|
+
expect(ctx.response.body.data.id).toBeDefined();
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 디렉토리 구조
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
features/ # Gherkin feature 파일
|
|
100
|
+
├── auth/login.feature
|
|
101
|
+
├── order/checkout.feature
|
|
102
|
+
step-definitions/ # 스텝 구현
|
|
103
|
+
├── auth.steps.ts
|
|
104
|
+
├── common.steps.ts
|
|
105
|
+
support/ # 헬퍼, 훅
|
|
106
|
+
├── world.ts # 테스트 컨텍스트
|
|
107
|
+
├── hooks.ts # Before, After 훅
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 도구
|
|
111
|
+
- `cucumber-js`: JS/TS Cucumber 구현
|
|
112
|
+
- `playwright`: E2E 테스트 러너
|
|
113
|
+
- `jest-cucumber`: Jest와 Cucumber 통합
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ddd
|
|
3
|
+
description: Domain-Driven Design 전략적 설계 가이드라인
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
tags: [ddd, methodology, architecture]
|
|
6
|
+
user-invocable: false
|
|
7
|
+
compatible-with: [tdd, bdd]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# DDD (Domain-Driven Design) — Strategic
|
|
11
|
+
|
|
12
|
+
## 철학
|
|
13
|
+
- 도메인 전문가와 개발자의 협업
|
|
14
|
+
- 유비쿼터스 언어 (Ubiquitous Language)
|
|
15
|
+
- 모델 주도 설계 (Model-Driven Design)
|
|
16
|
+
- 경계 컨텍스트로 복잡성 분리
|
|
17
|
+
|
|
18
|
+
## 전략적 vs 전술적
|
|
19
|
+
|
|
20
|
+
| 레벨 | 내용 | 위치 |
|
|
21
|
+
|------|------|------|
|
|
22
|
+
| 전략적 | Bounded Context, Ubiquitous Language, Context Map, Subdomain | 이 스킬 |
|
|
23
|
+
| 전술적 | Aggregate, Entity, Value Object, Repository, Domain Event | architectures/ |
|
|
24
|
+
|
|
25
|
+
## 핵심 개념
|
|
26
|
+
|
|
27
|
+
### Ubiquitous Language
|
|
28
|
+
도메인 전문가와 개발자가 공유하는 공통 언어.
|
|
29
|
+
코드, 문서, 대화 모두에서 동일한 용어 사용.
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
// Bad: 개발자 용어
|
|
33
|
+
class DataProcessor { processRecord(record: Record) { ... } }
|
|
34
|
+
|
|
35
|
+
// Good: 유비쿼터스 언어
|
|
36
|
+
class OrderFulfillment { shipOrder(order: Order) { ... } }
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Bounded Context
|
|
40
|
+
특정 도메인 모델이 적용되는 명시적 경계.
|
|
41
|
+
같은 "Product"도 Catalog(정보), Inventory(재고), Pricing(가격)에서 다른 의미.
|
|
42
|
+
|
|
43
|
+
### Subdomain
|
|
44
|
+
- **Core**: 비즈니스 핵심 차별화 → 최고 인력, 자체 개발
|
|
45
|
+
- **Supporting**: Core 지원, 차별화 아님 → 적당한 품질
|
|
46
|
+
- **Generic**: 모든 비즈니스에 공통 → 구매/오픈소스
|
|
47
|
+
|
|
48
|
+
### Context Map
|
|
49
|
+
Bounded Context 간 관계: Partnership, Shared Kernel, Customer-Supplier, Conformist, ACL, Open Host Service
|
|
50
|
+
|
|
51
|
+
## Rules
|
|
52
|
+
|
|
53
|
+
### 필수
|
|
54
|
+
- 용어 사전 (Glossary) 작성 및 유지
|
|
55
|
+
- 코드에서 유비쿼터스 언어 사용
|
|
56
|
+
- Bounded Context 경계 명확히 정의
|
|
57
|
+
- 컨텍스트 간 통신은 명시적 인터페이스로
|
|
58
|
+
- 외부 시스템 연동 시 ACL 사용
|
|
59
|
+
|
|
60
|
+
### 금지
|
|
61
|
+
- Bounded Context 간 도메인 모델 직접 공유
|
|
62
|
+
- 하나의 Aggregate가 여러 Context에 걸침
|
|
63
|
+
- 기술 용어를 도메인 모델에 사용
|
|
64
|
+
|
|
65
|
+
## Checklist
|
|
66
|
+
- [ ] 용어 사전 존재 및 최신화
|
|
67
|
+
- [ ] Bounded Context 경계 정의됨
|
|
68
|
+
- [ ] 코드가 유비쿼터스 언어 사용
|
|
69
|
+
- [ ] Context Map 문서화
|
|
70
|
+
- [ ] 외부 연동에 ACL 적용
|
|
71
|
+
- [ ] Subdomain 분류 (Core/Supporting/Generic)
|
|
72
|
+
|
|
73
|
+
## 참조
|
|
74
|
+
- `rules/strategic-patterns.md` — Context Map, ACL 예시, Event Storming, 디렉토리 구조
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: DDD Strategic Patterns
|
|
3
|
+
impact: HIGH
|
|
4
|
+
tags: ddd, architecture, domain-modeling
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# DDD Strategic Patterns
|
|
8
|
+
|
|
9
|
+
## Bounded Context
|
|
10
|
+
특정 도메인 모델이 적용되는 명시적 경계.
|
|
11
|
+
같은 용어도 컨텍스트마다 다른 의미를 가질 수 있음.
|
|
12
|
+
|
|
13
|
+
### "Product"의 다른 의미
|
|
14
|
+
- **Catalog**: 상품 정보, 설명, 이미지
|
|
15
|
+
- **Inventory**: 재고 수량, 위치, SKU
|
|
16
|
+
- **Pricing**: 가격, 할인, 프로모션
|
|
17
|
+
- **Shipping**: 무게, 크기, 배송 제한
|
|
18
|
+
|
|
19
|
+
### 가이드라인
|
|
20
|
+
- 하나의 Bounded Context = 하나의 팀
|
|
21
|
+
- 하나의 Bounded Context = 하나의 코드베이스 (또는 모듈)
|
|
22
|
+
- 컨텍스트 간 통신은 명시적 인터페이스로
|
|
23
|
+
|
|
24
|
+
## Subdomain 유형
|
|
25
|
+
|
|
26
|
+
| 유형 | 설명 | 전략 | 예시 |
|
|
27
|
+
|------|------|------|------|
|
|
28
|
+
| Core | 비즈니스 핵심 차별화 | 최고 인력, 자체 개발 | 쿠팡 로켓배송 |
|
|
29
|
+
| Supporting | Core 지원, 차별화 아님 | 아웃소싱/적당한 품질 | 내부 관리 시스템 |
|
|
30
|
+
| Generic | 모든 비즈니스에 공통 | 구매/오픈소스 | 결제, 인증, 이메일 |
|
|
31
|
+
|
|
32
|
+
## Context Map Relationships
|
|
33
|
+
|
|
34
|
+
| 관계 | 설명 | 다이어그램 |
|
|
35
|
+
|------|------|-----------|
|
|
36
|
+
| Partnership | 긴밀한 협력, 함께 성공/실패 | [A] ←Partnership→ [B] |
|
|
37
|
+
| Shared Kernel | 공유 모델, 양쪽 합의 필요 (최소화) | [A] ←Shared Kernel→ [B] |
|
|
38
|
+
| Customer-Supplier | 공급자가 고객 요구 수용 | [Supplier] → [Customer] |
|
|
39
|
+
| Conformist | Downstream이 Upstream 모델 수용 | [Upstream] → [Downstream] |
|
|
40
|
+
| ACL | 번역 레이어로 외부 모델로부터 보호 | [External] →ACL→ [Ours] |
|
|
41
|
+
| Open Host Service | 잘 정의된 프로토콜로 서비스 제공 | [Context] →OHS→ [Consumers] |
|
|
42
|
+
|
|
43
|
+
## Anti-Corruption Layer 예시 (Stripe 결제)
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// 외부 모델 (Stripe)
|
|
47
|
+
interface StripePaymentIntent {
|
|
48
|
+
id: string;
|
|
49
|
+
amount: number; // cents
|
|
50
|
+
status: 'succeeded' | 'pending' | 'failed';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 우리 도메인 모델
|
|
54
|
+
interface Payment {
|
|
55
|
+
id: PaymentId;
|
|
56
|
+
amount: Money; // 우리의 Money Value Object
|
|
57
|
+
status: PaymentStatus;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ACL
|
|
61
|
+
class StripePaymentAdapter implements PaymentGateway {
|
|
62
|
+
async processPayment(payment: Payment): Promise<PaymentResult> {
|
|
63
|
+
const intent = await this.stripe.paymentIntents.create({
|
|
64
|
+
amount: payment.amount.toCents(),
|
|
65
|
+
currency: payment.amount.currency.toLowerCase(),
|
|
66
|
+
});
|
|
67
|
+
return this.toPaymentResult(intent);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private mapStatus(stripeStatus: string): PaymentStatus {
|
|
71
|
+
const mapping: Record<string, PaymentStatus> = {
|
|
72
|
+
'succeeded': PaymentStatus.COMPLETED,
|
|
73
|
+
'pending': PaymentStatus.PROCESSING,
|
|
74
|
+
'failed': PaymentStatus.FAILED,
|
|
75
|
+
};
|
|
76
|
+
return mapping[stripeStatus] ?? PaymentStatus.UNKNOWN;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Event Storming
|
|
82
|
+
1. Domain Events 도출 (주황색)
|
|
83
|
+
2. Commands 식별 (파란색)
|
|
84
|
+
3. Aggregates 그룹핑 (노란색)
|
|
85
|
+
4. Bounded Context 경계 그리기
|
|
86
|
+
5. Context Map 작성
|
|
87
|
+
|
|
88
|
+
## 디렉토리 구조 (모노레포)
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
packages/
|
|
92
|
+
├── catalog/ # Catalog Context
|
|
93
|
+
│ └── src/domain/ + application/ + infrastructure/
|
|
94
|
+
├── order/ # Order Context
|
|
95
|
+
├── inventory/ # Inventory Context
|
|
96
|
+
└── shared/ # Shared Kernel (최소화)
|
|
97
|
+
└── src/value-objects/ + events/
|
|
98
|
+
```
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: debugging
|
|
3
|
+
description: |
|
|
4
|
+
체계적 디버깅 방법론.
|
|
5
|
+
근본 원인 추적, defense-in-depth, 가설-실험 루프, 로그 기반 진단.
|
|
6
|
+
Use when: "버그 수정, 디버깅, 에러 추적, 원인 분석, 트러블슈팅"
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
tags: [debugging, troubleshooting, methodology]
|
|
9
|
+
user-invocable: false
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Systematic Debugging
|
|
13
|
+
|
|
14
|
+
체계적 디버깅을 통해 근본 원인(root cause)을 빠르게 찾고 재발을 방지하는 방법론.
|
|
15
|
+
|
|
16
|
+
## Philosophy
|
|
17
|
+
|
|
18
|
+
- 증상이 아닌 근본 원인을 찾는다
|
|
19
|
+
- 가설을 세우고 실험으로 검증한다 (추측으로 코드를 수정하지 않는다)
|
|
20
|
+
- Defense in depth — 같은 유형의 버그가 재발하지 않도록 방어 계층을 추가한다
|
|
21
|
+
|
|
22
|
+
## Resources
|
|
23
|
+
|
|
24
|
+
| Priority | Type | Resource | Description |
|
|
25
|
+
|----------|------|----------|-------------|
|
|
26
|
+
| HIGH | ref | [root-cause-tracing](references/root-cause-tracing.md) | 5 Whys + 가설-실험 루프 상세 가이드 |
|
|
27
|
+
|
|
28
|
+
## Quick Rules
|
|
29
|
+
|
|
30
|
+
### Debugging Loop
|
|
31
|
+
1. **Reproduce** — 버그를 100% 재현하는 최소 조건 확보
|
|
32
|
+
2. **Hypothesize** — 원인 가설을 1~3개 세우고 가능성 순으로 정렬
|
|
33
|
+
3. **Test** — 각 가설을 실험으로 검증 (로그 추가, breakpoint, 입력 변경)
|
|
34
|
+
4. **Fix** — 근본 원인 수정 (증상 대응 X)
|
|
35
|
+
5. **Verify** — 원래 재현 조건에서 버그 사라짐 확인
|
|
36
|
+
6. **Prevent** — 회귀 테스트 추가, 방어 로직 보강
|
|
37
|
+
|
|
38
|
+
### Root Cause Categories
|
|
39
|
+
| 카테고리 | 예시 |
|
|
40
|
+
|---------|------|
|
|
41
|
+
| State | 예기치 않은 상태 변이, race condition |
|
|
42
|
+
| Data | 잘못된 입력, null/undefined, 타입 불일치 |
|
|
43
|
+
| Logic | 잘못된 조건, off-by-one, 순서 오류 |
|
|
44
|
+
| Environment | 설정 차이, 의존성 버전, OS 차이 |
|
|
45
|
+
| Integration | API 응답 변경, 타이밍, 네트워크 |
|
|
46
|
+
|
|
47
|
+
### Anti-Patterns
|
|
48
|
+
- **Shotgun debugging**: 여러 곳을 동시에 수정 → 원인 특정 불가
|
|
49
|
+
- **Print-and-pray**: console.log만 추가하고 가설 없이 실행 반복
|
|
50
|
+
- **Blame game**: "내 코드 문제 아닌데" → 증거 없이 외부 원인 지목
|
|
51
|
+
|
|
52
|
+
## Checklist
|
|
53
|
+
|
|
54
|
+
| Priority | Item |
|
|
55
|
+
|----------|------|
|
|
56
|
+
| CRITICAL | 재현 조건이 명확한가 |
|
|
57
|
+
| CRITICAL | 가설을 세운 후 수정했는가 (추측 수정 X) |
|
|
58
|
+
| HIGH | 근본 원인을 찾았는가 (증상 대응만 하지 않았는가) |
|
|
59
|
+
| HIGH | 회귀 테스트를 추가했는가 |
|
|
60
|
+
| MEDIUM | 같은 유형의 버그를 방지하는 방어 로직이 있는가 |
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Root Cause Tracing Guide
|
|
3
|
+
category: guide
|
|
4
|
+
source: internal
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Root Cause Tracing
|
|
8
|
+
|
|
9
|
+
버그의 근본 원인을 체계적으로 추적하는 상세 가이드.
|
|
10
|
+
|
|
11
|
+
## 5 Whys Technique
|
|
12
|
+
|
|
13
|
+
증상에서 시작해 "왜?"를 반복하여 근본 원인에 도달:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
증상: 사용자가 주문 시 500 에러 발생
|
|
17
|
+
Why 1: 주문 API에서 NullPointerException
|
|
18
|
+
Why 2: user.address가 null
|
|
19
|
+
Why 3: 소셜 로그인 사용자는 주소 미입력
|
|
20
|
+
Why 4: 주소 입력 폼이 소셜 로그인 플로우에 없음
|
|
21
|
+
Why 5: 소셜 로그인 기능 추가 시 주소 수집 요구사항 누락
|
|
22
|
+
→ 근본 원인: 요구사항 누락 (L2 피드백 대상)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Hypothesis-Experiment Loop
|
|
26
|
+
|
|
27
|
+
### Step 1: Gather Evidence
|
|
28
|
+
```
|
|
29
|
+
- 에러 메시지 정확히 기록
|
|
30
|
+
- 스택 트레이스 분석
|
|
31
|
+
- 최근 변경사항 (git log, git diff) 확인
|
|
32
|
+
- 환경 차이 (dev vs prod) 확인
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Step 2: Form Hypotheses
|
|
36
|
+
```
|
|
37
|
+
가설 목록 (가능성 순):
|
|
38
|
+
1. [HIGH] user.address null check 누락 — 소셜 로그인 플로우 확인
|
|
39
|
+
2. [MEDIUM] DB migration 중 address 컬럼 누락 — 스키마 확인
|
|
40
|
+
3. [LOW] 캐시에 오래된 사용자 데이터 — 캐시 무효화 확인
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Step 3: Test Each Hypothesis
|
|
44
|
+
```
|
|
45
|
+
가설 1 테스트:
|
|
46
|
+
- 소셜 로그인으로 가입한 테스트 유저 생성
|
|
47
|
+
- 주소 없이 주문 API 호출
|
|
48
|
+
- 결과: NullPointerException 재현됨 → 가설 1 확인
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Step 4: Fix Root Cause
|
|
52
|
+
```
|
|
53
|
+
수정:
|
|
54
|
+
1. 주문 API에 address null 검증 추가 (즉시 방어)
|
|
55
|
+
2. 소셜 로그인 플로우에 주소 입력 단계 추가 (근본 원인)
|
|
56
|
+
3. 기존 소셜 로그인 사용자에게 주소 입력 유도 (데이터 보완)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Step 5: Prevent Recurrence
|
|
60
|
+
```
|
|
61
|
+
방지:
|
|
62
|
+
1. 회귀 테스트: "주소 없는 사용자의 주문 시 적절한 에러 반환"
|
|
63
|
+
2. 필수 필드 검증 체크리스트에 "address" 추가
|
|
64
|
+
3. 새 로그인 방법 추가 시 "기존 필수 데이터 수집" 체크 항목 추가
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Common Pitfalls
|
|
68
|
+
|
|
69
|
+
- 첫 번째 "왜?"에서 멈춤 → 최소 3번은 반복
|
|
70
|
+
- 가설 없이 코드 수정 → 다른 곳이 깨질 위험
|
|
71
|
+
- 증상만 수정 (null check만 추가하고 근본 원인 방치)
|
|
72
|
+
- 재현 없이 수정 → 수정이 맞는지 검증 불가
|
|
73
|
+
|
|
74
|
+
## Defense in Depth
|
|
75
|
+
|
|
76
|
+
같은 유형의 버그가 다시 발생하지 않도록 여러 계층에서 방어:
|
|
77
|
+
|
|
78
|
+
| 계층 | 방어 | 예시 |
|
|
79
|
+
|------|------|------|
|
|
80
|
+
| 입력 | Zod 스키마 검증 | `z.object({ address: z.string().min(1) })` |
|
|
81
|
+
| 타입 | NonNullable, Required | `NonNullable<User['address']>` |
|
|
82
|
+
| 런타임 | 조기 에러 반환 | `if (!user.address) throw new BadRequestError(...)` |
|
|
83
|
+
| 테스트 | 회귀 테스트 | `it('should reject order without address')` |
|
|
84
|
+
| 모니터링 | 에러 알림 | Sentry, error rate alert |
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tdd
|
|
3
|
+
description: Test-Driven Development 방법론 가이드라인
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
tags: [tdd, methodology, testing]
|
|
6
|
+
user-invocable: false
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# TDD (Test-Driven Development)
|
|
10
|
+
|
|
11
|
+
## 철학
|
|
12
|
+
- 테스트가 설계를 이끈다
|
|
13
|
+
- 작은 단계로 진행한다
|
|
14
|
+
- 리팩토링은 테스트가 보장한다
|
|
15
|
+
- 불확실할 때는 더 작은 단계로
|
|
16
|
+
|
|
17
|
+
## Red-Green-Refactor Cycle
|
|
18
|
+
|
|
19
|
+
### 1. Red (1-2min) — 실패하는 테스트 작성
|
|
20
|
+
- 테스트가 실패하는 것을 확인
|
|
21
|
+
- 한 번에 하나의 기능만 테스트
|
|
22
|
+
- 테스트 이름으로 의도 명확히 표현
|
|
23
|
+
- **금지**: 구현 코드 먼저 작성
|
|
24
|
+
|
|
25
|
+
### 2. Green (3-5min) — 테스트를 통과하는 최소 코드
|
|
26
|
+
- 테스트 통과만을 목표
|
|
27
|
+
- 가장 단순한 구현 선택
|
|
28
|
+
- **금지**: 미래 요구사항 미리 구현, 완벽한 코드 추구
|
|
29
|
+
|
|
30
|
+
### 3. Refactor (5-10min) — 코드 정리
|
|
31
|
+
- 중복 제거, 네이밍 개선, 구조 개선
|
|
32
|
+
- 테스트 실행하며 진행
|
|
33
|
+
- **금지**: 기능 변경
|
|
34
|
+
|
|
35
|
+
## Kent Beck Techniques (상세: `rules/techniques.md`)
|
|
36
|
+
|
|
37
|
+
| 기법 | 사용 시점 |
|
|
38
|
+
|------|----------|
|
|
39
|
+
| Fake It | 구현 불확실 → 하드코딩 후 일반화 |
|
|
40
|
+
| Triangulation | 일반화 방향 불명확 → 2+ 테스트 |
|
|
41
|
+
| Obvious Implementation | 구현 명확 → 바로 작성 |
|
|
42
|
+
| One to Many | 컬렉션 → 단일 먼저, 확장 |
|
|
43
|
+
| Assert First | 구조 불명확 → assertion부터 역방향 |
|
|
44
|
+
| Starter Test | 시작점 모름 → 가장 단순한 테스트 |
|
|
45
|
+
| Test Data Builder | 객체 생성 반복 → 빌더 패턴 |
|
|
46
|
+
| Learning Test | 새 라이브러리 → 학습 테스트 |
|
|
47
|
+
|
|
48
|
+
## SSOT 통합 워크플로우
|
|
49
|
+
1. `service-spec.md`에서 API 명세 확인
|
|
50
|
+
2. 명세 기반 테스트 케이스 작성 (Starter Test)
|
|
51
|
+
3. 테스트 실패 확인 (Red)
|
|
52
|
+
4. 명세대로 구현 (Green)
|
|
53
|
+
5. 리팩토링 (Refactor)
|
|
54
|
+
6. 삼각측량으로 엣지 케이스 추가
|
|
55
|
+
|
|
56
|
+
## Checklist
|
|
57
|
+
- [ ] 테스트 먼저 작성했는가
|
|
58
|
+
- [ ] 테스트가 실패하는 것을 확인했는가
|
|
59
|
+
- [ ] 최소 코드로 통과했는가
|
|
60
|
+
- [ ] 리팩토링 단계를 거쳤는가
|
|
61
|
+
- [ ] 삼각측량으로 일반화했는가
|
|
62
|
+
- [ ] 엣지 케이스를 테스트했는가
|
|
63
|
+
|
|
64
|
+
## 참조
|
|
65
|
+
- `rules/techniques.md` — 각 기법의 코드 예시
|
|
66
|
+
- `rules/real-world-example.md` — 로그인 기능 TDD 전체 과정 + Anti-Patterns
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TDD Real-World Example
|
|
3
|
+
impact: HIGH
|
|
4
|
+
tags: tdd, testing, best-practices
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# TDD Real-World Example: 로그인 기능
|
|
8
|
+
|
|
9
|
+
## 1단계: Starter Test
|
|
10
|
+
```typescript
|
|
11
|
+
it('should create auth service', () => {
|
|
12
|
+
const authService = new AuthService(mockUserRepo);
|
|
13
|
+
expect(authService).toBeDefined();
|
|
14
|
+
});
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 2단계: Happy Path
|
|
18
|
+
```typescript
|
|
19
|
+
it('should return token for valid credentials', async () => {
|
|
20
|
+
// Given
|
|
21
|
+
const mockUser = new UserBuilder()
|
|
22
|
+
.withEmail('user@test.com')
|
|
23
|
+
.withPassword(await hash('password123'))
|
|
24
|
+
.build();
|
|
25
|
+
mockUserRepo.findByEmail.mockResolvedValue(mockUser);
|
|
26
|
+
|
|
27
|
+
// When
|
|
28
|
+
const result = await authService.login('user@test.com', 'password123');
|
|
29
|
+
|
|
30
|
+
// Then
|
|
31
|
+
expect(result.token).toBeDefined();
|
|
32
|
+
expect(result.user.email).toBe('user@test.com');
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 3단계: Error Cases (삼각측량)
|
|
37
|
+
```typescript
|
|
38
|
+
it('should throw for non-existent user', async () => {
|
|
39
|
+
mockUserRepo.findByEmail.mockResolvedValue(null);
|
|
40
|
+
await expect(authService.login('nobody@test.com', 'password'))
|
|
41
|
+
.rejects.toThrow('INVALID_CREDENTIALS');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should throw for wrong password', async () => {
|
|
45
|
+
const mockUser = new UserBuilder().withPassword(await hash('correct-password')).build();
|
|
46
|
+
mockUserRepo.findByEmail.mockResolvedValue(mockUser);
|
|
47
|
+
await expect(authService.login('user@test.com', 'wrong-password'))
|
|
48
|
+
.rejects.toThrow('INVALID_CREDENTIALS');
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 4단계: Edge Cases
|
|
53
|
+
```typescript
|
|
54
|
+
it('should throw for locked account', async () => {
|
|
55
|
+
const lockedUser = new UserBuilder().withStatus('locked').build();
|
|
56
|
+
mockUserRepo.findByEmail.mockResolvedValue(lockedUser);
|
|
57
|
+
await expect(authService.login('locked@test.com', 'password'))
|
|
58
|
+
.rejects.toThrow('ACCOUNT_LOCKED');
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 5단계: 구현 (테스트가 이끈 설계)
|
|
63
|
+
```typescript
|
|
64
|
+
class AuthService {
|
|
65
|
+
constructor(private userRepo: UserRepository) {}
|
|
66
|
+
|
|
67
|
+
async login(email: string, password: string): Promise<LoginResult> {
|
|
68
|
+
const user = await this.userRepo.findByEmail(email);
|
|
69
|
+
if (!user) throw new AuthError('INVALID_CREDENTIALS');
|
|
70
|
+
if (user.status === 'locked') throw new AuthError('ACCOUNT_LOCKED');
|
|
71
|
+
|
|
72
|
+
const isValid = await compare(password, user.password);
|
|
73
|
+
if (!isValid) throw new AuthError('INVALID_CREDENTIALS');
|
|
74
|
+
|
|
75
|
+
const token = this.generateToken(user);
|
|
76
|
+
return { token, user: this.toUserDto(user) };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Anti-Patterns
|
|
82
|
+
|
|
83
|
+
| 이름 | 문제 | 해결 |
|
|
84
|
+
|------|------|------|
|
|
85
|
+
| Test After | 테스트가 설계에 영향 못 줌 | 테스트 먼저, 실패 확인 후 구현 |
|
|
86
|
+
| Too Big Step | 실패 원인 파악 어려움 | Starter Test로 시작, 점진적 확장 |
|
|
87
|
+
| Test the Implementation | 리팩토링 시 테스트 깨짐 | 동작(behavior)을 테스트, public API만 |
|
|
88
|
+
| Skipping Refactor | 기술 부채 누적 | 매 사이클마다 Refactor 필수 |
|