Products
Product catalog for renovation services and funding products. Products define what Renewa offers — from energy consulting (iSFP) to specific funding program services (BEG EM, KfW). Supports bundles, application type mapping, and is the R1 mirror of the HubSpot Product object (0-7).
Source Files
| Layer | Path |
|---|---|
| Schema | backend/src/db/schema.ts |
| Admin Routes | backend/src/routes/admin/products.ts |
| Service | backend/src/services/catalog-service.ts |
| Sync Config | backend/src/services/hubspot/sync-engine/entity-configs.ts (productConfig) |
| Admin Pages | frontend/src/pages/admin/AdminProductsList.tsx, AdminProductDetail.tsx |
| Mock Data | backend/src/db/mocks/products.ts (large catalog; loads only with AUTO_MOCK=true) |
Database Tables
| Table | Purpose |
|---|---|
products | Main entity — key, label, category, pricing, HubSpot sync |
product_bundle_children | Parent-child relationships for bundle products |
application_types | Antragstypen (e.g., beg_einzelmassnahme, kfw_foerderung) |
product_application_types | Junction: which products apply to which application types |
Key Fields
| Field | Type | Notes |
|---|---|---|
key | text | Unique identifier (e.g., bafa_beg_em, effi_wg, isfp) |
shortName | text | Short display name (e.g., BEG EM, Effi WG, iSFP) |
label | jsonb LocalizedText | Bilingual name (de/en, required) |
description | jsonb LocalizedText | Bilingual description |
category | varchar | Grouping — foerdermittel (funding), beratung (consulting) |
actor | varchar | Responsible party — engineer, backoffice, technician, team |
productNumber | varchar | HubSpot Produktnummer (e.g., BBG EFFI AT) |
listPrice | integer | Listenpreis in cents (e.g., 110000 = 1100.00 EUR) |
priceEur / costOfGoodsSold | decimal(12,2) | HubSpot prices — decimal strings, Big.js arithmetic only (Invoices money rules) |
isBundle | boolean | Whether this is a bundle (Bündelprodukt) |
craft | varchar | HubSpot “gewerk” — Wände, Steildach, Wärmepumpe, … |
applicationTypeKey | varchar | HubSpot “antragstyp” — KfW 261 Effi, BAFA BEG EM, … |
technicalPlanningTypeKey | varchar | HubSpot “berechnungstyp” — iSFP, Heizlastberechnung, … |
positionType | varchar | HubSpot “positionstyp” — Rabatt, TVO (document-matrix marker) |
source | varchar | renewa (manually maintained) or hubspot (synced) |
hubspotId | varchar | HubSpot vendor ID — sync round-tripping only, never business logic |
recordOwnerContactId | uuid FK | Read-only HubSpot owner mirror, resolved to Contacts; sync layer is the sole writer |
HubSpot Sync
Products mirror the HubSpot Product object (objectTypeId 0-7) via the sync engine (productConfig in entity-configs.ts):
| Aspect | Details |
|---|---|
| HubSpot → Renewa | Products synced in with source: 'hubspot'; name/description land in hubspotProperties json |
| Coexistence | Manually maintained source: 'renewa' rows live alongside synced rows (key unique) |
| Shared fields | hubspotId, sku, priceEur, hsStatus, hubspotProperties, hubspotSchemaVersion |
| Lifecycle | archived, archivedAt, deletedAt, mergedIntoHubspotId for sync state; orphan detection requires non-null hubspotId |
No vendor lock-in: internal cross-table references (quote/invoice line items) join on products.id (UUID PK), never on hubspotId (CLAUDE.md HubSpot Entity Map).
Bundle System
Bundle products have child products via product_bundle_children:
parentProductId→ the bundle productchildProductId→ individual component productssortOrdercontrols display ordering- Unique constraint prevents duplicate parent-child links
Relationships
Product 1──* Product Bundle Children (parent)
Product *──1 Product Bundle Children (child)
Product *──* Application Types (via product_application_types)
Product 1──* Quote Line Items (productId FK)
Features
- Large mock catalog with real German renovation products (
db/mocks/products.ts; “seeding” retired) - Bundle products with parent-child composition (Bündelprodukt)
- Application type mapping — defines which products apply to which funding types
- Matrix matching via
craft,applicationTypeKey,technicalPlanningTypeKey,positionType - Admin management via Admin Dashboard with list and detail views
- Workflow integration — workflow templates/phases/tasks match on
product.keyarrays (matchingProductsRequired,assignedProductKeys) - Used in Quotes line items via
productIdFK
Related Pages
Quotes | Invoices | Funding Programs | Measures | HubSpot Integration | Workflows | Admin Dashboard | Database Architecture