ragarciaruben 1.20.7
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/.github/copilot-context/README.md +313 -0
- package/.github/copilot-context/agents/executor.agent.md +59 -0
- package/.github/copilot-context/agents/planner.agent.md +58 -0
- package/.github/copilot-context/agents/verifier.agent.md +68 -0
- package/.github/copilot-context/hooks/hooks.json +11 -0
- package/.github/copilot-context/hooks/inject-context.js +107 -0
- package/.github/copilot-context/instructions/architecture.instructions.md +33 -0
- package/.github/copilot-context/instructions/concerns.instructions.md +30 -0
- package/.github/copilot-context/instructions/conventions.instructions.md +25 -0
- package/.github/copilot-context/instructions/integrations.instructions.md +30 -0
- package/.github/copilot-context/instructions/stack.instructions.md +30 -0
- package/.github/copilot-context/instructions/structure.instructions.md +32 -0
- package/.github/copilot-context/instructions/testing.instructions.md +25 -0
- package/.github/copilot-context/prompts/execute-phase.prompt.md +148 -0
- package/.github/copilot-context/prompts/map-codebase.prompt.md +115 -0
- package/.github/copilot-context/prompts/new-project.prompt.md +85 -0
- package/.github/copilot-context/prompts/pause-work.prompt.md +104 -0
- package/.github/copilot-context/prompts/plan-phase.prompt.md +137 -0
- package/.github/copilot-context/prompts/progress.prompt.md +69 -0
- package/.github/copilot-context/prompts/resume-work.prompt.md +74 -0
- package/.github/copilot-context/prompts/sync-instructions.prompt.md +86 -0
- package/.github/copilot-context/prompts/verify-work.prompt.md +126 -0
- package/.github/copilot-context/skills/map-codebase/SKILL.md +49 -0
- package/.github/copilot-context/skills/project-history/SKILL.md +46 -0
- package/.github/copilot-instructions.md +68 -0
- package/.planning/PROJECT.md +61 -0
- package/.planning/REQUIREMENTS.md +70 -0
- package/.planning/ROADMAP.md +75 -0
- package/.planning/STATE.md +75 -0
- package/.planning/codebase/ARCHITECTURE.md +76 -0
- package/.planning/codebase/CONCERNS.md +102 -0
- package/.planning/codebase/CONVENTIONS.md +119 -0
- package/.planning/codebase/INTEGRATIONS.md +114 -0
- package/.planning/codebase/STACK.md +78 -0
- package/.planning/codebase/STRUCTURE.md +75 -0
- package/.planning/codebase/TESTING.md +157 -0
- package/.planning/continue-here.md +44 -0
- package/.vscode/settings.json +16 -0
- package/LICENSE +21 -0
- package/README.md +704 -0
- package/agents/gsd-codebase-mapper.md +764 -0
- package/agents/gsd-debugger.md +1246 -0
- package/agents/gsd-executor.md +469 -0
- package/agents/gsd-integration-checker.md +443 -0
- package/agents/gsd-phase-researcher.md +546 -0
- package/agents/gsd-plan-checker.md +690 -0
- package/agents/gsd-planner.md +1275 -0
- package/agents/gsd-project-researcher.md +621 -0
- package/agents/gsd-research-synthesizer.md +239 -0
- package/agents/gsd-roadmapper.md +642 -0
- package/agents/gsd-verifier.md +573 -0
- package/bin/install.js +2091 -0
- package/bin/setup-copilot-context.js +180 -0
- package/commands/gsd/add-phase.md +43 -0
- package/commands/gsd/add-tests.md +41 -0
- package/commands/gsd/add-todo.md +47 -0
- package/commands/gsd/audit-milestone.md +36 -0
- package/commands/gsd/check-todos.md +45 -0
- package/commands/gsd/cleanup.md +18 -0
- package/commands/gsd/complete-milestone.md +136 -0
- package/commands/gsd/debug.md +167 -0
- package/commands/gsd/discuss-phase.md +83 -0
- package/commands/gsd/execute-phase.md +41 -0
- package/commands/gsd/health.md +22 -0
- package/commands/gsd/help.md +22 -0
- package/commands/gsd/insert-phase.md +32 -0
- package/commands/gsd/join-discord.md +18 -0
- package/commands/gsd/list-phase-assumptions.md +46 -0
- package/commands/gsd/map-codebase.md +71 -0
- package/commands/gsd/new-milestone.md +44 -0
- package/commands/gsd/new-project.md +42 -0
- package/commands/gsd/new-project.md.bak +1041 -0
- package/commands/gsd/pause-work.md +38 -0
- package/commands/gsd/plan-milestone-gaps.md +34 -0
- package/commands/gsd/plan-phase.md +45 -0
- package/commands/gsd/progress.md +24 -0
- package/commands/gsd/quick.md +41 -0
- package/commands/gsd/reapply-patches.md +110 -0
- package/commands/gsd/remove-phase.md +31 -0
- package/commands/gsd/research-phase.md +189 -0
- package/commands/gsd/resume-work.md +40 -0
- package/commands/gsd/set-profile.md +34 -0
- package/commands/gsd/settings.md +36 -0
- package/commands/gsd/update.md +37 -0
- package/commands/gsd/verify-work.md +38 -0
- package/get-shit-done/bin/gsd-tools.cjs +585 -0
- package/get-shit-done/bin/lib/commands.cjs +553 -0
- package/get-shit-done/bin/lib/config.cjs +162 -0
- package/get-shit-done/bin/lib/core.cjs +411 -0
- package/get-shit-done/bin/lib/frontmatter.cjs +299 -0
- package/get-shit-done/bin/lib/init.cjs +710 -0
- package/get-shit-done/bin/lib/milestone.cjs +215 -0
- package/get-shit-done/bin/lib/phase.cjs +870 -0
- package/get-shit-done/bin/lib/roadmap.cjs +298 -0
- package/get-shit-done/bin/lib/state.cjs +521 -0
- package/get-shit-done/bin/lib/template.cjs +222 -0
- package/get-shit-done/bin/lib/verify.cjs +772 -0
- package/get-shit-done/references/checkpoints.md +776 -0
- package/get-shit-done/references/continuation-format.md +249 -0
- package/get-shit-done/references/decimal-phase-calculation.md +65 -0
- package/get-shit-done/references/git-integration.md +248 -0
- package/get-shit-done/references/git-planning-commit.md +38 -0
- package/get-shit-done/references/model-profile-resolution.md +34 -0
- package/get-shit-done/references/model-profiles.md +92 -0
- package/get-shit-done/references/phase-argument-parsing.md +61 -0
- package/get-shit-done/references/planning-config.md +196 -0
- package/get-shit-done/references/questioning.md +145 -0
- package/get-shit-done/references/tdd.md +263 -0
- package/get-shit-done/references/ui-brand.md +160 -0
- package/get-shit-done/references/verification-patterns.md +612 -0
- package/get-shit-done/templates/DEBUG.md +164 -0
- package/get-shit-done/templates/UAT.md +247 -0
- package/get-shit-done/templates/VALIDATION.md +76 -0
- package/get-shit-done/templates/codebase/architecture.md +255 -0
- package/get-shit-done/templates/codebase/concerns.md +310 -0
- package/get-shit-done/templates/codebase/conventions.md +307 -0
- package/get-shit-done/templates/codebase/integrations.md +280 -0
- package/get-shit-done/templates/codebase/stack.md +186 -0
- package/get-shit-done/templates/codebase/structure.md +285 -0
- package/get-shit-done/templates/codebase/testing.md +480 -0
- package/get-shit-done/templates/config.json +37 -0
- package/get-shit-done/templates/context.md +283 -0
- package/get-shit-done/templates/continue-here.md +78 -0
- package/get-shit-done/templates/debug-subagent-prompt.md +91 -0
- package/get-shit-done/templates/discovery.md +146 -0
- package/get-shit-done/templates/milestone-archive.md +123 -0
- package/get-shit-done/templates/milestone.md +115 -0
- package/get-shit-done/templates/phase-prompt.md +569 -0
- package/get-shit-done/templates/planner-subagent-prompt.md +117 -0
- package/get-shit-done/templates/project.md +184 -0
- package/get-shit-done/templates/requirements.md +231 -0
- package/get-shit-done/templates/research-project/ARCHITECTURE.md +204 -0
- package/get-shit-done/templates/research-project/FEATURES.md +147 -0
- package/get-shit-done/templates/research-project/PITFALLS.md +200 -0
- package/get-shit-done/templates/research-project/STACK.md +120 -0
- package/get-shit-done/templates/research-project/SUMMARY.md +170 -0
- package/get-shit-done/templates/research.md +552 -0
- package/get-shit-done/templates/retrospective.md +54 -0
- package/get-shit-done/templates/roadmap.md +202 -0
- package/get-shit-done/templates/state.md +176 -0
- package/get-shit-done/templates/summary-complex.md +59 -0
- package/get-shit-done/templates/summary-minimal.md +41 -0
- package/get-shit-done/templates/summary-standard.md +48 -0
- package/get-shit-done/templates/summary.md +248 -0
- package/get-shit-done/templates/user-setup.md +311 -0
- package/get-shit-done/templates/verification-report.md +322 -0
- package/get-shit-done/workflows/add-phase.md +111 -0
- package/get-shit-done/workflows/add-tests.md +350 -0
- package/get-shit-done/workflows/add-todo.md +157 -0
- package/get-shit-done/workflows/audit-milestone.md +297 -0
- package/get-shit-done/workflows/check-todos.md +176 -0
- package/get-shit-done/workflows/cleanup.md +152 -0
- package/get-shit-done/workflows/complete-milestone.md +763 -0
- package/get-shit-done/workflows/diagnose-issues.md +219 -0
- package/get-shit-done/workflows/discovery-phase.md +289 -0
- package/get-shit-done/workflows/discuss-phase.md +542 -0
- package/get-shit-done/workflows/execute-phase.md +449 -0
- package/get-shit-done/workflows/execute-plan.md +448 -0
- package/get-shit-done/workflows/health.md +156 -0
- package/get-shit-done/workflows/help.md +489 -0
- package/get-shit-done/workflows/insert-phase.md +129 -0
- package/get-shit-done/workflows/list-phase-assumptions.md +178 -0
- package/get-shit-done/workflows/map-codebase.md +315 -0
- package/get-shit-done/workflows/new-milestone.md +382 -0
- package/get-shit-done/workflows/new-project.md +1116 -0
- package/get-shit-done/workflows/pause-work.md +122 -0
- package/get-shit-done/workflows/plan-milestone-gaps.md +274 -0
- package/get-shit-done/workflows/plan-phase.md +569 -0
- package/get-shit-done/workflows/progress.md +381 -0
- package/get-shit-done/workflows/quick.md +453 -0
- package/get-shit-done/workflows/remove-phase.md +154 -0
- package/get-shit-done/workflows/research-phase.md +73 -0
- package/get-shit-done/workflows/resume-project.md +306 -0
- package/get-shit-done/workflows/set-profile.md +80 -0
- package/get-shit-done/workflows/settings.md +213 -0
- package/get-shit-done/workflows/transition.md +544 -0
- package/get-shit-done/workflows/update.md +219 -0
- package/get-shit-done/workflows/verify-phase.md +242 -0
- package/get-shit-done/workflows/verify-work.md +569 -0
- package/hooks/dist/gsd-check-update.js +62 -0
- package/hooks/dist/gsd-context-monitor.js +122 -0
- package/hooks/dist/gsd-statusline.js +108 -0
- package/package.json +54 -0
- package/scripts/build-hooks.js +43 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Technology Stack
|
|
2
|
+
|
|
3
|
+
<!-- Generated by /map-codebase. Describes the full technology foundation.
|
|
4
|
+
Consumed by: plan-phase (setup/config/integration work), execute-phase (dependency decisions). -->
|
|
5
|
+
|
|
6
|
+
## Runtime
|
|
7
|
+
|
|
8
|
+
| Layer | Technology | Version | Notes |
|
|
9
|
+
|-------|-----------|---------|-------|
|
|
10
|
+
| Language | [e.g., TypeScript] | [X.X] | [any notes] |
|
|
11
|
+
| Runtime | [e.g., Node.js] | [X.X] | [any notes] |
|
|
12
|
+
| Package manager | [e.g., pnpm] | [X.X] | [any notes] |
|
|
13
|
+
|
|
14
|
+
## Framework
|
|
15
|
+
|
|
16
|
+
| Purpose | Library | Version | Role |
|
|
17
|
+
|---------|---------|---------|------|
|
|
18
|
+
| [Web framework] | [e.g., Express / Fastify / Next.js] | [X.X] | [What it does] |
|
|
19
|
+
| [ORM / DB client] | [e.g., Prisma / Drizzle] | [X.X] | [What it does] |
|
|
20
|
+
| [Auth] | [e.g., Passport.js / NextAuth] | [X.X] | [What it does] |
|
|
21
|
+
|
|
22
|
+
## Key Dependencies
|
|
23
|
+
|
|
24
|
+
| Package | Version | Purpose |
|
|
25
|
+
|---------|---------|---------|
|
|
26
|
+
| `[package-name]` | `^X.X` | [Why it exists] |
|
|
27
|
+
| `[package-name]` | `^X.X` | [Why it exists] |
|
|
28
|
+
| `[package-name]` | `^X.X` | [Why it exists] |
|
|
29
|
+
|
|
30
|
+
## Dev Toolchain
|
|
31
|
+
|
|
32
|
+
| Tool | Config File | Purpose |
|
|
33
|
+
|------|------------|---------|
|
|
34
|
+
| [TypeScript] | `tsconfig.json` | Compilation |
|
|
35
|
+
| [ESLint] | `.eslintrc.js` | Linting |
|
|
36
|
+
| [Prettier] | `.prettierrc` | Formatting |
|
|
37
|
+
| [Vitest / Jest] | `vitest.config.ts` | Testing |
|
|
38
|
+
| [Build tool] | `[config file]` | Bundle/compile |
|
|
39
|
+
|
|
40
|
+
## Infrastructure
|
|
41
|
+
|
|
42
|
+
| Layer | Technology | How configured |
|
|
43
|
+
|-------|-----------|----------------|
|
|
44
|
+
| Database | [e.g., PostgreSQL 15] | [e.g., Docker locally, RDS in prod] |
|
|
45
|
+
| Cache | [e.g., Redis 7] | [e.g., ElastiCache in prod] |
|
|
46
|
+
| Object storage | [e.g., S3] | [e.g., via AWS SDK v3] |
|
|
47
|
+
| Message queue | [e.g., SQS / RabbitMQ] | [e.g., via @aws-sdk/client-sqs] |
|
|
48
|
+
| Deployment | [e.g., AWS ECS / Vercel / K8s] | [How deployed] |
|
|
49
|
+
|
|
50
|
+
## Environment Variables
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Application
|
|
54
|
+
APP_PORT=3000
|
|
55
|
+
NODE_ENV=development
|
|
56
|
+
|
|
57
|
+
# Database
|
|
58
|
+
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
|
|
59
|
+
|
|
60
|
+
# [Auth provider]
|
|
61
|
+
AUTH_SECRET=
|
|
62
|
+
AUTH_PROVIDER_CLIENT_ID=
|
|
63
|
+
AUTH_PROVIDER_CLIENT_SECRET=
|
|
64
|
+
|
|
65
|
+
# [External API]
|
|
66
|
+
STRIPE_SECRET_KEY=
|
|
67
|
+
STRIPE_WEBHOOK_SECRET=
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
*Actual secrets in `.env` (gitignored). Example in `.env.example`.*
|
|
71
|
+
|
|
72
|
+
## Version Constraints
|
|
73
|
+
|
|
74
|
+
[Any locked versions, peer dependency requirements, or compatibility notes that affect future dependency changes]
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
*Generated: [date]*
|
|
78
|
+
*Last updated: [date] after [trigger]*
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# File Structure
|
|
2
|
+
|
|
3
|
+
<!-- Generated by /map-codebase. Describes physical organization of the codebase.
|
|
4
|
+
Primary purpose: answer "where do I put new code?"
|
|
5
|
+
Consumed by: plan-phase (any), execute-phase (when creating new files). -->
|
|
6
|
+
|
|
7
|
+
## Root Layout
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
/
|
|
11
|
+
├── src/ [Main application source]
|
|
12
|
+
├── tests/ [Test files]
|
|
13
|
+
├── docs/ [Documentation]
|
|
14
|
+
├── scripts/ [Build/deploy scripts]
|
|
15
|
+
├── .github/ [Copilot context + CI/CD]
|
|
16
|
+
├── .planning/ [Project context documents]
|
|
17
|
+
├── package.json [Node.js manifest / replace with appropriate manifest]
|
|
18
|
+
└── [config files] [tsconfig.json, .eslintrc, etc.]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Source Tree
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
src/
|
|
25
|
+
├── [describe your actual structure here]
|
|
26
|
+
│ ├── [subdirectory] [What goes here]
|
|
27
|
+
│ └── [subdirectory] [What goes here]
|
|
28
|
+
├── [module/] [Description]
|
|
29
|
+
└── [module/] [Description]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Where To Put New Code
|
|
33
|
+
|
|
34
|
+
<!-- This section is the primary value of this document. Be prescriptive. -->
|
|
35
|
+
|
|
36
|
+
| I'm adding... | It goes in... | Naming convention |
|
|
37
|
+
|---------------|---------------|-------------------|
|
|
38
|
+
| A new API endpoint | `src/routes/[resource].route.ts` | `[resource].route.ts` (kebab-case) |
|
|
39
|
+
| Business logic | `src/services/[resource].service.ts` | `[resource].service.ts` |
|
|
40
|
+
| Database queries | `src/repositories/[resource].repository.ts` | `[resource].repository.ts` |
|
|
41
|
+
| A new data model | `src/models/[Resource].model.ts` | `[Resource].model.ts` (PascalCase) |
|
|
42
|
+
| Reusable utility | `src/utils/[descriptive-name].ts` | `[name].ts` (kebab-case) |
|
|
43
|
+
| Shared types/interfaces | `src/types/[domain].types.ts` | `[domain].types.ts` |
|
|
44
|
+
| Middleware | `src/middleware/[name].middleware.ts` | `[name].middleware.ts` |
|
|
45
|
+
| Configuration | `src/config/[name].config.ts` | `[name].config.ts` |
|
|
46
|
+
| A unit test | `tests/unit/[mirrors-src-path].test.ts` | Mirror src path |
|
|
47
|
+
| An integration test | `tests/integration/[feature].test.ts` | Feature-scoped |
|
|
48
|
+
| A new React component | `src/components/[Name]/[Name].tsx` | PascalCase directory + file |
|
|
49
|
+
| A new page | `src/pages/[name]/page.tsx` | kebab-case directory |
|
|
50
|
+
|
|
51
|
+
## File Naming Rules
|
|
52
|
+
|
|
53
|
+
- **Components:** `PascalCase.tsx` (e.g., `UserCard.tsx`)
|
|
54
|
+
- **Utilities/Services/Routes:** `kebab-case.ts` (e.g., `user-service.ts` or `user.service.ts`)
|
|
55
|
+
- **Constants:** `SCREAMING_SNAKE_CASE.ts` (e.g., `API_CONSTANTS.ts`)
|
|
56
|
+
- **Types/Interfaces:** exported with `I` prefix or `Type` suffix — [specify your convention]
|
|
57
|
+
- **Test files:** mirror source path with `.test.ts` or `.spec.ts` suffix
|
|
58
|
+
|
|
59
|
+
## Colocation Patterns
|
|
60
|
+
|
|
61
|
+
[Describe any patterns for co-locating related files, e.g., feature folders, barrel files, index.ts patterns]
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
Example — feature folder pattern:
|
|
65
|
+
src/features/auth/
|
|
66
|
+
├── auth.route.ts
|
|
67
|
+
├── auth.service.ts
|
|
68
|
+
├── auth.controller.ts
|
|
69
|
+
├── auth.types.ts
|
|
70
|
+
└── index.ts ← barrel export
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
*Generated: [date]*
|
|
75
|
+
*Last updated: [date] after [trigger]*
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Testing Patterns
|
|
2
|
+
|
|
3
|
+
<!-- Generated by /map-codebase. Describes test framework, patterns, and organization.
|
|
4
|
+
Consumed by: execute-phase (all work), plan-phase (testing phases).
|
|
5
|
+
Auto-loaded by Copilot when editing *.test.* or *.spec.* files. -->
|
|
6
|
+
|
|
7
|
+
## Test Framework
|
|
8
|
+
|
|
9
|
+
- **Runner:** [Vitest / Jest / Pytest / Go test]
|
|
10
|
+
- **Assertion library:** [Built-in expect / Chai]
|
|
11
|
+
- **Mocking:** [vi.mock() / jest.mock() / unittest.mock]
|
|
12
|
+
- **Coverage:** [v8 / istanbul] — threshold: [80%] lines/branches
|
|
13
|
+
- **Snapshot testing:** [Used / Not used]
|
|
14
|
+
|
|
15
|
+
## Running Tests
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# All tests
|
|
19
|
+
npm test
|
|
20
|
+
|
|
21
|
+
# Watch mode
|
|
22
|
+
npm run test:watch
|
|
23
|
+
|
|
24
|
+
# Coverage report
|
|
25
|
+
npm run test:coverage
|
|
26
|
+
|
|
27
|
+
# Specific file
|
|
28
|
+
npx vitest run src/services/user.service.test.ts
|
|
29
|
+
|
|
30
|
+
# Pattern match
|
|
31
|
+
npx vitest run --grep "UserService"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Test File Organization
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
tests/
|
|
38
|
+
├── unit/ # Pure unit tests (no I/O)
|
|
39
|
+
│ ├── services/ # Service layer tests
|
|
40
|
+
│ ├── utils/ # Utility function tests
|
|
41
|
+
│ └── models/ # Model/schema validation tests
|
|
42
|
+
├── integration/ # Tests with real DB / HTTP
|
|
43
|
+
│ ├── routes/ # API endpoint tests
|
|
44
|
+
│ └── repositories/ # Database query tests
|
|
45
|
+
├── e2e/ # End-to-end tests
|
|
46
|
+
│ └── flows/ # User journey tests
|
|
47
|
+
└── helpers/
|
|
48
|
+
├── factories.ts # Test data factories
|
|
49
|
+
├── setup.ts # Global test setup
|
|
50
|
+
└── mocks/ # Shared mock implementations
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
*Alternative: Test files co-located with source (`*.test.ts` next to `*.ts`). [Specify which pattern you use.]*
|
|
54
|
+
|
|
55
|
+
## Test Structure Pattern
|
|
56
|
+
|
|
57
|
+
Follow the **Arrange-Act-Assert** pattern with `describe`/`it` blocks:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
describe('UserService', () => {
|
|
61
|
+
describe('createUser()', () => {
|
|
62
|
+
it('creates a user with hashed password', async () => {
|
|
63
|
+
// Arrange
|
|
64
|
+
const dto = { email: 'test@example.com', password: 'plaintext' };
|
|
65
|
+
const mockRepo = createMockUserRepository();
|
|
66
|
+
|
|
67
|
+
// Act
|
|
68
|
+
const result = await new UserService(mockRepo).createUser(dto);
|
|
69
|
+
|
|
70
|
+
// Assert
|
|
71
|
+
expect(result.email).toBe('test@example.com');
|
|
72
|
+
expect(result.password).not.toBe('plaintext');
|
|
73
|
+
expect(mockRepo.save).toHaveBeenCalledOnce();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('throws ValidationError when email already exists', async () => {
|
|
77
|
+
// Arrange
|
|
78
|
+
const mockRepo = createMockUserRepository({ emailExists: true });
|
|
79
|
+
|
|
80
|
+
// Act & Assert
|
|
81
|
+
await expect(
|
|
82
|
+
new UserService(mockRepo).createUser({ email: 'taken@test.com', password: 'pw' })
|
|
83
|
+
).rejects.toThrow(ValidationError);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Mocking Strategy
|
|
90
|
+
|
|
91
|
+
- **Services:** mock at repository layer — don't mock the service being tested
|
|
92
|
+
- **External HTTP:** use [msw / nock] to intercept at network level
|
|
93
|
+
- **Database:** [test database with transactions rolled back / in-memory DB / repository mocks]
|
|
94
|
+
- **Environment variables:** set in `vitest.config.ts` under `env`; never `process.env` mutations in tests
|
|
95
|
+
- **Time:** use `vi.useFakeTimers()` for time-dependent tests
|
|
96
|
+
|
|
97
|
+
## Test Data
|
|
98
|
+
|
|
99
|
+
Use factory functions, not hardcoded objects:
|
|
100
|
+
```typescript
|
|
101
|
+
// tests/helpers/factories.ts
|
|
102
|
+
export function createUser(overrides: Partial<User> = {}): User {
|
|
103
|
+
return {
|
|
104
|
+
id: 'usr_test_123',
|
|
105
|
+
email: 'test@example.com',
|
|
106
|
+
name: 'Test User',
|
|
107
|
+
createdAt: new Date('2024-01-01'),
|
|
108
|
+
...overrides, // caller overrides specific fields for the test case
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Integration Test Pattern
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
describe('POST /api/users', () => {
|
|
117
|
+
let app: Express;
|
|
118
|
+
let db: TestDatabase;
|
|
119
|
+
|
|
120
|
+
beforeAll(async () => {
|
|
121
|
+
db = await createTestDatabase();
|
|
122
|
+
app = createApp(db);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
afterEach(async () => {
|
|
126
|
+
await db.rollback(); // clean state between tests
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
afterAll(async () => {
|
|
130
|
+
await db.close();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('returns 201 with created user', async () => {
|
|
134
|
+
const response = await request(app)
|
|
135
|
+
.post('/api/users')
|
|
136
|
+
.send({ email: 'new@test.com', password: 'password123' })
|
|
137
|
+
.set('Content-Type', 'application/json');
|
|
138
|
+
|
|
139
|
+
expect(response.status).toBe(201);
|
|
140
|
+
expect(response.body).toMatchObject({ email: 'new@test.com' });
|
|
141
|
+
expect(response.body.password).toBeUndefined(); // never expose password
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## What To Test
|
|
147
|
+
|
|
148
|
+
- ✅ Business logic in services (unit tests with mocked deps)
|
|
149
|
+
- ✅ API contract (integration tests: status codes, response shape, error cases)
|
|
150
|
+
- ✅ Edge cases: empty inputs, null values, boundary conditions
|
|
151
|
+
- ✅ Error paths: what happens when dependencies fail
|
|
152
|
+
- ❌ Don't test framework internals (ORM queries, Express routing)
|
|
153
|
+
- ❌ Don't test private/internal implementation details
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
*Generated: [date]*
|
|
157
|
+
*Last updated: [date] after [trigger]*
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Continue Here
|
|
2
|
+
|
|
3
|
+
<!-- Generated at session pause. Gives the next session full context to resume immediately.
|
|
4
|
+
Reference: .planning/STATE.md for project-wide position. -->
|
|
5
|
+
|
|
6
|
+
## Where We Are
|
|
7
|
+
|
|
8
|
+
**Phase:** [X] — [Phase Name]
|
|
9
|
+
**Plan:** [A] of [B]
|
|
10
|
+
**As of:** [YYYY-MM-DD HH:MM]
|
|
11
|
+
|
|
12
|
+
## What Was Just Completed
|
|
13
|
+
|
|
14
|
+
[Concrete description of the last completed action — file changed, test passed, API endpoint shipped, etc.]
|
|
15
|
+
|
|
16
|
+
- ✅ [Completed item 1]
|
|
17
|
+
- ✅ [Completed item 2]
|
|
18
|
+
- ✅ [Completed item 3]
|
|
19
|
+
|
|
20
|
+
## What Remains
|
|
21
|
+
|
|
22
|
+
- [ ] [Next immediate task]
|
|
23
|
+
- [ ] [Task after that]
|
|
24
|
+
- [ ] [Remaining items in current plan]
|
|
25
|
+
|
|
26
|
+
## Decisions Made This Session
|
|
27
|
+
|
|
28
|
+
<!-- Lock these in — don't re-litigate next session -->
|
|
29
|
+
|
|
30
|
+
- [Decision 1 and its rationale]
|
|
31
|
+
- [Decision 2 and its rationale]
|
|
32
|
+
|
|
33
|
+
## Blockers / Watch-Outs
|
|
34
|
+
|
|
35
|
+
<!-- Anything the next session needs to know before touching code -->
|
|
36
|
+
|
|
37
|
+
- [Blocker or warning — e.g., "Auth middleware has a race condition in tests, skip until Phase 3"]
|
|
38
|
+
|
|
39
|
+
## Exact Next Action
|
|
40
|
+
|
|
41
|
+
**Resume by doing:** [Single clear action — e.g., "Run `npm test` to verify the auth middleware, then open `src/routes/user.ts` and implement the POST /users endpoint per plan 02-01"]
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
*Saved: [YYYY-MM-DD HH:MM]*
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Tell Copilot where to find the context engineering system files.
|
|
3
|
+
// All context files are isolated in .github/copilot-context/ — configure
|
|
4
|
+
// each feature type to look there instead of the default .github/ root.
|
|
5
|
+
|
|
6
|
+
"chat.instructionsFilesLocations": [
|
|
7
|
+
".github/copilot-context/instructions"
|
|
8
|
+
],
|
|
9
|
+
"chat.promptFilesLocations": [
|
|
10
|
+
".github/copilot-context/prompts"
|
|
11
|
+
],
|
|
12
|
+
"chat.agentFilesLocations": [
|
|
13
|
+
".github/copilot-context/agents",
|
|
14
|
+
".github/copilot-context/skills"
|
|
15
|
+
]
|
|
16
|
+
}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Lex Christopherson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|