sddx-workflow 0.6.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.md +134 -0
- package/dist/cli.js +311 -0
- package/package.json +46 -0
- package/templates/CLAUDE.md +35 -0
- package/templates/claude-commands/ask.md +5 -0
- package/templates/claude-commands/assume.md +7 -0
- package/templates/claude-commands/bootstrap.md +5 -0
- package/templates/claude-commands/bugfix.md +6 -0
- package/templates/claude-commands/finish.md +5 -0
- package/templates/claude-commands/refactor.md +6 -0
- package/templates/claude-commands/review.md +5 -0
- package/templates/claude-commands/spec-new.md +4 -0
- package/templates/claude-commands/spec-plan.md +4 -0
- package/templates/claude-commands/spec-tasks.md +5 -0
- package/templates/conventions/base.md +32 -0
- package/templates/copilot-instructions.md +33 -0
- package/templates/copilot-prompts/ask.prompt.md +10 -0
- package/templates/copilot-prompts/assume.prompt.md +12 -0
- package/templates/copilot-prompts/bootstrap.prompt.md +11 -0
- package/templates/copilot-prompts/bugfix.prompt.md +12 -0
- package/templates/copilot-prompts/finish.prompt.md +10 -0
- package/templates/copilot-prompts/refactor.prompt.md +10 -0
- package/templates/copilot-prompts/review.prompt.md +10 -0
- package/templates/copilot-prompts/spec-new.prompt.md +9 -0
- package/templates/copilot-prompts/spec-plan.prompt.md +9 -0
- package/templates/copilot-prompts/spec-tasks.prompt.md +10 -0
- package/templates/cursor-rules/sddx-workflow.mdc +27 -0
- package/templates/domains/auth.md +31 -0
- package/templates/domains/email.md +30 -0
- package/templates/domains/payments.md +32 -0
- package/templates/domains/storage.md +30 -0
- package/templates/project-overview.md +31 -0
- package/templates/specs/_template/1-requirements.md +81 -0
- package/templates/specs/_template/2-plan.md +128 -0
- package/templates/specs/_template/3-tasks.md +53 -0
- package/templates/windsurf-rules/sddx-workflow.md +26 -0
- package/templates/workflow.md +285 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Research and exploration — no code changes
|
|
3
|
+
mode: agent
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Execute the /ask command defined in .sdd/workflow.md.
|
|
7
|
+
|
|
8
|
+
Research and exploration only — do not modify any files. Read, analyze, and summarize findings with explicit options or recommendations.
|
|
9
|
+
|
|
10
|
+
Topic: ${input:topic}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Surface all assumptions before acting — stop for confirmation
|
|
3
|
+
mode: agent
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Execute the /assume command defined in .sdd/workflow.md.
|
|
7
|
+
|
|
8
|
+
List every assumption being made about the task, codebase state, and technical decisions.
|
|
9
|
+
For each: what you're assuming, why, and what changes if it's wrong.
|
|
10
|
+
Stop and wait for confirmation before proceeding.
|
|
11
|
+
|
|
12
|
+
Context: ${input:context}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Populate project context via interview or codebase scan
|
|
3
|
+
mode: agent
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Execute the /bootstrap command defined in .sdd/workflow.md.
|
|
7
|
+
|
|
8
|
+
If the project already has code, scan the codebase first (read structure, package files, schema, routes), infer what you can, then ask only about what the code cannot answer.
|
|
9
|
+
If it's a new project, ask the 6 interview questions defined in workflow.md one at a time.
|
|
10
|
+
|
|
11
|
+
Present the full draft of .sdd/project-overview.md and .sdd/conventions.md for approval before writing any file.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Reproduce → diagnose → fix → validate
|
|
3
|
+
mode: agent
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Execute the /bugfix command defined in .sdd/workflow.md.
|
|
7
|
+
|
|
8
|
+
Follow the stages in order without skipping: Reproduce → Diagnose → Fix → Validate.
|
|
9
|
+
Stop after Reproduce if the bug cannot be confirmed with a test or repro case.
|
|
10
|
+
Escalate to /spec-new if the fix scope exceeds ~1 file or ~50 lines.
|
|
11
|
+
|
|
12
|
+
Bug or error: ${input:bug}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Stage files and generate a conventional commit message
|
|
3
|
+
mode: agent
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Execute the /finish command defined in .sdd/workflow.md.
|
|
7
|
+
|
|
8
|
+
Run git status and git diff. Stage all relevant files (exclude .env*, build artifacts, scratch files). Determine the commit type. Draft a conventional commit message following the format in workflow.md — one overview sentence, detailed bullets with reasoning, optional footer for non-obvious context.
|
|
9
|
+
|
|
10
|
+
Stop and present the staged file list and commit message for approval before committing.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Restructure without changing external behavior
|
|
3
|
+
mode: agent
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Execute the /refactor command defined in .sdd/workflow.md.
|
|
7
|
+
|
|
8
|
+
Run existing tests first to establish a green baseline. Implement in small steps — tests must stay green throughout. No new features or bug fixes mixed in.
|
|
9
|
+
|
|
10
|
+
Target: ${input:target}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Final audit before closing a spec
|
|
3
|
+
mode: agent
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Execute the /review command defined in .sdd/workflow.md.
|
|
7
|
+
|
|
8
|
+
Verify: all goals (G1, G2…) satisfied, every acceptance scenario has a passing test, full test suite passes, no out-of-scope changes, no speculative code, implementation is the simplest that meets requirements.
|
|
9
|
+
|
|
10
|
+
Spec: ${input:specName}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Scaffold a spec folder for a new feature
|
|
3
|
+
mode: agent
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Execute the /spec-new command defined in .sdd/workflow.md.
|
|
7
|
+
|
|
8
|
+
Create a specs/${input:featureName}/ folder by copying the three template files from specs/_template/.
|
|
9
|
+
Replace <Feature Name> in each file title with the actual feature name.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Generate technical plan — stops for approval before any code
|
|
3
|
+
mode: agent
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Execute the /spec-plan command defined in .sdd/workflow.md.
|
|
7
|
+
|
|
8
|
+
Read specs/${input:specName}/1-requirements.md, run /assume to surface assumptions, then draft the technical plan in specs/${input:specName}/2-plan.md.
|
|
9
|
+
Stop for explicit approval before writing any implementation code.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Execute approved plan one task at a time, TDD-first
|
|
3
|
+
mode: agent
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Execute the /spec-tasks command defined in .sdd/workflow.md.
|
|
7
|
+
|
|
8
|
+
Read the approved specs/${input:specName}/2-plan.md and execute tasks one at a time.
|
|
9
|
+
Write the test first (red), implement until green, run the full suite, then move to the next task.
|
|
10
|
+
Stop immediately if tests fail or a task reveals new scope.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: SDD Protocol — read before starting any task in this project
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
This project uses the SDD Protocol. Before starting any task, read:
|
|
7
|
+
|
|
8
|
+
1. `.sdd/workflow.md` — all commands, ceremony levels, and stop points
|
|
9
|
+
2. `.sdd/project-overview.md` — what this app is, its non-goals, and domains
|
|
10
|
+
3. `.sdd/conventions.md` — project-specific conventions and patterns
|
|
11
|
+
|
|
12
|
+
## Available commands
|
|
13
|
+
|
|
14
|
+
| Command | Purpose |
|
|
15
|
+
|---|---|
|
|
16
|
+
| `/bootstrap` | Populate project context — interview or codebase scan |
|
|
17
|
+
| `/ask` | Research only — no code changes |
|
|
18
|
+
| `/assume` | List assumptions and stop for confirmation |
|
|
19
|
+
| `/bugfix` | Reproduce → diagnose → fix → validate |
|
|
20
|
+
| `/refactor` | Restructure without behavior change |
|
|
21
|
+
| `/spec-new` | Scaffold a spec folder |
|
|
22
|
+
| `/spec-plan` | Generate technical plan — stop for approval |
|
|
23
|
+
| `/spec-tasks` | Execute plan one task at a time, TDD-first |
|
|
24
|
+
| `/review` | Final audit before closing |
|
|
25
|
+
| `/finish` | Stage files and generate commit message |
|
|
26
|
+
|
|
27
|
+
Full definitions for each command are in `.sdd/workflow.md`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Domain: Auth
|
|
2
|
+
|
|
3
|
+
## Responsibility
|
|
4
|
+
|
|
5
|
+
Authentication and session management.
|
|
6
|
+
|
|
7
|
+
## Boundaries
|
|
8
|
+
|
|
9
|
+
- Owns: login, logout, session tokens, password reset flows
|
|
10
|
+
- Does NOT own: user profile data, role-based permissions (see roles domain)
|
|
11
|
+
|
|
12
|
+
## Key Concepts
|
|
13
|
+
|
|
14
|
+
- **Session**: short-lived token, validated server-side on every request
|
|
15
|
+
- **Refresh token**: long-lived, rotated on use
|
|
16
|
+
- **Auth state**: derived on the server per request — never trusted from client payload
|
|
17
|
+
|
|
18
|
+
## Critical Rules
|
|
19
|
+
|
|
20
|
+
- Never log tokens, passwords, or raw session data
|
|
21
|
+
- Validate session on the server before acting on user identity — never trust client-supplied user IDs
|
|
22
|
+
- Auth failures return generic errors to the client (no user enumeration)
|
|
23
|
+
- Password reset tokens are single-use and expire
|
|
24
|
+
|
|
25
|
+
## Files
|
|
26
|
+
|
|
27
|
+
<!-- List key files once the domain is built:
|
|
28
|
+
- lib/auth/session.ts
|
|
29
|
+
- app/_actions/auth.ts
|
|
30
|
+
- middleware.ts
|
|
31
|
+
-->
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Domain: Email / Notifications
|
|
2
|
+
|
|
3
|
+
## Responsibility
|
|
4
|
+
|
|
5
|
+
Transactional emails and in-app notifications.
|
|
6
|
+
|
|
7
|
+
## Boundaries
|
|
8
|
+
|
|
9
|
+
- Owns: email templates, notification dispatch, delivery status
|
|
10
|
+
- Does NOT own: user preferences for notification opt-in/out (see user-preferences domain)
|
|
11
|
+
|
|
12
|
+
## Key Concepts
|
|
13
|
+
|
|
14
|
+
- **Transactional email**: triggered by a user action (welcome, reset, receipt)
|
|
15
|
+
- **Delivery status**: sent → delivered → opened, tracked via provider webhooks
|
|
16
|
+
|
|
17
|
+
## Critical Rules
|
|
18
|
+
|
|
19
|
+
- Send emails via a queue — never block a request on email delivery
|
|
20
|
+
- Marketing emails must include an unsubscribe link (CAN-SPAM / GDPR)
|
|
21
|
+
- Never include sensitive data (tokens, PII) in email subject lines
|
|
22
|
+
- Delivery failures are non-fatal — log and alert, don't crash the originating flow
|
|
23
|
+
|
|
24
|
+
## Files
|
|
25
|
+
|
|
26
|
+
<!-- List key files once the domain is built:
|
|
27
|
+
- lib/email/client.ts
|
|
28
|
+
- lib/email/templates/
|
|
29
|
+
- app/_actions/notifications.ts
|
|
30
|
+
-->
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Domain: Payments
|
|
2
|
+
|
|
3
|
+
## Responsibility
|
|
4
|
+
|
|
5
|
+
Payment processing, subscriptions, and billing.
|
|
6
|
+
|
|
7
|
+
## Boundaries
|
|
8
|
+
|
|
9
|
+
- Owns: payment intents, subscriptions, invoices, provider webhooks
|
|
10
|
+
- Does NOT own: user accounts, product catalog
|
|
11
|
+
|
|
12
|
+
## Key Concepts
|
|
13
|
+
|
|
14
|
+
- **Payment Intent**: server-side object representing a charge attempt
|
|
15
|
+
- **Webhook**: provider event — must be verified with signature before processing
|
|
16
|
+
- **Idempotency key**: required on every payment mutation to prevent double-charges
|
|
17
|
+
|
|
18
|
+
## Critical Rules
|
|
19
|
+
|
|
20
|
+
- Never log card data, raw tokens, or payment provider secrets
|
|
21
|
+
- Always verify webhook signatures before processing events
|
|
22
|
+
- Include an idempotency key on every payment mutation
|
|
23
|
+
- Use server-side API keys only — never expose secret keys to the client
|
|
24
|
+
- Failed payments are events to handle, not errors to throw
|
|
25
|
+
|
|
26
|
+
## Files
|
|
27
|
+
|
|
28
|
+
<!-- List key files once the domain is built:
|
|
29
|
+
- lib/payments/stripe.ts
|
|
30
|
+
- app/api/webhooks/stripe/route.ts
|
|
31
|
+
- app/_actions/payments.ts
|
|
32
|
+
-->
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Domain: Storage
|
|
2
|
+
|
|
3
|
+
## Responsibility
|
|
4
|
+
|
|
5
|
+
File upload, storage, and retrieval.
|
|
6
|
+
|
|
7
|
+
## Boundaries
|
|
8
|
+
|
|
9
|
+
- Owns: upload flows, signed URLs, file metadata
|
|
10
|
+
- Does NOT own: access permissions (enforced via storage policies), rendering/display
|
|
11
|
+
|
|
12
|
+
## Key Concepts
|
|
13
|
+
|
|
14
|
+
- **Signed URL**: temporary, scoped URL for accessing or uploading a file
|
|
15
|
+
- **Bucket**: top-level container — one per access pattern (public vs. private)
|
|
16
|
+
- **Storage policy**: access rules applied at the storage layer — always configured
|
|
17
|
+
|
|
18
|
+
## Critical Rules
|
|
19
|
+
|
|
20
|
+
- Private files are always served via signed URLs, never direct bucket access
|
|
21
|
+
- Validate file type and size on the server, not just the client
|
|
22
|
+
- Storage policies must match the application-level permission model
|
|
23
|
+
- Scan or validate uploads before making them accessible to other users
|
|
24
|
+
|
|
25
|
+
## Files
|
|
26
|
+
|
|
27
|
+
<!-- List key files once the domain is built:
|
|
28
|
+
- lib/storage/client.ts
|
|
29
|
+
- app/_actions/upload.ts
|
|
30
|
+
-->
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Project Overview
|
|
2
|
+
|
|
3
|
+
<!-- Populated by /bootstrap. Update this file as the project evolves.
|
|
4
|
+
The AI agent reads this before starting any task. -->
|
|
5
|
+
|
|
6
|
+
## What This App Does
|
|
7
|
+
|
|
8
|
+
<!-- One paragraph: problem solved, target user, core value proposition. -->
|
|
9
|
+
|
|
10
|
+
## What It Does NOT Do
|
|
11
|
+
|
|
12
|
+
<!-- Explicit non-goals. As important as the goals — prevents scope creep
|
|
13
|
+
at the product level, not just the task level. -->
|
|
14
|
+
|
|
15
|
+
## Main Domains
|
|
16
|
+
|
|
17
|
+
<!-- The primary business domains and what each one owns.
|
|
18
|
+
Example:
|
|
19
|
+
- Auth — session management, login/logout, password reset
|
|
20
|
+
- Orders — creation, status transitions, fulfillment
|
|
21
|
+
- Inventory — stock levels, reservations, restocking -->
|
|
22
|
+
|
|
23
|
+
## Architecture Decisions
|
|
24
|
+
|
|
25
|
+
<!-- Key decisions already locked in: why this stack, why this structure,
|
|
26
|
+
constraints that must not be violated. -->
|
|
27
|
+
|
|
28
|
+
## Definition of Done
|
|
29
|
+
|
|
30
|
+
<!-- What "production ready" means for this project:
|
|
31
|
+
performance targets, security requirements, compliance, accessibility. -->
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Requirements: <Feature Name>
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
- [ ] Draft
|
|
6
|
+
- [ ] Reviewed
|
|
7
|
+
- [ ] Ready for /spec-plan — all open questions resolved, all scenarios written
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Problem Statement
|
|
12
|
+
|
|
13
|
+
<!-- Who has this problem? What is the pain? How often does it happen?
|
|
14
|
+
What is the cost of NOT solving it?
|
|
15
|
+
|
|
16
|
+
✗ Weak: "Users want to see their files better."
|
|
17
|
+
✓ Strong: "Users who manage 100+ files have no way to know which files
|
|
18
|
+
they recently opened — they re-navigate from scratch every session,
|
|
19
|
+
which wastes time and causes them to re-open the wrong version." -->
|
|
20
|
+
|
|
21
|
+
## Goals
|
|
22
|
+
|
|
23
|
+
<!-- Label each goal so plans and tasks can reference them by ID.
|
|
24
|
+
Write in measurable, user-visible terms.
|
|
25
|
+
✗ Weak: "Improve the file browsing experience."
|
|
26
|
+
✓ Strong: "Users can see the last-opened timestamp on any file." -->
|
|
27
|
+
|
|
28
|
+
- **G1**:
|
|
29
|
+
- **G2**:
|
|
30
|
+
- **G3**: <!-- add or remove lines as needed -->
|
|
31
|
+
|
|
32
|
+
## Non-Goals
|
|
33
|
+
|
|
34
|
+
<!-- Explicitly state what this does NOT cover.
|
|
35
|
+
This section is as important as Goals — it prevents scope creep before planning starts.
|
|
36
|
+
|
|
37
|
+
Example:
|
|
38
|
+
- Does not include sorting files by last-opened date (separate feature)
|
|
39
|
+
- Does not track access history — only the most recent timestamp
|
|
40
|
+
- Does not apply to folders -->
|
|
41
|
+
|
|
42
|
+
## Acceptance Criteria
|
|
43
|
+
|
|
44
|
+
<!-- Each scenario is a verifiable contract. Write them so a test can be derived
|
|
45
|
+
directly from the prose. Name real fields, status codes, UI elements, routes.
|
|
46
|
+
|
|
47
|
+
Scenario: file that has been opened shows its last-opened timestamp
|
|
48
|
+
Given: a file has been opened at least once (last_accessed_at is not null)
|
|
49
|
+
When: the user opens the file info modal
|
|
50
|
+
Then: a "Last opened" row is visible with the formatted timestamp
|
|
51
|
+
And: the timestamp matches the most recent recorded access time
|
|
52
|
+
|
|
53
|
+
Scenario: file that has never been opened hides the timestamp row
|
|
54
|
+
Given: a file has never been opened (last_accessed_at is null)
|
|
55
|
+
When: the user opens the file info modal
|
|
56
|
+
Then: the "Last opened" row is not rendered
|
|
57
|
+
|
|
58
|
+
Scenario: <add one scenario per distinct behavior>
|
|
59
|
+
Given: <precondition — system state before the action>
|
|
60
|
+
When: <action or event that triggers the behavior>
|
|
61
|
+
Then: <primary expected outcome>
|
|
62
|
+
And: <secondary outcome, if any>
|
|
63
|
+
-->
|
|
64
|
+
|
|
65
|
+
## Constraints
|
|
66
|
+
|
|
67
|
+
<!-- Group by type. Be explicit — vague constraints produce unexpected tradeoffs.
|
|
68
|
+
|
|
69
|
+
Technical: "Must not add a DB migration — the column already exists with a default."
|
|
70
|
+
Business: "Must ship before the Q2 demo on May 15."
|
|
71
|
+
UX: "Must match the existing row layout in the info modal — no redesign." -->
|
|
72
|
+
|
|
73
|
+
## Open Questions
|
|
74
|
+
|
|
75
|
+
<!-- Mark each question by whether it blocks planning or can be decided during it.
|
|
76
|
+
|
|
77
|
+
⛔ Blocking — /spec-plan cannot start until this is resolved:
|
|
78
|
+
Does folder navigation count as "opening" a file?
|
|
79
|
+
|
|
80
|
+
⚠️ Non-blocking — can be decided during planning with a reasonable default:
|
|
81
|
+
Should the timestamp be relative ("3 days ago") or absolute ("Apr 12, 14:30")? -->
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Technical Plan: <Feature Name>
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
- [ ] Draft
|
|
6
|
+
- [ ] **Approved** ← AI must not write code until this is checked
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Goals This Plan Addresses
|
|
11
|
+
|
|
12
|
+
<!-- List the goal IDs from 1-requirements.md that this plan covers.
|
|
13
|
+
If a goal is out of scope for this plan, say so explicitly.
|
|
14
|
+
|
|
15
|
+
G1 ✓ — covered by Tasks 1–2
|
|
16
|
+
G2 ✓ — covered by Task 3
|
|
17
|
+
G3 ✗ — out of scope for this plan (deferred to specs/payments-v2/) -->
|
|
18
|
+
|
|
19
|
+
## Assumptions
|
|
20
|
+
|
|
21
|
+
<!-- Every assumption that shapes this plan. Format: what + why + impact if false.
|
|
22
|
+
Run /assume before writing this section — list what came up there.
|
|
23
|
+
|
|
24
|
+
1. **`last_accessed_at` column already exists on `files`** — confirmed in schema.ts.
|
|
25
|
+
If false: a migration is required before any task in this plan can run.
|
|
26
|
+
|
|
27
|
+
2. **Fire-and-forget is acceptable for access recording** — a missed event
|
|
28
|
+
is not a product defect for this use case.
|
|
29
|
+
If false: need a queue with guaranteed delivery (significant scope increase). -->
|
|
30
|
+
|
|
31
|
+
## Approach
|
|
32
|
+
|
|
33
|
+
<!-- The simplest solution that satisfies the requirements. State it directly.
|
|
34
|
+
If you considered a simpler approach and rejected it, say why in one line.
|
|
35
|
+
|
|
36
|
+
Example: "A dedicated POST /api/files/[id]/access endpoint that issues a
|
|
37
|
+
targeted UPDATE on last_accessed_at only, leaving updated_at untouched.
|
|
38
|
+
Alternative: updating last_accessed_at in the existing PATCH /api/files/[id]
|
|
39
|
+
— rejected because it would bump updated_at on every read, corrupting
|
|
40
|
+
the 'modified' timestamp shown to users." -->
|
|
41
|
+
|
|
42
|
+
## Tradeoffs
|
|
43
|
+
|
|
44
|
+
<!-- Conscious sacrifices the chosen approach makes. Only include if they exist.
|
|
45
|
+
Format: what we gain → what we give up → why that's acceptable here.
|
|
46
|
+
|
|
47
|
+
Example:
|
|
48
|
+
- Fire-and-forget for access recording → we may miss an event if the request
|
|
49
|
+
fails silently → acceptable because a missed timestamp is not a product defect;
|
|
50
|
+
showing a slightly stale "last opened" is better than adding latency to every open.
|
|
51
|
+
- Separate POST endpoint instead of reusing PATCH → one extra HTTP round-trip
|
|
52
|
+
per file open → acceptable because it keeps updated_at semantics clean,
|
|
53
|
+
which is more important than saving a request.
|
|
54
|
+
|
|
55
|
+
If the approach has no meaningful tradeoffs, write "none." -->
|
|
56
|
+
|
|
57
|
+
## Components Affected
|
|
58
|
+
|
|
59
|
+
<!-- Every file that will be modified. Distinguish writes from read-only references.
|
|
60
|
+
|
|
61
|
+
New: app/api/files/[id]/access/route.ts
|
|
62
|
+
Modified: components/file-manager/itemButton.tsx — call recordFileAccess on open
|
|
63
|
+
Modified: components/file-manager/FileInfoModal.tsx — add "Last opened" row
|
|
64
|
+
Reference (no changes): lib/db/schema.ts — verify column type only -->
|
|
65
|
+
|
|
66
|
+
## New Artifacts
|
|
67
|
+
|
|
68
|
+
<!-- New files, types, DB objects, or migrations that don't exist yet.
|
|
69
|
+
|
|
70
|
+
File: lib/file-manager/recordFileAccess.ts — client-side fire-and-forget helper
|
|
71
|
+
Migration: none — column already exists
|
|
72
|
+
Type: none — reuses existing FileRecord -->
|
|
73
|
+
|
|
74
|
+
## What This Plan Does NOT Do
|
|
75
|
+
|
|
76
|
+
<!-- Mirror the non-goals from 1-requirements.md. Keeps the agent from drifting.
|
|
77
|
+
|
|
78
|
+
- Does not sort files by last-opened date
|
|
79
|
+
- Does not track access history — only the single most recent timestamp
|
|
80
|
+
- Does not apply to folders — folder navigation is intentionally excluded -->
|
|
81
|
+
|
|
82
|
+
## External Dependencies
|
|
83
|
+
|
|
84
|
+
<!-- New packages, APIs, or services this plan introduces. If none, write "none". -->
|
|
85
|
+
|
|
86
|
+
## Risks & Open Questions
|
|
87
|
+
|
|
88
|
+
<!-- Technical risks that could change this plan. Unresolved items block approval.
|
|
89
|
+
|
|
90
|
+
Risk: concurrent writes to last_accessed_at from multiple tabs.
|
|
91
|
+
→ Acceptable — last-write-wins is fine; no ordering guarantee needed.
|
|
92
|
+
|
|
93
|
+
Open: should the client retry the POST if it fails silently?
|
|
94
|
+
→ Decision needed before Task 2 starts. -->
|
|
95
|
+
|
|
96
|
+
## Abort Criteria
|
|
97
|
+
|
|
98
|
+
<!-- Conditions that require stopping /spec-tasks and returning to this plan.
|
|
99
|
+
Define them before starting — not when you're already stuck mid-execution.
|
|
100
|
+
|
|
101
|
+
- Any assumption above is found to be false
|
|
102
|
+
- recordFileAccess introduces measurable latency on file open (> 50ms p95)
|
|
103
|
+
- A component listed in "Components Affected" has been significantly refactored
|
|
104
|
+
since this plan was written, changing its interface
|
|
105
|
+
- A task requires touching files not listed here -->
|
|
106
|
+
|
|
107
|
+
## Verification
|
|
108
|
+
|
|
109
|
+
<!-- How to confirm each task is done. Link explicitly to scenarios in 1-requirements.md.
|
|
110
|
+
|
|
111
|
+
Task 1: POST /api/files/[id]/access returns 200 and updates only last_accessed_at
|
|
112
|
+
(run: check DB row — last_accessed_at changed, updated_at unchanged)
|
|
113
|
+
Task 2: opening a file via any of the four paths triggers the POST
|
|
114
|
+
(run: network tab or test spy — POST fires on lightbox, drawer, viewer, canvas)
|
|
115
|
+
Task 3: "Scenario: file that has been opened…" and "Scenario: file that has
|
|
116
|
+
never been opened…" both pass as integration tests -->
|
|
117
|
+
|
|
118
|
+
## Task Count Estimate
|
|
119
|
+
|
|
120
|
+
<!-- Rough count: N tasks -->
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Approval
|
|
125
|
+
|
|
126
|
+
Date:
|
|
127
|
+
Approved by:
|
|
128
|
+
Notes:
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Tasks: <Feature Name>
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Plan approved: <!-- date -->
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Rules
|
|
10
|
+
|
|
11
|
+
- One task at a time — finish it completely before moving on
|
|
12
|
+
- Write the test first — it must fail (red) before any implementation; implement until green; then run the full suite
|
|
13
|
+
- Each task touches only what's needed — no cleanup of adjacent code
|
|
14
|
+
- If a task reveals new scope, STOP and update 2-plan.md before continuing
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Tasks
|
|
19
|
+
|
|
20
|
+
- [ ] **Task 1**: <!-- Single-line description of what this task does.
|
|
21
|
+
Example: "Create POST /api/files/[id]/access route that updates
|
|
22
|
+
last_accessed_at without bumping updated_at" -->
|
|
23
|
+
- Test: <!-- What to write first, and what "red" looks like before implementation.
|
|
24
|
+
Example: "POST /api/files/[id]/access with a valid fileId returns 200
|
|
25
|
+
and the DB row shows last_accessed_at updated, updated_at unchanged
|
|
26
|
+
— must fail before the route file exists." -->
|
|
27
|
+
- Changes: <!-- Files to touch and what specifically changes in each.
|
|
28
|
+
Example: "create app/api/files/[id]/access/route.ts — PATCH targeting
|
|
29
|
+
only last_accessed_at; create lib/files/recordFileAccess.ts — thin
|
|
30
|
+
fetch wrapper, fire-and-forget, no return value." -->
|
|
31
|
+
- Goal: <!-- Goal ID from 1-requirements.md this task moves forward. Example: "G1" -->
|
|
32
|
+
- Criterion: <!-- Acceptance scenario this task satisfies. Example: "Scenario: file that has been opened shows its last-opened timestamp" -->
|
|
33
|
+
- Tradeoff: <!-- what we gain → what we give up → why acceptable. Omit if not applicable. -->
|
|
34
|
+
|
|
35
|
+
- [ ] **Task 2**: <!-- description -->
|
|
36
|
+
- Test: <!-- what to write first and what red looks like -->
|
|
37
|
+
- Changes: <!-- files + specific changes in each -->
|
|
38
|
+
- Goal: <!-- goal ID from 1-requirements.md -->
|
|
39
|
+
- Criterion: <!-- scenario name from 1-requirements.md -->
|
|
40
|
+
- Tradeoff: <!-- omit if not applicable -->
|
|
41
|
+
|
|
42
|
+
<!-- Add tasks as needed. One logical change per task.
|
|
43
|
+
If two changes always need to happen together to keep tests green, they are one task.
|
|
44
|
+
If two changes can be verified independently, they are two tasks. -->
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Completion
|
|
49
|
+
|
|
50
|
+
- [ ] All tasks done
|
|
51
|
+
- [ ] Every acceptance scenario in 1-requirements.md covered by a passing test
|
|
52
|
+
- [ ] /review completed
|
|
53
|
+
- [ ] Spec moved to `specs/_done/<name>/`
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
trigger: always_on
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
This project uses the SDD Protocol. Before starting any task, read:
|
|
6
|
+
|
|
7
|
+
1. `.sdd/workflow.md` — all commands, ceremony levels, and stop points
|
|
8
|
+
2. `.sdd/project-overview.md` — what this app is, its non-goals, and domains
|
|
9
|
+
3. `.sdd/conventions.md` — project-specific conventions and patterns
|
|
10
|
+
|
|
11
|
+
## Available commands
|
|
12
|
+
|
|
13
|
+
| Command | Purpose |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `/bootstrap` | Populate project context — interview or codebase scan |
|
|
16
|
+
| `/ask` | Research only — no code changes |
|
|
17
|
+
| `/assume` | List assumptions and stop for confirmation |
|
|
18
|
+
| `/bugfix` | Reproduce → diagnose → fix → validate |
|
|
19
|
+
| `/refactor` | Restructure without behavior change |
|
|
20
|
+
| `/spec-new` | Scaffold a spec folder |
|
|
21
|
+
| `/spec-plan` | Generate technical plan — stop for approval |
|
|
22
|
+
| `/spec-tasks` | Execute plan one task at a time, TDD-first |
|
|
23
|
+
| `/review` | Final audit before closing |
|
|
24
|
+
| `/finish` | Stage files and generate commit message |
|
|
25
|
+
|
|
26
|
+
Full definitions for each command are in `.sdd/workflow.md`.
|