feat: basecamp-project skill

This commit is contained in:
m3tm3re
2026-04-24 20:00:33 +02:00
parent 0ad41acb03
commit 6e0e847299
211 changed files with 46029 additions and 2592 deletions

View File

@@ -0,0 +1,255 @@
# Architecture Template
Template for `.planning/codebase/ARCHITECTURE.md` - captures conceptual code organization.
**Purpose:** Document how the code is organized at a conceptual level. Complements STRUCTURE.md (which shows physical file locations).
---
## File Template
```markdown
# Architecture
**Analysis Date:** [YYYY-MM-DD]
## Pattern Overview
**Overall:** [Pattern name: e.g., "Monolithic CLI", "Serverless API", "Full-stack MVC"]
**Key Characteristics:**
- [Characteristic 1: e.g., "Single executable"]
- [Characteristic 2: e.g., "Stateless request handling"]
- [Characteristic 3: e.g., "Event-driven"]
## Layers
[Describe the conceptual layers and their responsibilities]
**[Layer Name]:**
- Purpose: [What this layer does]
- Contains: [Types of code: e.g., "route handlers", "business logic"]
- Depends on: [What it uses: e.g., "data layer only"]
- Used by: [What uses it: e.g., "API routes"]
**[Layer Name]:**
- Purpose: [What this layer does]
- Contains: [Types of code]
- Depends on: [What it uses]
- Used by: [What uses it]
## Data Flow
[Describe the typical request/execution lifecycle]
**[Flow Name] (e.g., "HTTP Request", "CLI Command", "Event Processing"):**
1. [Entry point: e.g., "User runs command"]
2. [Processing step: e.g., "Router matches path"]
3. [Processing step: e.g., "Controller validates input"]
4. [Processing step: e.g., "Service executes logic"]
5. [Output: e.g., "Response returned"]
**State Management:**
- [How state is handled: e.g., "Stateless - no persistent state", "Database per request", "In-memory cache"]
## Key Abstractions
[Core concepts/patterns used throughout the codebase]
**[Abstraction Name]:**
- Purpose: [What it represents]
- Examples: [e.g., "UserService, ProjectService"]
- Pattern: [e.g., "Singleton", "Factory", "Repository"]
**[Abstraction Name]:**
- Purpose: [What it represents]
- Examples: [Concrete examples]
- Pattern: [Pattern used]
## Entry Points
[Where execution begins]
**[Entry Point]:**
- Location: [Brief: e.g., "src/index.ts", "API Gateway triggers"]
- Triggers: [What invokes it: e.g., "CLI invocation", "HTTP request"]
- Responsibilities: [What it does: e.g., "Parse args, route to command"]
## Error Handling
**Strategy:** [How errors are handled: e.g., "Exception bubbling to top-level handler", "Per-route error middleware"]
**Patterns:**
- [Pattern: e.g., "try/catch at controller level"]
- [Pattern: e.g., "Error codes returned to user"]
## Cross-Cutting Concerns
[Aspects that affect multiple layers]
**Logging:**
- [Approach: e.g., "Winston logger, injected per-request"]
**Validation:**
- [Approach: e.g., "Zod schemas at API boundary"]
**Authentication:**
- [Approach: e.g., "JWT middleware on protected routes"]
---
*Architecture analysis: [date]*
*Update when major patterns change*
```
<good_examples>
```markdown
# Architecture
**Analysis Date:** 2025-01-20
## Pattern Overview
**Overall:** CLI Application with Plugin System
**Key Characteristics:**
- Single executable with subcommands
- Plugin-based extensibility
- File-based state (no database)
- Synchronous execution model
## Layers
**Command Layer:**
- Purpose: Parse user input and route to appropriate handler
- Contains: Command definitions, argument parsing, help text
- Location: `src/commands/*.ts`
- Depends on: Service layer for business logic
- Used by: CLI entry point (`src/index.ts`)
**Service Layer:**
- Purpose: Core business logic
- Contains: FileService, TemplateService, InstallService
- Location: `src/services/*.ts`
- Depends on: File system utilities, external tools
- Used by: Command handlers
**Utility Layer:**
- Purpose: Shared helpers and abstractions
- Contains: File I/O wrappers, path resolution, string formatting
- Location: `src/utils/*.ts`
- Depends on: Node.js built-ins only
- Used by: Service layer
## Data Flow
**CLI Command Execution:**
1. User runs: `gsd new-project`
2. Commander parses args and flags
3. Command handler invoked (`src/commands/new-project.ts`)
4. Handler calls service methods (`src/services/project.ts``create()`)
5. Service reads templates, processes files, writes output
6. Results logged to console
7. Process exits with status code
**State Management:**
- File-based: All state lives in `.planning/` directory
- No persistent in-memory state
- Each command execution is independent
## Key Abstractions
**Service:**
- Purpose: Encapsulate business logic for a domain
- Examples: `src/services/file.ts`, `src/services/template.ts`, `src/services/project.ts`
- Pattern: Singleton-like (imported as modules, not instantiated)
**Command:**
- Purpose: CLI command definition
- Examples: `src/commands/new-project.ts`, `src/commands/plan-phase.ts`
- Pattern: Commander.js command registration
**Template:**
- Purpose: Reusable document structures
- Examples: PROJECT.md, PLAN.md templates
- Pattern: Markdown files with substitution variables
## Entry Points
**CLI Entry:**
- Location: `src/index.ts`
- Triggers: User runs `gsd <command>`
- Responsibilities: Register commands, parse args, display help
**Commands:**
- Location: `src/commands/*.ts`
- Triggers: Matched command from CLI
- Responsibilities: Validate input, call services, format output
## Error Handling
**Strategy:** Throw exceptions, catch at command level, log and exit
**Patterns:**
- Services throw Error with descriptive messages
- Command handlers catch, log error to stderr, exit(1)
- Validation errors shown before execution (fail fast)
## Cross-Cutting Concerns
**Logging:**
- Console.log for normal output
- Console.error for errors
- Chalk for colored output
**Validation:**
- Zod schemas for config file parsing
- Manual validation in command handlers
- Fail fast on invalid input
**File Operations:**
- FileService abstraction over fs-extra
- All paths validated before operations
- Atomic writes (temp file + rename)
---
*Architecture analysis: 2025-01-20*
*Update when major patterns change*
```
</good_examples>
<guidelines>
**What belongs in ARCHITECTURE.md:**
- Overall architectural pattern (monolith, microservices, layered, etc.)
- Conceptual layers and their relationships
- Data flow / request lifecycle
- Key abstractions and patterns
- Entry points
- Error handling strategy
- Cross-cutting concerns (logging, auth, validation)
**What does NOT belong here:**
- Exhaustive file listings (that's STRUCTURE.md)
- Technology choices (that's STACK.md)
- Line-by-line code walkthrough (defer to code reading)
- Implementation details of specific features
**File paths ARE welcome:**
Include file paths as concrete examples of abstractions. Use backtick formatting: `src/services/user.ts`. This makes the architecture document actionable for the agent when planning.
**When filling this template:**
- Read main entry points (index, server, main)
- Identify layers by reading imports/dependencies
- Trace a typical request/command execution
- Note recurring patterns (services, controllers, repositories)
- Keep descriptions conceptual, not mechanical
**Useful for phase planning when:**
- Adding new features (where does it fit in the layers?)
- Refactoring (understanding current patterns)
- Identifying where to add code (which layer handles X?)
- Understanding dependencies between components
</guidelines>

View File

@@ -0,0 +1,310 @@
# Codebase Concerns Template
Template for `.planning/codebase/CONCERNS.md` - captures known issues and areas requiring care.
**Purpose:** Surface actionable warnings about the codebase. Focused on "what to watch out for when making changes."
---
## File Template
```markdown
# Codebase Concerns
**Analysis Date:** [YYYY-MM-DD]
## Tech Debt
**[Area/Component]:**
- Issue: [What's the shortcut/workaround]
- Why: [Why it was done this way]
- Impact: [What breaks or degrades because of it]
- Fix approach: [How to properly address it]
**[Area/Component]:**
- Issue: [What's the shortcut/workaround]
- Why: [Why it was done this way]
- Impact: [What breaks or degrades because of it]
- Fix approach: [How to properly address it]
## Known Bugs
**[Bug description]:**
- Symptoms: [What happens]
- Trigger: [How to reproduce]
- Workaround: [Temporary mitigation if any]
- Root cause: [If known]
- Blocked by: [If waiting on something]
**[Bug description]:**
- Symptoms: [What happens]
- Trigger: [How to reproduce]
- Workaround: [Temporary mitigation if any]
- Root cause: [If known]
## Security Considerations
**[Area requiring security care]:**
- Risk: [What could go wrong]
- Current mitigation: [What's in place now]
- Recommendations: [What should be added]
**[Area requiring security care]:**
- Risk: [What could go wrong]
- Current mitigation: [What's in place now]
- Recommendations: [What should be added]
## Performance Bottlenecks
**[Slow operation/endpoint]:**
- Problem: [What's slow]
- Measurement: [Actual numbers: "500ms p95", "2s load time"]
- Cause: [Why it's slow]
- Improvement path: [How to speed it up]
**[Slow operation/endpoint]:**
- Problem: [What's slow]
- Measurement: [Actual numbers]
- Cause: [Why it's slow]
- Improvement path: [How to speed it up]
## Fragile Areas
**[Component/Module]:**
- Why fragile: [What makes it break easily]
- Common failures: [What typically goes wrong]
- Safe modification: [How to change it without breaking]
- Test coverage: [Is it tested? Gaps?]
**[Component/Module]:**
- Why fragile: [What makes it break easily]
- Common failures: [What typically goes wrong]
- Safe modification: [How to change it without breaking]
- Test coverage: [Is it tested? Gaps?]
## Scaling Limits
**[Resource/System]:**
- Current capacity: [Numbers: "100 req/sec", "10k users"]
- Limit: [Where it breaks]
- Symptoms at limit: [What happens]
- Scaling path: [How to increase capacity]
## Dependencies at Risk
**[Package/Service]:**
- Risk: [e.g., "deprecated", "unmaintained", "breaking changes coming"]
- Impact: [What breaks if it fails]
- Migration plan: [Alternative or upgrade path]
## Missing Critical Features
**[Feature gap]:**
- Problem: [What's missing]
- Current workaround: [How users cope]
- Blocks: [What can't be done without it]
- Implementation complexity: [Rough effort estimate]
## Test Coverage Gaps
**[Untested area]:**
- What's not tested: [Specific functionality]
- Risk: [What could break unnoticed]
- Priority: [High/Medium/Low]
- Difficulty to test: [Why it's not tested yet]
---
*Concerns audit: [date]*
*Update as issues are fixed or new ones discovered*
```
<good_examples>
```markdown
# Codebase Concerns
**Analysis Date:** 2025-01-20
## Tech Debt
**Database queries in React components:**
- Issue: Direct Supabase queries in 15+ page components instead of server actions
- Files: `app/dashboard/page.tsx`, `app/profile/page.tsx`, `app/courses/[id]/page.tsx`, `app/settings/page.tsx` (and 11 more in `app/`)
- Why: Rapid prototyping during MVP phase
- Impact: Can't implement RLS properly, exposes DB structure to client
- Fix approach: Move all queries to server actions in `app/actions/`, add proper RLS policies
**Manual webhook signature validation:**
- Issue: Copy-pasted Stripe webhook verification code in 3 different endpoints
- Files: `app/api/webhooks/stripe/route.ts`, `app/api/webhooks/checkout/route.ts`, `app/api/webhooks/subscription/route.ts`
- Why: Each webhook added ad-hoc without abstraction
- Impact: Easy to miss verification in new webhooks (security risk)
- Fix approach: Create shared `lib/stripe/validate-webhook.ts` middleware
## Known Bugs
**Race condition in subscription updates:**
- Symptoms: User shows as "free" tier for 5-10 seconds after successful payment
- Trigger: Fast navigation after Stripe checkout redirect, before webhook processes
- Files: `app/checkout/success/page.tsx` (redirect handler), `app/api/webhooks/stripe/route.ts` (webhook)
- Workaround: Stripe webhook eventually updates status (self-heals)
- Root cause: Webhook processing slower than user navigation, no optimistic UI update
- Fix: Add polling in `app/checkout/success/page.tsx` after redirect
**Inconsistent session state after logout:**
- Symptoms: User redirected to /dashboard after logout instead of /login
- Trigger: Logout via button in mobile nav (desktop works fine)
- File: `components/MobileNav.tsx` (line ~45, logout handler)
- Workaround: Manual URL navigation to /login works
- Root cause: Mobile nav component not awaiting supabase.auth.signOut()
- Fix: Add await to logout handler in `components/MobileNav.tsx`
## Security Considerations
**Admin role check client-side only:**
- Risk: Admin dashboard pages check isAdmin from Supabase client, no server verification
- Files: `app/admin/page.tsx`, `app/admin/users/page.tsx`, `components/AdminGuard.tsx`
- Current mitigation: None (relying on UI hiding)
- Recommendations: Add middleware to admin routes in `middleware.ts`, verify role server-side
**Unvalidated file uploads:**
- Risk: Users can upload any file type to avatar bucket (no size/type validation)
- File: `components/AvatarUpload.tsx` (upload handler)
- Current mitigation: Supabase bucket limits to 2MB (configured in dashboard)
- Recommendations: Add file type validation (image/* only) in `lib/storage/validate.ts`
## Performance Bottlenecks
**/api/courses endpoint:**
- Problem: Fetching all courses with nested lessons and authors
- File: `app/api/courses/route.ts`
- Measurement: 1.2s p95 response time with 50+ courses
- Cause: N+1 query pattern (separate query per course for lessons)
- Improvement path: Use Prisma include to eager-load lessons in `lib/db/courses.ts`, add Redis caching
**Dashboard initial load:**
- Problem: Waterfall of 5 serial API calls on mount
- File: `app/dashboard/page.tsx`
- Measurement: 3.5s until interactive on slow 3G
- Cause: Each component fetches own data independently
- Improvement path: Convert to Server Component with single parallel fetch
## Fragile Areas
**Authentication middleware chain:**
- File: `middleware.ts`
- Why fragile: 4 different middleware functions run in specific order (auth -> role -> subscription -> logging)
- Common failures: Middleware order change breaks everything, hard to debug
- Safe modification: Add tests before changing order, document dependencies in comments
- Test coverage: No integration tests for middleware chain (only unit tests)
**Stripe webhook event handling:**
- File: `app/api/webhooks/stripe/route.ts`
- Why fragile: Giant switch statement with 12 event types, shared transaction logic
- Common failures: New event type added without handling, partial DB updates on error
- Safe modification: Extract each event handler to `lib/stripe/handlers/*.ts`
- Test coverage: Only 3 of 12 event types have tests
## Scaling Limits
**Supabase Free Tier:**
- Current capacity: 500MB database, 1GB file storage, 2GB bandwidth/month
- Limit: ~5000 users estimated before hitting limits
- Symptoms at limit: 429 rate limit errors, DB writes fail
- Scaling path: Upgrade to Pro ($25/mo) extends to 8GB DB, 100GB storage
**Server-side render blocking:**
- Current capacity: ~50 concurrent users before slowdown
- Limit: Vercel Hobby plan (10s function timeout, 100GB-hrs/mo)
- Symptoms at limit: 504 gateway timeouts on course pages
- Scaling path: Upgrade to Vercel Pro ($20/mo), add edge caching
## Dependencies at Risk
**react-hot-toast:**
- Risk: Unmaintained (last update 18 months ago), React 19 compatibility unknown
- Impact: Toast notifications break, no graceful degradation
- Migration plan: Switch to sonner (actively maintained, similar API)
## Missing Critical Features
**Payment failure handling:**
- Problem: No retry mechanism or user notification when subscription payment fails
- Current workaround: Users manually re-enter payment info (if they notice)
- Blocks: Can't retain users with expired cards, no dunning process
- Implementation complexity: Medium (Stripe webhooks + email flow + UI)
**Course progress tracking:**
- Problem: No persistent state for which lessons completed
- Current workaround: Users manually track progress
- Blocks: Can't show completion percentage, can't recommend next lesson
- Implementation complexity: Low (add completed_lessons junction table)
## Test Coverage Gaps
**Payment flow end-to-end:**
- What's not tested: Full Stripe checkout -> webhook -> subscription activation flow
- Risk: Payment processing could break silently (has happened twice)
- Priority: High
- Difficulty to test: Need Stripe test fixtures and webhook simulation setup
**Error boundary behavior:**
- What's not tested: How app behaves when components throw errors
- Risk: White screen of death for users, no error reporting
- Priority: Medium
- Difficulty to test: Need to intentionally trigger errors in test environment
---
*Concerns audit: 2025-01-20*
*Update as issues are fixed or new ones discovered*
```
</good_examples>
<guidelines>
**What belongs in CONCERNS.md:**
- Tech debt with clear impact and fix approach
- Known bugs with reproduction steps
- Security gaps and mitigation recommendations
- Performance bottlenecks with measurements
- Fragile code that breaks easily
- Scaling limits with numbers
- Dependencies that need attention
- Missing features that block workflows
- Test coverage gaps
**What does NOT belong here:**
- Opinions without evidence ("code is messy")
- Complaints without solutions ("auth sucks")
- Future feature ideas (that's for product planning)
- Normal TODOs (those live in code comments)
- Architectural decisions that are working fine
- Minor code style issues
**When filling this template:**
- **Always include file paths** - Concerns without locations are not actionable. Use backticks: `src/file.ts`
- Be specific with measurements ("500ms p95" not "slow")
- Include reproduction steps for bugs
- Suggest fix approaches, not just problems
- Focus on actionable items
- Prioritize by risk/impact
- Update as issues get resolved
- Add new concerns as discovered
**Tone guidelines:**
- Professional, not emotional ("N+1 query pattern" not "terrible queries")
- Solution-oriented ("Fix: add index" not "needs fixing")
- Risk-focused ("Could expose user data" not "security is bad")
- Factual ("3.5s load time" not "really slow")
**Useful for phase planning when:**
- Deciding what to work on next
- Estimating risk of changes
- Understanding where to be careful
- Prioritizing improvements
- Onboarding new the agent contexts
- Planning refactoring work
**How this gets populated:**
Explore agents detect these during codebase mapping. Manual additions welcome for human-discovered issues. This is living documentation, not a complaint list.
</guidelines>

View File

@@ -0,0 +1,307 @@
# Coding Conventions Template
Template for `.planning/codebase/CONVENTIONS.md` - captures coding style and patterns.
**Purpose:** Document how code is written in this codebase. Prescriptive guide for the agent to match existing style.
---
## File Template
```markdown
# Coding Conventions
**Analysis Date:** [YYYY-MM-DD]
## Naming Patterns
**Files:**
- [Pattern: e.g., "kebab-case for all files"]
- [Test files: e.g., "*.test.ts alongside source"]
- [Components: e.g., "PascalCase.tsx for React components"]
**Functions:**
- [Pattern: e.g., "camelCase for all functions"]
- [Async: e.g., "no special prefix for async functions"]
- [Handlers: e.g., "handleEventName for event handlers"]
**Variables:**
- [Pattern: e.g., "camelCase for variables"]
- [Constants: e.g., "UPPER_SNAKE_CASE for constants"]
- [Private: e.g., "_prefix for private members" or "no prefix"]
**Types:**
- [Interfaces: e.g., "PascalCase, no I prefix"]
- [Types: e.g., "PascalCase for type aliases"]
- [Enums: e.g., "PascalCase for enum name, UPPER_CASE for values"]
## Code Style
**Formatting:**
- [Tool: e.g., "Prettier with config in .prettierrc"]
- [Line length: e.g., "100 characters max"]
- [Quotes: e.g., "single quotes for strings"]
- [Semicolons: e.g., "required" or "omitted"]
**Linting:**
- [Tool: e.g., "ESLint with eslint.config.js"]
- [Rules: e.g., "extends airbnb-base, no console in production"]
- [Run: e.g., "npm run lint"]
## Import Organization
**Order:**
1. [e.g., "External packages (react, express, etc.)"]
2. [e.g., "Internal modules (@/lib, @/components)"]
3. [e.g., "Relative imports (., ..)"]
4. [e.g., "Type imports (import type {})"]
**Grouping:**
- [Blank lines: e.g., "blank line between groups"]
- [Sorting: e.g., "alphabetical within each group"]
**Path Aliases:**
- [Aliases used: e.g., "@/ for src/, @components/ for src/components/"]
## Error Handling
**Patterns:**
- [Strategy: e.g., "throw errors, catch at boundaries"]
- [Custom errors: e.g., "extend Error class, named *Error"]
- [Async: e.g., "use try/catch, no .catch() chains"]
**Error Types:**
- [When to throw: e.g., "invalid input, missing dependencies"]
- [When to return: e.g., "expected failures return Result<T, E>"]
- [Logging: e.g., "log error with context before throwing"]
## Logging
**Framework:**
- [Tool: e.g., "console.log, pino, winston"]
- [Levels: e.g., "debug, info, warn, error"]
**Patterns:**
- [Format: e.g., "structured logging with context object"]
- [When: e.g., "log state transitions, external calls"]
- [Where: e.g., "log at service boundaries, not in utils"]
## Comments
**When to Comment:**
- [e.g., "explain why, not what"]
- [e.g., "document business logic, algorithms, edge cases"]
- [e.g., "avoid obvious comments like // increment counter"]
**JSDoc/TSDoc:**
- [Usage: e.g., "required for public APIs, optional for internal"]
- [Format: e.g., "use @param, @returns, @throws tags"]
**TODO Comments:**
- [Pattern: e.g., "// TODO(username): description"]
- [Tracking: e.g., "link to issue number if available"]
## Function Design
**Size:**
- [e.g., "keep under 50 lines, extract helpers"]
**Parameters:**
- [e.g., "max 3 parameters, use object for more"]
- [e.g., "destructure objects in parameter list"]
**Return Values:**
- [e.g., "explicit returns, no implicit undefined"]
- [e.g., "return early for guard clauses"]
## Module Design
**Exports:**
- [e.g., "named exports preferred, default exports for React components"]
- [e.g., "export from index.ts for public API"]
**Barrel Files:**
- [e.g., "use index.ts to re-export public API"]
- [e.g., "avoid circular dependencies"]
---
*Convention analysis: [date]*
*Update when patterns change*
```
<good_examples>
```markdown
# Coding Conventions
**Analysis Date:** 2025-01-20
## Naming Patterns
**Files:**
- kebab-case for all files (command-handler.ts, user-service.ts)
- *.test.ts alongside source files
- index.ts for barrel exports
**Functions:**
- camelCase for all functions
- No special prefix for async functions
- handleEventName for event handlers (handleClick, handleSubmit)
**Variables:**
- camelCase for variables
- UPPER_SNAKE_CASE for constants (MAX_RETRIES, API_BASE_URL)
- No underscore prefix (no private marker in TS)
**Types:**
- PascalCase for interfaces, no I prefix (User, not IUser)
- PascalCase for type aliases (UserConfig, ResponseData)
- PascalCase for enum names, UPPER_CASE for values (Status.PENDING)
## Code Style
**Formatting:**
- Prettier with .prettierrc
- 100 character line length
- Single quotes for strings
- Semicolons required
- 2 space indentation
**Linting:**
- ESLint with eslint.config.js
- Extends @typescript-eslint/recommended
- No console.log in production code (use logger)
- Run: npm run lint
## Import Organization
**Order:**
1. External packages (react, express, commander)
2. Internal modules (@/lib, @/services)
3. Relative imports (./utils, ../types)
4. Type imports (import type { User })
**Grouping:**
- Blank line between groups
- Alphabetical within each group
- Type imports last within each group
**Path Aliases:**
- @/ maps to src/
- No other aliases defined
## Error Handling
**Patterns:**
- Throw errors, catch at boundaries (route handlers, main functions)
- Extend Error class for custom errors (ValidationError, NotFoundError)
- Async functions use try/catch, no .catch() chains
**Error Types:**
- Throw on invalid input, missing dependencies, invariant violations
- Log error with context before throwing: logger.error({ err, userId }, 'Failed to process')
- Include cause in error message: new Error('Failed to X', { cause: originalError })
## Logging
**Framework:**
- pino logger instance exported from lib/logger.ts
- Levels: debug, info, warn, error (no trace)
**Patterns:**
- Structured logging with context: logger.info({ userId, action }, 'User action')
- Log at service boundaries, not in utility functions
- Log state transitions, external API calls, errors
- No console.log in committed code
## Comments
**When to Comment:**
- Explain why, not what: // Retry 3 times because API has transient failures
- Document business rules: // Users must verify email within 24 hours
- Explain non-obvious algorithms or workarounds
- Avoid obvious comments: // set count to 0
**JSDoc/TSDoc:**
- Required for public API functions
- Optional for internal functions if signature is self-explanatory
- Use @param, @returns, @throws tags
**TODO Comments:**
- Format: // TODO: description (no username, using git blame)
- Link to issue if exists: // TODO: Fix race condition (issue #123)
## Function Design
**Size:**
- Keep under 50 lines
- Extract helpers for complex logic
- One level of abstraction per function
**Parameters:**
- Max 3 parameters
- Use options object for 4+ parameters: function create(options: CreateOptions)
- Destructure in parameter list: function process({ id, name }: ProcessParams)
**Return Values:**
- Explicit return statements
- Return early for guard clauses
- Use Result<T, E> type for expected failures
## Module Design
**Exports:**
- Named exports preferred
- Default exports only for React components
- Export public API from index.ts barrel files
**Barrel Files:**
- index.ts re-exports public API
- Keep internal helpers private (don't export from index)
- Avoid circular dependencies (import from specific files if needed)
---
*Convention analysis: 2025-01-20*
*Update when patterns change*
```
</good_examples>
<guidelines>
**What belongs in CONVENTIONS.md:**
- Naming patterns observed in the codebase
- Formatting rules (Prettier config, linting rules)
- Import organization patterns
- Error handling strategy
- Logging approach
- Comment conventions
- Function and module design patterns
**What does NOT belong here:**
- Architecture decisions (that's ARCHITECTURE.md)
- Technology choices (that's STACK.md)
- Test patterns (that's TESTING.md)
- File organization (that's STRUCTURE.md)
**When filling this template:**
- Check .prettierrc, .eslintrc, or similar config files
- Examine 5-10 representative source files for patterns
- Look for consistency: if 80%+ follows a pattern, document it
- Be prescriptive: "Use X" not "Sometimes Y is used"
- Note deviations: "Legacy code uses Y, new code should use X"
- Keep under ~150 lines total
**Useful for phase planning when:**
- Writing new code (match existing style)
- Adding features (follow naming patterns)
- Refactoring (apply consistent conventions)
- Code review (check against documented patterns)
- Onboarding (understand style expectations)
**Analysis approach:**
- Scan src/ directory for file naming patterns
- Check package.json scripts for lint/format commands
- Read 5-10 files to identify function naming, error handling
- Look for config files (.prettierrc, eslint.config.js)
- Note patterns in imports, comments, function signatures
</guidelines>

View File

@@ -0,0 +1,280 @@
# External Integrations Template
Template for `.planning/codebase/INTEGRATIONS.md` - captures external service dependencies.
**Purpose:** Document what external systems this codebase communicates with. Focused on "what lives outside our code that we depend on."
---
## File Template
```markdown
# External Integrations
**Analysis Date:** [YYYY-MM-DD]
## APIs & External Services
**Payment Processing:**
- [Service] - [What it's used for: e.g., "subscription billing, one-time payments"]
- SDK/Client: [e.g., "stripe npm package v14.x"]
- Auth: [e.g., "API key in STRIPE_SECRET_KEY env var"]
- Endpoints used: [e.g., "checkout sessions, webhooks"]
**Email/SMS:**
- [Service] - [What it's used for: e.g., "transactional emails"]
- SDK/Client: [e.g., "sendgrid/mail v8.x"]
- Auth: [e.g., "API key in SENDGRID_API_KEY env var"]
- Templates: [e.g., "managed in SendGrid dashboard"]
**External APIs:**
- [Service] - [What it's used for]
- Integration method: [e.g., "REST API via fetch", "GraphQL client"]
- Auth: [e.g., "OAuth2 token in AUTH_TOKEN env var"]
- Rate limits: [if applicable]
## Data Storage
**Databases:**
- [Type/Provider] - [e.g., "PostgreSQL on Supabase"]
- Connection: [e.g., "via DATABASE_URL env var"]
- Client: [e.g., "Prisma ORM v5.x"]
- Migrations: [e.g., "prisma migrate in migrations/"]
**File Storage:**
- [Service] - [e.g., "AWS S3 for user uploads"]
- SDK/Client: [e.g., "@aws-sdk/client-s3"]
- Auth: [e.g., "IAM credentials in AWS_* env vars"]
- Buckets: [e.g., "prod-uploads, dev-uploads"]
**Caching:**
- [Service] - [e.g., "Redis for session storage"]
- Connection: [e.g., "REDIS_URL env var"]
- Client: [e.g., "ioredis v5.x"]
## Authentication & Identity
**Auth Provider:**
- [Service] - [e.g., "Supabase Auth", "Auth0", "custom JWT"]
- Implementation: [e.g., "Supabase client SDK"]
- Token storage: [e.g., "httpOnly cookies", "localStorage"]
- Session management: [e.g., "JWT refresh tokens"]
**OAuth Integrations:**
- [Provider] - [e.g., "Google OAuth for sign-in"]
- Credentials: [e.g., "GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET"]
- Scopes: [e.g., "email, profile"]
## Monitoring & Observability
**Error Tracking:**
- [Service] - [e.g., "Sentry"]
- DSN: [e.g., "SENTRY_DSN env var"]
- Release tracking: [e.g., "via SENTRY_RELEASE"]
**Analytics:**
- [Service] - [e.g., "Mixpanel for product analytics"]
- Token: [e.g., "MIXPANEL_TOKEN env var"]
- Events tracked: [e.g., "user actions, page views"]
**Logs:**
- [Service] - [e.g., "CloudWatch", "Datadog", "none (stdout only)"]
- Integration: [e.g., "AWS Lambda built-in"]
## CI/CD & Deployment
**Hosting:**
- [Platform] - [e.g., "Vercel", "AWS Lambda", "Docker on ECS"]
- Deployment: [e.g., "automatic on main branch push"]
- Environment vars: [e.g., "configured in Vercel dashboard"]
**CI Pipeline:**
- [Service] - [e.g., "GitHub Actions"]
- Workflows: [e.g., "test.yml, deploy.yml"]
- Secrets: [e.g., "stored in GitHub repo secrets"]
## Environment Configuration
**Development:**
- Required env vars: [List critical vars]
- Secrets location: [e.g., ".env.local (gitignored)", "1Password vault"]
- Mock/stub services: [e.g., "Stripe test mode", "local PostgreSQL"]
**Staging:**
- Environment-specific differences: [e.g., "uses staging Stripe account"]
- Data: [e.g., "separate staging database"]
**Production:**
- Secrets management: [e.g., "Vercel environment variables"]
- Failover/redundancy: [e.g., "multi-region DB replication"]
## Webhooks & Callbacks
**Incoming:**
- [Service] - [Endpoint: e.g., "/api/webhooks/stripe"]
- Verification: [e.g., "signature validation via stripe.webhooks.constructEvent"]
- Events: [e.g., "payment_intent.succeeded, customer.subscription.updated"]
**Outgoing:**
- [Service] - [What triggers it]
- Endpoint: [e.g., "external CRM webhook on user signup"]
- Retry logic: [if applicable]
---
*Integration audit: [date]*
*Update when adding/removing external services*
```
<good_examples>
```markdown
# External Integrations
**Analysis Date:** 2025-01-20
## APIs & External Services
**Payment Processing:**
- Stripe - Subscription billing and one-time course payments
- SDK/Client: stripe npm package v14.8
- Auth: API key in STRIPE_SECRET_KEY env var
- Endpoints used: checkout sessions, customer portal, webhooks
**Email/SMS:**
- SendGrid - Transactional emails (receipts, password resets)
- SDK/Client: @sendgrid/mail v8.1
- Auth: API key in SENDGRID_API_KEY env var
- Templates: Managed in SendGrid dashboard (template IDs in code)
**External APIs:**
- OpenAI API - Course content generation
- Integration method: REST API via openai npm package v4.x
- Auth: Bearer token in OPENAI_API_KEY env var
- Rate limits: 3500 requests/min (tier 3)
## Data Storage
**Databases:**
- PostgreSQL on Supabase - Primary data store
- Connection: via DATABASE_URL env var
- Client: Prisma ORM v5.8
- Migrations: prisma migrate in prisma/migrations/
**File Storage:**
- Supabase Storage - User uploads (profile images, course materials)
- SDK/Client: @supabase/supabase-js v2.x
- Auth: Service role key in SUPABASE_SERVICE_ROLE_KEY
- Buckets: avatars (public), course-materials (private)
**Caching:**
- None currently (all database queries, no Redis)
## Authentication & Identity
**Auth Provider:**
- Supabase Auth - Email/password + OAuth
- Implementation: Supabase client SDK with server-side session management
- Token storage: httpOnly cookies via @supabase/ssr
- Session management: JWT refresh tokens handled by Supabase
**OAuth Integrations:**
- Google OAuth - Social sign-in
- Credentials: GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET (Supabase dashboard)
- Scopes: email, profile
## Monitoring & Observability
**Error Tracking:**
- Sentry - Server and client errors
- DSN: SENTRY_DSN env var
- Release tracking: Git commit SHA via SENTRY_RELEASE
**Analytics:**
- None (planned: Mixpanel)
**Logs:**
- Vercel logs - stdout/stderr only
- Retention: 7 days on Pro plan
## CI/CD & Deployment
**Hosting:**
- Vercel - Next.js app hosting
- Deployment: Automatic on main branch push
- Environment vars: Configured in Vercel dashboard (synced to .env.example)
**CI Pipeline:**
- GitHub Actions - Tests and type checking
- Workflows: .github/workflows/ci.yml
- Secrets: None needed (public repo tests only)
## Environment Configuration
**Development:**
- Required env vars: DATABASE_URL, NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY
- Secrets location: .env.local (gitignored), team shared via 1Password vault
- Mock/stub services: Stripe test mode, Supabase local dev project
**Staging:**
- Uses separate Supabase staging project
- Stripe test mode
- Same Vercel account, different environment
**Production:**
- Secrets management: Vercel environment variables
- Database: Supabase production project with daily backups
## Webhooks & Callbacks
**Incoming:**
- Stripe - /api/webhooks/stripe
- Verification: Signature validation via stripe.webhooks.constructEvent
- Events: payment_intent.succeeded, customer.subscription.updated, customer.subscription.deleted
**Outgoing:**
- None
---
*Integration audit: 2025-01-20*
*Update when adding/removing external services*
```
</good_examples>
<guidelines>
**What belongs in INTEGRATIONS.md:**
- External services the code communicates with
- Authentication patterns (where secrets live, not the secrets themselves)
- SDKs and client libraries used
- Environment variable names (not values)
- Webhook endpoints and verification methods
- Database connection patterns
- File storage locations
- Monitoring and logging services
**What does NOT belong here:**
- Actual API keys or secrets (NEVER write these)
- Internal architecture (that's ARCHITECTURE.md)
- Code patterns (that's PATTERNS.md)
- Technology choices (that's STACK.md)
- Performance issues (that's CONCERNS.md)
**When filling this template:**
- Check .env.example or .env.template for required env vars
- Look for SDK imports (stripe, @sendgrid/mail, etc.)
- Check for webhook handlers in routes/endpoints
- Note where secrets are managed (not the secrets)
- Document environment-specific differences (dev/staging/prod)
- Include auth patterns for each service
**Useful for phase planning when:**
- Adding new external service integrations
- Debugging authentication issues
- Understanding data flow outside the application
- Setting up new environments
- Auditing third-party dependencies
- Planning for service outages or migrations
**Security note:**
Document WHERE secrets live (env vars, Vercel dashboard, 1Password), never WHAT the secrets are.
</guidelines>

View File

@@ -0,0 +1,186 @@
# Technology Stack Template
Template for `.planning/codebase/STACK.md` - captures the technology foundation.
**Purpose:** Document what technologies run this codebase. Focused on "what executes when you run the code."
---
## File Template
```markdown
# Technology Stack
**Analysis Date:** [YYYY-MM-DD]
## Languages
**Primary:**
- [Language] [Version] - [Where used: e.g., "all application code"]
**Secondary:**
- [Language] [Version] - [Where used: e.g., "build scripts, tooling"]
## Runtime
**Environment:**
- [Runtime] [Version] - [e.g., "Node.js 20.x"]
- [Additional requirements if any]
**Package Manager:**
- [Manager] [Version] - [e.g., "npm 10.x"]
- Lockfile: [e.g., "package-lock.json present"]
## Frameworks
**Core:**
- [Framework] [Version] - [Purpose: e.g., "web server", "UI framework"]
**Testing:**
- [Framework] [Version] - [e.g., "Jest for unit tests"]
- [Framework] [Version] - [e.g., "Playwright for E2E"]
**Build/Dev:**
- [Tool] [Version] - [e.g., "Vite for bundling"]
- [Tool] [Version] - [e.g., "TypeScript compiler"]
## Key Dependencies
[Only include dependencies critical to understanding the stack - limit to 5-10 most important]
**Critical:**
- [Package] [Version] - [Why it matters: e.g., "authentication", "database access"]
- [Package] [Version] - [Why it matters]
**Infrastructure:**
- [Package] [Version] - [e.g., "Express for HTTP routing"]
- [Package] [Version] - [e.g., "PostgreSQL client"]
## Configuration
**Environment:**
- [How configured: e.g., ".env files", "environment variables"]
- [Key configs: e.g., "DATABASE_URL, API_KEY required"]
**Build:**
- [Build config files: e.g., "vite.config.ts, tsconfig.json"]
## Platform Requirements
**Development:**
- [OS requirements or "any platform"]
- [Additional tooling: e.g., "Docker for local DB"]
**Production:**
- [Deployment target: e.g., "Vercel", "AWS Lambda", "Docker container"]
- [Version requirements]
---
*Stack analysis: [date]*
*Update after major dependency changes*
```
<good_examples>
```markdown
# Technology Stack
**Analysis Date:** 2025-01-20
## Languages
**Primary:**
- TypeScript 5.3 - All application code
**Secondary:**
- JavaScript - Build scripts, config files
## Runtime
**Environment:**
- Node.js 20.x (LTS)
- No browser runtime (CLI tool only)
**Package Manager:**
- npm 10.x
- Lockfile: `package-lock.json` present
## Frameworks
**Core:**
- None (vanilla Node.js CLI)
**Testing:**
- Vitest 1.0 - Unit tests
- tsx - TypeScript execution without build step
**Build/Dev:**
- TypeScript 5.3 - Compilation to JavaScript
- esbuild - Used by Vitest for fast transforms
## Key Dependencies
**Critical:**
- commander 11.x - CLI argument parsing and command structure
- chalk 5.x - Terminal output styling
- fs-extra 11.x - Extended file system operations
**Infrastructure:**
- Node.js built-ins - fs, path, child_process for file operations
## Configuration
**Environment:**
- No environment variables required
- Configuration via CLI flags only
**Build:**
- `tsconfig.json` - TypeScript compiler options
- `vitest.config.ts` - Test runner configuration
## Platform Requirements
**Development:**
- macOS/Linux/Windows (any platform with Node.js)
- No external dependencies
**Production:**
- Distributed as npm package
- Installed globally via npm install -g
- Runs on user's Node.js installation
---
*Stack analysis: 2025-01-20*
*Update after major dependency changes*
```
</good_examples>
<guidelines>
**What belongs in STACK.md:**
- Languages and versions
- Runtime requirements (Node, Bun, Deno, browser)
- Package manager and lockfile
- Framework choices
- Critical dependencies (limit to 5-10 most important)
- Build tooling
- Platform/deployment requirements
**What does NOT belong here:**
- File structure (that's STRUCTURE.md)
- Architectural patterns (that's ARCHITECTURE.md)
- Every dependency in package.json (only critical ones)
- Implementation details (defer to code)
**When filling this template:**
- Check package.json for dependencies
- Note runtime version from .nvmrc or package.json engines
- Include only dependencies that affect understanding (not every utility)
- Specify versions only when version matters (breaking changes, compatibility)
**Useful for phase planning when:**
- Adding new dependencies (check compatibility)
- Upgrading frameworks (know what's in use)
- Choosing implementation approach (must work with existing stack)
- Understanding build requirements
</guidelines>

View File

@@ -0,0 +1,285 @@
# Structure Template
Template for `.planning/codebase/STRUCTURE.md` - captures physical file organization.
**Purpose:** Document where things physically live in the codebase. Answers "where do I put X?"
---
## File Template
```markdown
# Codebase Structure
**Analysis Date:** [YYYY-MM-DD]
## Directory Layout
[ASCII box-drawing tree of top-level directories with purpose - use ├── └── │ characters for tree structure only]
```
[project-root]/
├── [dir]/ # [Purpose]
├── [dir]/ # [Purpose]
├── [dir]/ # [Purpose]
└── [file] # [Purpose]
```
## Directory Purposes
**[Directory Name]:**
- Purpose: [What lives here]
- Contains: [Types of files: e.g., "*.ts source files", "component directories"]
- Key files: [Important files in this directory]
- Subdirectories: [If nested, describe structure]
**[Directory Name]:**
- Purpose: [What lives here]
- Contains: [Types of files]
- Key files: [Important files]
- Subdirectories: [Structure]
## Key File Locations
**Entry Points:**
- [Path]: [Purpose: e.g., "CLI entry point"]
- [Path]: [Purpose: e.g., "Server startup"]
**Configuration:**
- [Path]: [Purpose: e.g., "TypeScript config"]
- [Path]: [Purpose: e.g., "Build configuration"]
- [Path]: [Purpose: e.g., "Environment variables"]
**Core Logic:**
- [Path]: [Purpose: e.g., "Business services"]
- [Path]: [Purpose: e.g., "Database models"]
- [Path]: [Purpose: e.g., "API routes"]
**Testing:**
- [Path]: [Purpose: e.g., "Unit tests"]
- [Path]: [Purpose: e.g., "Test fixtures"]
**Documentation:**
- [Path]: [Purpose: e.g., "User-facing docs"]
- [Path]: [Purpose: e.g., "Developer guide"]
## Naming Conventions
**Files:**
- [Pattern]: [Example: e.g., "kebab-case.ts for modules"]
- [Pattern]: [Example: e.g., "PascalCase.tsx for React components"]
- [Pattern]: [Example: e.g., "*.test.ts for test files"]
**Directories:**
- [Pattern]: [Example: e.g., "kebab-case for feature directories"]
- [Pattern]: [Example: e.g., "plural names for collections"]
**Special Patterns:**
- [Pattern]: [Example: e.g., "index.ts for directory exports"]
- [Pattern]: [Example: e.g., "__tests__ for test directories"]
## Where to Add New Code
**New Feature:**
- Primary code: [Directory path]
- Tests: [Directory path]
- Config if needed: [Directory path]
**New Component/Module:**
- Implementation: [Directory path]
- Types: [Directory path]
- Tests: [Directory path]
**New Route/Command:**
- Definition: [Directory path]
- Handler: [Directory path]
- Tests: [Directory path]
**Utilities:**
- Shared helpers: [Directory path]
- Type definitions: [Directory path]
## Special Directories
[Any directories with special meaning or generation]
**[Directory]:**
- Purpose: [e.g., "Generated code", "Build output"]
- Source: [e.g., "Auto-generated by X", "Build artifacts"]
- Committed: [Yes/No - in .gitignore?]
---
*Structure analysis: [date]*
*Update when directory structure changes*
```
<good_examples>
```markdown
# Codebase Structure
**Analysis Date:** 2025-01-20
## Directory Layout
```
get-shit-done/
├── bin/ # Executable entry points
├── commands/ # Slash command definitions
│ └── gsd/ # GSD-specific commands
├── get-shit-done/ # Skill resources
│ ├── references/ # Principle documents
│ ├── templates/ # File templates
│ └── workflows/ # Multi-step procedures
├── src/ # Source code (if applicable)
├── tests/ # Test files
├── package.json # Project manifest
└── README.md # User documentation
```
## Directory Purposes
**bin/**
- Purpose: CLI entry points
- Contains: install.js (installer script)
- Key files: install.js - handles npx installation
- Subdirectories: None
**commands/gsd/**
- Purpose: Slash command definitions for Claude Code
- Contains: *.md files (one per command)
- Key files: new-project.md, plan-phase.md, execute-plan.md
- Subdirectories: None (flat structure)
**get-shit-done/references/**
- Purpose: Core philosophy and guidance documents
- Contains: principles.md, questioning.md, plan-format.md
- Key files: principles.md - system philosophy
- Subdirectories: None
**get-shit-done/templates/**
- Purpose: Document templates for .planning/ files
- Contains: Template definitions with frontmatter
- Key files: project.md, roadmap.md, plan.md, summary.md
- Subdirectories: codebase/ (new - for stack/architecture/structure templates)
**get-shit-done/workflows/**
- Purpose: Reusable multi-step procedures
- Contains: Workflow definitions called by commands
- Key files: execute-plan.md, research-phase.md
- Subdirectories: None
## Key File Locations
**Entry Points:**
- `bin/install.js` - Installation script (npx entry)
**Configuration:**
- `package.json` - Project metadata, dependencies, bin entry
- `.gitignore` - Excluded files
**Core Logic:**
- `bin/install.js` - All installation logic (file copying, path replacement)
**Testing:**
- `tests/` - Test files (if present)
**Documentation:**
- `README.md` - User-facing installation and usage guide
- `GEMINI.md` - Instructions for Claude Code when working in this repo
## Naming Conventions
**Files:**
- kebab-case.md: Markdown documents
- kebab-case.js: JavaScript source files
- UPPERCASE.md: Important project files (README, CLAUDE, CHANGELOG)
**Directories:**
- kebab-case: All directories
- Plural for collections: templates/, commands/, workflows/
**Special Patterns:**
- {command-name}.md: Slash command definition
- *-template.md: Could be used but templates/ directory preferred
## Where to Add New Code
**New Slash Command:**
- Primary code: `commands/gsd/{command-name}.md`
- Tests: `tests/commands/{command-name}.test.js` (if testing implemented)
- Documentation: Update `README.md` with new command
**New Template:**
- Implementation: `get-shit-done/templates/{name}.md`
- Documentation: Template is self-documenting (includes guidelines)
**New Workflow:**
- Implementation: `get-shit-done/workflows/{name}.md`
- Usage: Reference from command with `@.pi/gsd/workflows/{name}.md`
**New Reference Document:**
- Implementation: `get-shit-done/references/{name}.md`
- Usage: Reference from commands/workflows as needed
**Utilities:**
- No utilities yet (`install.js` is monolithic)
- If extracted: `src/utils/`
## Special Directories
**get-shit-done/**
- Purpose: Resources installed to .agent/
- Source: Copied by bin/install.js during installation
- Committed: Yes (source of truth)
**commands/**
- Purpose: Slash commands installed to .agent/commands/
- Source: Copied by bin/install.js during installation
- Committed: Yes (source of truth)
---
*Structure analysis: 2025-01-20*
*Update when directory structure changes*
```
</good_examples>
<guidelines>
**What belongs in STRUCTURE.md:**
- Directory layout (ASCII box-drawing tree for structure visualization)
- Purpose of each directory
- Key file locations (entry points, configs, core logic)
- Naming conventions
- Where to add new code (by type)
- Special/generated directories
**What does NOT belong here:**
- Conceptual architecture (that's ARCHITECTURE.md)
- Technology stack (that's STACK.md)
- Code implementation details (defer to code reading)
- Every single file (focus on directories and key files)
**When filling this template:**
- Use `tree -L 2` or similar to visualize structure
- Identify top-level directories and their purposes
- Note naming patterns by observing existing files
- Locate entry points, configs, and main logic areas
- Keep directory tree concise (max 2-3 levels)
**Tree format (ASCII box-drawing characters for structure only):**
```
root/
├── dir1/ # Purpose
│ ├── subdir/ # Purpose
│ └── file.ts # Purpose
├── dir2/ # Purpose
└── file.ts # Purpose
```
**Useful for phase planning when:**
- Adding new features (where should files go?)
- Understanding project organization
- Finding where specific logic lives
- Following existing conventions
</guidelines>

View File

@@ -0,0 +1,480 @@
# Testing Patterns Template
Template for `.planning/codebase/TESTING.md` - captures test framework and patterns.
**Purpose:** Document how tests are written and run. Guide for adding tests that match existing patterns.
---
## File Template
```markdown
# Testing Patterns
**Analysis Date:** [YYYY-MM-DD]
## Test Framework
**Runner:**
- [Framework: e.g., "Jest 29.x", "Vitest 1.x"]
- [Config: e.g., "jest.config.js in project root"]
**Assertion Library:**
- [Library: e.g., "built-in expect", "chai"]
- [Matchers: e.g., "toBe, toEqual, toThrow"]
**Run Commands:**
```bash
[e.g., "npm test" or "npm run test"] # Run all tests
[e.g., "npm test -- --watch"] # Watch mode
[e.g., "npm test -- path/to/file.test.ts"] # Single file
[e.g., "npm run test:coverage"] # Coverage report
```
## Test File Organization
**Location:**
- [Pattern: e.g., "*.test.ts alongside source files"]
- [Alternative: e.g., "__tests__/ directory" or "separate tests/ tree"]
**Naming:**
- [Unit tests: e.g., "module-name.test.ts"]
- [Integration: e.g., "feature-name.integration.test.ts"]
- [E2E: e.g., "user-flow.e2e.test.ts"]
**Structure:**
```
[Show actual directory pattern, e.g.:
src/
lib/
utils.ts
utils.test.ts
services/
user-service.ts
user-service.test.ts
]
```
## Test Structure
**Suite Organization:**
```typescript
[Show actual pattern used, e.g.:
describe('ModuleName', () => {
describe('functionName', () => {
it('should handle success case', () => {
// arrange
// act
// assert
});
it('should handle error case', () => {
// test code
});
});
});
]
```
**Patterns:**
- [Setup: e.g., "beforeEach for shared setup, avoid beforeAll"]
- [Teardown: e.g., "afterEach to clean up, restore mocks"]
- [Structure: e.g., "arrange/act/assert pattern required"]
## Mocking
**Framework:**
- [Tool: e.g., "Jest built-in mocking", "Vitest vi", "Sinon"]
- [Import mocking: e.g., "vi.mock() at top of file"]
**Patterns:**
```typescript
[Show actual mocking pattern, e.g.:
// Mock external dependency
vi.mock('./external-service', () => ({
fetchData: vi.fn()
}));
// Mock in test
const mockFetch = vi.mocked(fetchData);
mockFetch.mockResolvedValue({ data: 'test' });
]
```
**What to Mock:**
- [e.g., "External APIs, file system, database"]
- [e.g., "Time/dates (use vi.useFakeTimers)"]
- [e.g., "Network calls (use mock fetch)"]
**What NOT to Mock:**
- [e.g., "Pure functions, utilities"]
- [e.g., "Internal business logic"]
## Fixtures and Factories
**Test Data:**
```typescript
[Show pattern for creating test data, e.g.:
// Factory pattern
function createTestUser(overrides?: Partial<User>): User {
return {
id: 'test-id',
name: 'Test User',
email: 'test@example.com',
...overrides
};
}
// Fixture file
// tests/fixtures/users.ts
export const mockUsers = [/* ... */];
]
```
**Location:**
- [e.g., "tests/fixtures/ for shared fixtures"]
- [e.g., "factory functions in test file or tests/factories/"]
## Coverage
**Requirements:**
- [Target: e.g., "80% line coverage", "no specific target"]
- [Enforcement: e.g., "CI blocks <80%", "coverage for awareness only"]
**Configuration:**
- [Tool: e.g., "built-in coverage via --coverage flag"]
- [Exclusions: e.g., "exclude *.test.ts, config files"]
**View Coverage:**
```bash
[e.g., "npm run test:coverage"]
[e.g., "open coverage/index.html"]
```
## Test Types
**Unit Tests:**
- [Scope: e.g., "test single function/class in isolation"]
- [Mocking: e.g., "mock all external dependencies"]
- [Speed: e.g., "must run in <1s per test"]
**Integration Tests:**
- [Scope: e.g., "test multiple modules together"]
- [Mocking: e.g., "mock external services, use real internal modules"]
- [Setup: e.g., "use test database, seed data"]
**E2E Tests:**
- [Framework: e.g., "Playwright for E2E"]
- [Scope: e.g., "test full user flows"]
- [Location: e.g., "e2e/ directory separate from unit tests"]
## Common Patterns
**Async Testing:**
```typescript
[Show pattern, e.g.:
it('should handle async operation', async () => {
const result = await asyncFunction();
expect(result).toBe('expected');
});
]
```
**Error Testing:**
```typescript
[Show pattern, e.g.:
it('should throw on invalid input', () => {
expect(() => functionCall()).toThrow('error message');
});
// Async error
it('should reject on failure', async () => {
await expect(asyncCall()).rejects.toThrow('error message');
});
]
```
**Snapshot Testing:**
- [Usage: e.g., "for React components only" or "not used"]
- [Location: e.g., "__snapshots__/ directory"]
---
*Testing analysis: [date]*
*Update when test patterns change*
```
<good_examples>
```markdown
# Testing Patterns
**Analysis Date:** 2025-01-20
## Test Framework
**Runner:**
- Vitest 1.0.4
- Config: vitest.config.ts in project root
**Assertion Library:**
- Vitest built-in expect
- Matchers: toBe, toEqual, toThrow, toMatchObject
**Run Commands:**
```bash
npm test # Run all tests
npm test -- --watch # Watch mode
npm test -- path/to/file.test.ts # Single file
npm run test:coverage # Coverage report
```
## Test File Organization
**Location:**
- *.test.ts alongside source files
- No separate tests/ directory
**Naming:**
- unit-name.test.ts for all tests
- No distinction between unit/integration in filename
**Structure:**
```
src/
lib/
parser.ts
parser.test.ts
services/
install-service.ts
install-service.test.ts
bin/
install.ts
(no test - integration tested via CLI)
```
## Test Structure
**Suite Organization:**
```typescript
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
describe('ModuleName', () => {
describe('functionName', () => {
beforeEach(() => {
// reset state
});
it('should handle valid input', () => {
// arrange
const input = createTestInput();
// act
const result = functionName(input);
// assert
expect(result).toEqual(expectedOutput);
});
it('should throw on invalid input', () => {
expect(() => functionName(null)).toThrow('Invalid input');
});
});
});
```
**Patterns:**
- Use beforeEach for per-test setup, avoid beforeAll
- Use afterEach to restore mocks: vi.restoreAllMocks()
- Explicit arrange/act/assert comments in complex tests
- One assertion focus per test (but multiple expects OK)
## Mocking
**Framework:**
- Vitest built-in mocking (vi)
- Module mocking via vi.mock() at top of test file
**Patterns:**
```typescript
import { vi } from 'vitest';
import { externalFunction } from './external';
// Mock module
vi.mock('./external', () => ({
externalFunction: vi.fn()
}));
describe('test suite', () => {
it('mocks function', () => {
const mockFn = vi.mocked(externalFunction);
mockFn.mockReturnValue('mocked result');
// test code using mocked function
expect(mockFn).toHaveBeenCalledWith('expected arg');
});
});
```
**What to Mock:**
- File system operations (fs-extra)
- Child process execution (child_process.exec)
- External API calls
- Environment variables (process.env)
**What NOT to Mock:**
- Internal pure functions
- Simple utilities (string manipulation, array helpers)
- TypeScript types
## Fixtures and Factories
**Test Data:**
```typescript
// Factory functions in test file
function createTestConfig(overrides?: Partial<Config>): Config {
return {
targetDir: '/tmp/test',
global: false,
...overrides
};
}
// Shared fixtures in tests/fixtures/
// tests/fixtures/sample-command.md
export const sampleCommand = `---
description: Test command
---
Content here`;
```
**Location:**
- Factory functions: define in test file near usage
- Shared fixtures: tests/fixtures/ (for multi-file test data)
- Mock data: inline in test when simple, factory when complex
## Coverage
**Requirements:**
- No enforced coverage target
- Coverage tracked for awareness
- Focus on critical paths (parsers, service logic)
**Configuration:**
- Vitest coverage via c8 (built-in)
- Excludes: *.test.ts, bin/install.ts, config files
**View Coverage:**
```bash
npm run test:coverage
open coverage/index.html
```
## Test Types
**Unit Tests:**
- Test single function in isolation
- Mock all external dependencies (fs, child_process)
- Fast: each test <100ms
- Examples: parser.test.ts, validator.test.ts
**Integration Tests:**
- Test multiple modules together
- Mock only external boundaries (file system, process)
- Examples: install-service.test.ts (tests service + parser)
**E2E Tests:**
- Not currently used
- CLI integration tested manually
## Common Patterns
**Async Testing:**
```typescript
it('should handle async operation', async () => {
const result = await asyncFunction();
expect(result).toBe('expected');
});
```
**Error Testing:**
```typescript
it('should throw on invalid input', () => {
expect(() => parse(null)).toThrow('Cannot parse null');
});
// Async error
it('should reject on file not found', async () => {
await expect(readConfig('invalid.txt')).rejects.toThrow('ENOENT');
});
```
**File System Mocking:**
```typescript
import { vi } from 'vitest';
import * as fs from 'fs-extra';
vi.mock('fs-extra');
it('mocks file system', () => {
vi.mocked(fs.readFile).mockResolvedValue('file content');
// test code
});
```
**Snapshot Testing:**
- Not used in this codebase
- Prefer explicit assertions for clarity
---
*Testing analysis: 2025-01-20*
*Update when test patterns change*
```
</good_examples>
<guidelines>
**What belongs in TESTING.md:**
- Test framework and runner configuration
- Test file location and naming patterns
- Test structure (describe/it, beforeEach patterns)
- Mocking approach and examples
- Fixture/factory patterns
- Coverage requirements
- How to run tests (commands)
- Common testing patterns in actual code
**What does NOT belong here:**
- Specific test cases (defer to actual test files)
- Technology choices (that's STACK.md)
- CI/CD setup (that's deployment docs)
**When filling this template:**
- Check package.json scripts for test commands
- Find test config file (jest.config.js, vitest.config.ts)
- Read 3-5 existing test files to identify patterns
- Look for test utilities in tests/ or test-utils/
- Check for coverage configuration
- Document actual patterns used, not ideal patterns
**Useful for phase planning when:**
- Adding new features (write matching tests)
- Refactoring (maintain test patterns)
- Fixing bugs (add regression tests)
- Understanding verification approach
- Setting up test infrastructure
**Analysis approach:**
- Check package.json for test framework and scripts
- Read test config file for coverage, setup
- Examine test file organization (collocated vs separate)
- Review 5 test files for patterns (mocking, structure, assertions)
- Look for test utilities, fixtures, factories
- Note any test types (unit, integration, e2e)
- Document commands for running tests
</guidelines>