Audience: PMs, Legal, Developers
Outcomes: Predictable contract flow; minimal back-and-forth
State machine
stateDiagram-v2 [*] --> draft draft --> pending_review: sendForReview pending_review --> approved: approve pending_review --> rejected: reject approved --> pending_signature: sign pending_signature --> active: fullySigned rejected --> draft: revise active --> [*]
Key API calls
# Create/update draft curl -X POST $API_BASE/api/contracts/draft -b cookies.txt \ -H 'Content-Type: application/json' \ -d '{"title":"Design SOW","value":"1500.00","currency":"USD","contractType":"service","parties":["[email protected]","[email protected]"]}' # Send for review curl -X POST $API_BASE/api/contracts/draft/send-for-review -b cookies.txt \ -H 'Content-Type: application/json' -d '{...}' # Approve/Reject curl -X POST $API_BASE/api/contracts/draft/draft_123/respond -b cookies.txt \ -H 'Content-Type: application/json' -d '{"action":"approve","message":"Looks good"}' # Activate (signing / on-chain prep) curl -X POST $API_BASE/api/contracts/blockchain -b cookies.txt \ -H 'Content-Type: application/json' \ -d '{"title":"Design SOW","amount":150000,"currency":"USD","buyerEmail":"[email protected]"}'
Edge cases
Missing partner link for cross-org contracts ⇒ 400/403.
Changing terms after approval resets to draft or requires re-review.
Effective/expiry times are UTC; reminders show absolute local times.
Anti-patterns
Email-only approvals; keep decisions in-app for auditability.
QA checklist
Draft → Review → Approve → Sign transitions persist and emit events.
Term change after approval forces re-review.
Attempt to sign without required roles/KYC ⇒ 403 with reason.