Quotes
Financial quotes for renovation work — unified lifecycle entity covering pre-win vendor cost quotes and post-win execution. Quotes track line items and funding allocations, and are the R1 mirror of the HubSpot Quote object (0-14) — not Deals (HubSpot Deal = R1 Project).
Pivot (2026-05): post-win execution no longer lives on quote-owned phase tables (
quote_phases/quote_phase_tasksare gone). Won quotes hand over to workflow packages (workflow_packages.sourceQuoteId) — see Workflows and the contractor-engagement rebuild (spec2026-05-09-contractor-engagement-rebuild-design.md, handover redesign2026-05-29-workflow-package-handover-redesign-design.md).
Source Files
| Layer | Path |
|---|---|
| Schema | backend/src/db/schema.ts |
| Routes | backend/src/routes/quotes.ts, backend/src/routes/workflow/quotes.ts |
| Service | backend/src/services/quote-service.ts, backend/src/services/quote-finance-service.ts |
| Sync Config | backend/src/services/hubspot/sync-engine/entity-configs.ts (quoteConfig) |
| Pages | frontend/src/pages/Quotes.tsx |
| Components | frontend/src/components/quotes/ |
| Queries | frontend/src/lib/queries/quoteQueries.ts |
Database Tables
| Table | Purpose |
|---|---|
quotes | Main entity — project, contact, amounts, status, HubSpot sync, billing aggregates |
quote_line_items | Individual cost items with quantities, unit prices, component type, productId FK to Products |
quote_skill_assignments | Skill/trade assignments for quote execution |
quote_ab_snapshots | A/B comparison snapshots for quote versioning |
quote_department_responsibilities | Department responsibility assignments per quote |
quote_line_item_funding_measures | Links line items to Funding Applications measures |
quote_line_item_funding_loans | Links line items to funding loans |
component_quote_links | Links Building Components to quote line items |
funding_quote_allocations | Distributes funding across quotes (with approval workflow) |
Key Fields
| Field | Type | Notes |
|---|---|---|
projectId | uuid FK | Parent project (cascade delete) |
buildingId | uuid FK | Parent building |
contactId | uuid FK | Vendor/supplier contact |
status | enum | draft, sent, declined, accepted, in_progress, completed, cancelled, submitted, under_review, approved, rejected, expired, awarded, superseded |
totalAmount / netAmount / taxAmount | decimal(12,2) | Money: decimal strings + Big.js via @shared/money (spec 2026-04-24-money-arithmetic-bigjs-design.md) |
taxRate | decimal | Default 0.19 (German VAT) |
discountPercentage, skontoPercentage | decimal | Discount and early-payment terms |
templateId / templateVersion | uuid FK / int | Workflows template binding for the post-win lifecycle |
replacesQuoteId | uuid FK | Self-referential for quote replacement/versioning |
contractValue / billedTotal / paidTotal / openTotal | integer | Denormalized billing aggregates (maintained by lib/billing/billing-aggregates) |
hubspotId | varchar | HubSpot vendor ID — sync round-tripping only |
recordOwnerContactId | uuid FK | Read-only HubSpot owner mirror → Contacts; sync layer is sole writer |
HubSpot Sync
quoteConfig mirrors the HubSpot Quote object (0-14). projectId/buildingId/contactId are association-only columns: the sync’s pre-sync hook resolves them from the quote’s associated Deal/Contact, so the FK relationships come from HubSpot associations, not properties. Internal references always join on quotes.id (UUID PK), never hubspotId.
Quote Change Flows
Replacing an accepted quote (Angebotsänderung) is first-class (spec 2026-05-12-quote-change-rebuild-design.md):
- The new quote points at its predecessor via
replacesQuoteId; the old quote moves tosuperseded. - The affected workflow package re-points and bumps its version; the diff is journaled in
scope_change_log(triggerQuoteId,previousQuoteId, typedScopeDiffwith work-done warnings) — see Workflows.
Relationships
Quote *──1 Project
Quote *──1 Building
Quote *──1 Contact (vendor)
Quote 1──* Quote Line Items ──1 Product (optional)
Quote 1──* Quote Skill Assignments / A/B Snapshots / Department Responsibilities
Quote Line Items *──* Building Components (via component_quote_links)
Quote *──* Funding Applications (via funding_quote_allocations)
Quote 1──* Invoices (captured contractor invoices, optional source link)
Quote 1──* Workflow Packages (sourceQuoteId — post-win execution)
Quote ──> replacesQuoteId (self, quote change)
Frontend Components
| Component | Purpose |
|---|---|
QuoteForm | Create/edit quote with financial details |
QuoteLineItemsTable | Manage individual line items |
QuotesList | List view with filtering and sorting |
BuildingQuotesList | Quotes scoped to a building |
InlineQuotesTable / InlineQuoteRow | Compact inline display within other views |
LinkFundingApplicationsDialog | Link quotes to Funding Applications |
CreateQuoteWithProjectDialog | Quick-create quote with project selection |
Features
- Line items management with quantities, unit prices, component type mapping, and Products references
- Funding allocation linking line items to Funding Applications measures and loans
- Component linking connecting quote line items to Building Components
- A/B snapshots for comparing quote versions side-by-side
- Skill assignments tracking which trades/skills are needed for execution
- Post-win handover to workflow packages (one package per won quote)
- Quote change with supersession + scope-change journaling
- Skonto/discount terms with deadlines (German early-payment convention)
- Billing aggregates denormalized from the billing module (Invoices)
Related Pages
Projects | Buildings | Invoices | Funding Applications | Building Components | Products | Contacts | Workflows | Financial Calculations | HubSpot Integration | Database Architecture