Files
simone 3b1f49d059 docs(v2.0): finalize roadmap + requirements — phases 7-11 approved for planning
- Upgrade PROJECT.md: v2.0 Business Operations Suite (unified catalog, offers with phases, public quotes, CRM pipeline, auto-provisioning)
- Create REQUIREMENTS.md sections: CAT-U, OFFER-B, QUOTE, CRM, WIN requirements for phases 7-11
- Extend ROADMAP.md: 5-phase structure (7-11), 14-19 days total, risk/flag registry
- Archive v1.0 milestone (phases 1-6, complete)
- Switch STATE.md to v2.0, status=planning
- Create research documents: STACK.md, FEATURES_v2.0.md, ARCHITECTURE.md, PITFALLS.md, SUMMARY.md

Ready for: /gsd-plan-phase 7

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-11 06:01:59 +02:00

211 lines
7.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Pitfalls Checklist: Business Operations Suite v2.0
Quick reference for preventing the 9 major pitfalls during Phase 79 implementation.
---
## Critical Pitfalls (Before Code)
### 1. Catalog Consolidation Breaks Quotes
- [ ] Migration strategy documented (Expand-Contract, not drop)
- [ ] Mapping layer between old/new tables designed
- [ ] Backfill script tested on production backup
- [ ] Referential integrity test query written
- [ ] Dual-write period defined (2-3 weeks)
- [ ] Rollback plan documented (drop new table, revert code)
### 2. Offer Template Mutation
- [ ] Offer/project hierarchy mapping documented (1 page)
- [ ] Copy function uses `db.transaction()` (all-or-nothing)
- [ ] Uses `structuredClone()` for deep copy, not `{...spread}`
- [ ] Idempotency key added to CRM leads table
- [ ] Integration test: copy offer, verify structure consistent across instances
- [ ] Test: edit project phase, verify offer template unchanged
### 3. Public Quote Token Leakage
- [ ] Token length ≥ 32 chars (nanoid(32) or nanoid(64))
- [ ] Expiration field added (default 7 days)
- [ ] Email validation on public page (token + email required)
- [ ] Rate limiting implemented (max 3 views/token/minute)
- [ ] Code audit: quote_items NOT in public API response
- [ ] Test: brute-force 1000 guesses, verify rate limit activates
- [ ] Test: enumerate tokens with different emails, verify 401
---
## Moderate Pitfalls (During Implementation)
### 4. Drag-and-Drop Race Condition
- [ ] `version` field added to offer_phases
- [ ] Update mutation checks version (returns 409 if mismatch)
- [ ] Server recomputes all sort_orders atomically
- [ ] Frontend handles 409 Conflict (refresh UI)
- [ ] Test: concurrent drag in 2 tabs, verify final state correct
### 5. CRM "Win" Double-Click
- [ ] Idempotency key added to crm_leads (unique)
- [ ] "Win" mutation checks if key already processed
- [ ] All sub-steps in single `db.transaction()`
- [ ] Button disabled until success
- [ ] Idempotency key stored in localStorage
- [ ] Test: double-click "Win", verify only 1 client created
### 6. Offer Copy Missing Tasks/Deliverables
- [ ] Mapping documented: offer_micro → project_phase → project_task → deliverable
- [ ] Copy function recursive (phases → tasks → deliverables)
- [ ] Validation test: assert counts match expected
- [ ] Integration test exists (copy, verify structure)
- [ ] Query test: no orphaned deliverables (task_id IS NULL)
---
## Minor Pitfalls (Polish)
### 7. Offer State Not Synced Between Tabs
- [ ] `version` field on offer_micros
- [ ] Update returns 409 on version mismatch
- [ ] UI shows "Offer changed, reload?" dialog
### 8. CRM Schema Backward Incompatibility
- [ ] New columns added as NULLABLE
- [ ] Code handles NULL defensively (e.g., `lead.budget ?? 0`)
- [ ] Backfill script written (sets defaults for existing rows)
- [ ] NOT NULL constraint added only after backfill + validation
- [ ] Test: production data copied to test db, code runs without errors
### 9. CRM Scope Creep
- [ ] Must-have features defined for v2.0 (lead pipeline, quote, auto-onboard)
- [ ] Should-have features listed for v2.1+ (email, calls, source)
- [ ] Won't-have features documented (team, multi-user, integrations)
- [ ] Scope document signed off by product
- [ ] Success metric defined: "Can go from lead to won project in <30 min"
---
## Phase 7 Checklist (Catalog & Offers)
**Before code:**
- [ ] Catalog consolidation migration plan reviewed
- [ ] Offer/project hierarchy documented
- [ ] Drag-drop version/locking strategy designed
**During implementation:**
- [ ] Migration backfill tested on production backup
- [ ] Drag-drop version field added
- [ ] Offer phase copy function atomic (transaction)
- [ ] Idempotency key on CRM leads
- [ ] Integration tests for copy consistency
**Before go-live:**
- [ ] Dry-run migration on production DB
- [ ] Verify referential integrity (no orphaned quote_items)
- [ ] Concurrent drag-drop test passes
- [ ] Offer copy count validation passes
---
## Phase 8 Checklist (Public Quote Pages)
**Before code:**
- [ ] Token security requirements finalized
- [ ] API response schema designed (no quote_items)
- [ ] Rate limiting strategy defined
**During implementation:**
- [ ] Token generation (nanoid(32))
- [ ] Expiration + email validation
- [ ] Rate limiting middleware
- [ ] Code audit for quote_items exposure
- [ ] Brute-force test (>1000 guesses/sec)
**Before go-live:**
- [ ] Brute-force test activates rate limit
- [ ] Enumeration test returns 401 for wrong email
- [ ] Expiration test returns 401 after expiration
- [ ] Code review: quote_items not in response
---
## Phase 9 Checklist (CRM Won Automation)
**Before code:**
- [ ] Scope document (Must/Should/Could/Won't) reviewed
- [ ] Idempotency strategy designed
- [ ] Payment plan algorithm defined
- [ ] Offer snapshot structure (JSONB) designed
**During implementation:**
- [ ] Idempotency key on crm_leads
- [ ] "Win" mutation atomic (client + project + phases + payments)
- [ ] Offer snapshot stored on win
- [ ] Button disabled until success
- [ ] Payment consistency tests
**Before go-live:**
- [ ] Double-click test: only 1 client created
- [ ] Network timeout test: retry returns same project
- [ ] Partial failure test: rollback on error
- [ ] Payment consistency test: correct number created
- [ ] Idempotency test: 10x "Win" with same key = 1 client
---
## Key Questions Before Each Phase
**Phase 7:**
- ✓ Is catalog consolidation migration safe (Expand-Contract, dual-write)?
- ✓ Does offer/project hierarchy mapping make sense (1 micro = 1 phase)?
- ✓ Is copy function atomic (all-or-nothing)?
- ✓ Do we have integration tests for offer phase structure consistency?
**Phase 8:**
- ✓ Is token length ≥ 32 chars and properly random?
- ✓ Do we validate both token AND email on public page?
- ✓ Is rate limiting active (max 3 views/token/min)?
- ✓ Can we prove quote_items never appears in public response?
**Phase 9:**
- ✓ Is "Win" action atomic (transaction)?
- ✓ Does idempotency key prevent duplicates on retry?
- ✓ Is button disabled until success?
- ✓ Have we defined Must/Should/Won't scope with user?
---
## Testing Validation Matrix
| Pitfall | Test Case | Expected Outcome | Status |
|---------|-----------|------------------|--------|
| 1. Catalog consolidation | Backfill migration on prod backup | Zero orphaned quote_items | [ ] |
| 2. Offer template mutation | Edit project phase, check offer unchanged | Offer template immutable | [ ] |
| 3. Token leakage | Brute-force 1000 guesses/sec | Rate limit activates (429) | [ ] |
| 3. Token leakage | Enumerate with wrong email | Returns 401 Unauthorized | [ ] |
| 4. Drag-drop race | Concurrent drag in 2 tabs | Final sort_order is coherent | [ ] |
| 5. Double-click clients | Click "Win" twice | Only 1 client created | [ ] |
| 5. Double-click clients | Network timeout + retry | Same project returned | [ ] |
| 6. Missing deliverables | Copy offer to project | All tasks and deliverables copied | [ ] |
| 8. Schema backward compat | Copy production data to test DB | No crashes, NULL handled | [ ] |
| 9. Payment consistency | "Win" with partial failure | Rollback, no orphaned payments | [ ] |
---
## Red Flags During Development
🚨 **Stop and review if:**
- Offer/project hierarchy mapping is unclear (should be 1 page, explicit)
- Drag-drop sort_order updates without version check
- "Win" mutation has any non-transactional steps (client created outside txn)
- Copy function uses shallow spread (`{...obj}`) instead of `structuredClone()`
- Token length < 32 chars
- Public API response includes quote_items or per_service_price
- CRM leads table has no idempotency_key column
- Schema changes add NOT NULL without backfill test
- "Win" button not disabled until response received
- No rate limiting on public quote page
---
**Owner:** Development team
**Review:** Before each phase kickoff
**Update:** As testing results come in