Product Architecture
Inside TradeQuote
A modern multi-tenant SaaS that keeps every business's data isolated, every quotation auditable, and every flow snappy on mobile and desktop.
Core quotation lifecycle
Add customer
Draft quotation
Generate PDF
Send to customer
Customer accepts
System layers
Identity & Tenancy
- · Role-based sessions
- · Tenant scoping per request
- · Customer portal links
Application
- · Customer CRUD
- · Quotation editor
- · PDF generation
- · Email delivery
Data
- · Tenant-scoped reads
- · Append-only audit log
- · Versioned quotations
Tenant isolation rules engine
Every read and write passes through a rules engine that scopes data to the active tenant. This prevents accidental cross-tenant leakage even when the application code has bugs.
rule "scope.customers"
when role == "tradesperson"
allow read, write where customer.tenantId == session.tenantId
rule "scope.quotations"
when role == "tradesperson"
allow read, write where quotation.tenantId == session.tenantId
rule "customer.portal"
when role == "customer"
allow read where quotation.customerEmail == session.email
allow write status in ("Accepted", "Rejected")
where quotation.status == "Sent"
rule "admin.oversight"
when role == "admin"
allow read all
deny write on quotation.itemsQuotation status machine
Draft
Sent
Accepted
Rejected
- · Draft → Sent: tradesperson sends to customer (email + PDF).
- · Sent → Accepted: customer accepts via portal.
- · Sent → Rejected: customer declines; tradesperson can duplicate as a new draft.
- · Accepted/Rejected are terminal — duplicate to revise.
Data model
Tenant
id
company
vat
plan
active
User
id
email
role
tenantId?
Customer
id
tenantId
fullName
email
phone
address
Quotation
id
number
tenantId
customerId
status
items[]
QuoteItem
id
description
qty
unitPrice
AuditEvent
id
ts
actor
action
target
Tenant isolation
Row-level scoping enforced at the data layer.
Audit trail
Every state change appended to an immutable log.
Versioned quotes
Every edit captured for compliance and trust.