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>
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
# Pitfalls Checklist: Business Operations Suite v2.0
|
||||
|
||||
Quick reference for preventing the 9 major pitfalls during Phase 7–9 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
|
||||
Reference in New Issue
Block a user