Purchase Pipeline — Architecture

7 stages, 3 new tables, everything else reuses existing models

The 7 Stages
1
Purchase Request
Operations team fills in items needed
EXISTING · purchase_requests
2
GM Digital Signature
GM draws signature on canvas, saved as image
NEW · purchase_signatures
3
Select Suppliers → Send RFQ Links
Pick suppliers from list, system sends unique links via WhatsApp/Email
NEW · rfq_invitations
4
Suppliers Submit Quotes
Each supplier opens their private link, fills price + terms, submits
NEW · supplier_quotes + quote_items
5
Quote Comparison & Award
Side-by-side table, team picks winner, records decision reason
NEW · supplier_quotes (awarded flag)
6
Issue LPO
Create & send Local Purchase Order to winning supplier
EXISTING · purchase_orders (LPO)
7
Receive Materials at Site
GRN created — each item flagged Inventory or Consumable
EXISTING · goods_receipt_notes + grn_items
8
Issue Payment / Cheque
Record cheque number, bank, amount, payment date
EXISTING · supplier_payments
3 New Database Tables
purchase_signatures
id
purchase_request_id → FK
signed_by → FK users
signature_image → base64 png
signed_at → timestamp
ip_address
rfq_invitations
id
purchase_request_id → FK
supplier_id → FK
token → unique 64-char hex
channel → email|whatsapp|both
sent_at, opened_at, expires_at
status → pending|opened|submitted|declined
supplier_quotes + supplier_quote_items
id
rfq_invitation_id → FK
submitted_at
lead_time_days
payment_terms
notes
total_amount
is_awarded → boolean
award_reason
── items ──
description, unit, qty, unit_price, total
Public Portal (no auth)
🔗 /rfq/{token}
• Outside auth middleware — no login needed
• Token validated on every request
• Expires 7 days after sending
• Can only be submitted once
• Shows your company name + item list
• Supplier fills price/terms, submits
• Confirmation screen shown after submit
Existing models — minor additions only
purchase_requests → add stage column
grn_items → add type (inventory|consumable)
purchase_orders → relabel as LPO in UI only

Does this architecture look right? Reply in the terminal.