The ERP World View — Why Construction Is Manufacturing¶
Read this first. Before any spec, any code, any schema. This is the lens through which every design decision in this project makes sense.
The Three Concerns¶
iDempiere separates documents into header (C_Order) and lines (C_OrderLine), with its BOM spatiality validated against Validation Rules. We inherit the same separation:
| Concern | iDempiere | BIM Compiler | Table |
|---|---|---|---|
| WHAT to build | Orders, Categories, Products | Which products, classified by M_Product_Category + AD_Org | c_orderline |
| HOW to validate | BOMs, AttributeSets, Validation | Spatial rules propose, regulatory rules gate — by discipline and jurisdiction | ad_val_rule |
| WHERE it lands | Output.db for 4D–8D | Compiled placements + ASIs — the single source of truth downstream | output.db |
These three concerns are never merged. A change to WHAT (swap a product) does not require changes to HOW (rules are independent — swap jurisdiction without touching products) or WHERE (compiled output recalculates automatically). This is the architectural invariant that makes exception-based ordering possible: override one concern, inherit the others.
The downstream payoff: output.db with its ASIs (per-instance attributes) is what every downstream dimension reads — 4D scheduling, 5D cost, 6D carbon, 7D facility management, and 8D ERP integration. One compiled output, seven queries.
WHAT: M_Product_Category (Classification) + AD_Org (Discipline)¶
The WHAT concern has two orthogonal axes — what kind of thing and who is responsible.
M_Product_Category — Product classification (WHAT kind of thing). The same entity iDempiere uses to group products into swap pools. Categories form a BOM cascade — a Bill of Materials is a recipe: one parent product, N child products, each with a quantity. The magic is that each child can itself be a BOM — a building contains floors, a floor contains rooms, a room contains furniture, recursively. Each level is atomic and self-contained:
Level M_Product_Category Examples
───── ────────────────── ────────
Building RE (Residential) SH, DX, DM, FK
Floor GF, L1, RF ground, first, roof
Room LIVING, KITCHEN swap pool — replace one LIVING layout for another
Leaf IFC_WALL, IFC_DOOR element classification (→ component library geometry)
The category at each level defines the swap pool — you can replace one LIVING room layout with another LIVING layout, but you can't swap a LIVING room for a KITCHEN. This is iDempiere's Configure-to-Order constraint applied to spatial BOMs.
AD_Org — Discipline (WHO is responsible). In iDempiere, AD_Org partitions
data by business unit. Here, 16 engineering disciplines partition the BOM
validation space — from architecture to rail infrastructure. Each has its
own rules, its own AD_Val_Rule set, its own validation pass — but sharing
the same product catalog. See the full AD_Org table below for all 16
disciplines with IFC class mappings and Terminal element counts.
The distinction matters. Disciplines cut ACROSS the category tree — they don't appear AS levels within it. Three products in the same room (same category path) can have three different AD_Orgs:
Category cascade: RE → GF → LIVING → SOFA_001 ← AD_Org = ARC
Category cascade: RE → GF → LIVING → SPRINKLER_001 ← AD_Org = FP
Category cascade: RE → GF → LIVING → LIGHT_001 ← AD_Org = ELEC
M_Product_Category answers "what kind of thing?" AD_Org answers "who installs it?"
The Category Cascade — One Pattern, Three Domains¶
The cascade is universal. The same parent→child→grandchild pattern governs residential, infrastructure, and commercial buildings. Only the category names change:
Residential:
RE (Residential)
└─ M_Product: SH (IsBOM=Y) ← the building IS a product
└─ GF (Ground Floor, IsBOM=Y) ← floor is a product
└─ LIVING (Room, IsBOM=Y) ← room is a product
├─ SOFA_001 (IsBOM=N) ← leaf — geometry from component library
└─ TABLE_001 (IsBOM=N) ← leaf — geometry from component library
Infrastructure:
IN (Infrastructure)
└─ M_Product: BR (Bridge, IsBOM=Y)
└─ SUP (Support, IsBOM=Y) ← segment is a product
└─ PILE_001 (IsBOM=N) ← leaf — geometry from component library
Commercial:
CO (Commercial)
└─ M_Product: WA (Warehouse A, IsBOM=Y)
└─ L1 (Level 1, IsBOM=Y) ← floor is a product
└─ OFFICE (Space, IsBOM=Y) ← space type — same swap-pool logic
└─ DOOR_001 (IsBOM=N) ← leaf — geometry from component library
Category Population — Current State¶
| M_Product_Category | Buildings | Sub-Categories |
|---|---|---|
| RE (Residential) | SH, DM, DX, FK, AC | LIVING, KITCHEN, BEDROOM, BATHROOM, DINING, MASTER, CORRIDOR, OFFICE + floor-level (GF, RF, L1, L2) |
| RE (Residential, floor-only) | BA, BH, BS, CA, CE, CH, CL, CP, CS, ES, GH, HI, JE, JS, MO, NI, RA, RM, RS, SC, WB, WI | Floor-level categories only (GF, L1, L2, ROOF, FDN, MISC) — no room categories yet |
| IN (Infrastructure) | BR, RD, RL | SUP, DCK, ABT, TRK, ROAD, RAIL, GEO — segment types |
| CO (Commercial) | WA, WL, WT, TE | LOBBY, OFFICE, PLANT_ROOM, LOADING + floor-level (L1–L5) + discipline-driven (ARC, STR, FP, ACMV, ELEC, CW, SP, LPG) |
| IP (Industrial Plant) | IP | PROCESS, UTILITY, CONTROL, MISC + floor-level |
Gaps: 22 residential buildings have only floor-level categories (GF, L1, L2) but no room-level categories (LIVING, KITCHEN, BEDROOM). These buildings were extracted before room-level classification was implemented. Re-extraction with the current pipeline would populate room categories automatically.
Self-describing BOM tree: The hierarchy is whatever the products make it
(BBC.md §1 — no fixed UNIT/FLOOR/ROOM/SET/ITEM vocabulary). Root = getParentBOM() returns null.
Leaf = getChildren() returns empty. M_Product_Category determines the grouping at each level.
The Insight¶
In 2006, we built ADempiere's manufacturing BOM module. In 2010, we rebuilt it for iDempiere. After two decades of watching M_Product, M_BOM, and C_Order handle everything from circuit boards to patio furniture sets, the realisation was unavoidable:
A building is just a very large manufactured product with spatial coordinates.
Every wall panel is an M_Product. Every floor plan is an M_BOM (assembly recipe). Every construction project is a C_Order. The only thing manufacturing MRP lacks is the where — the (x, y, z) coordinates that turn a flat bill of materials into a three-dimensional building.
Manufacturing solved procurement, scheduling, cost control, and quality decades ago. Construction never had a Bill of Materials. This project provides one. The rest follows from that foundation.
The Pattern: A Product IS a BOM¶
In iDempiere/Libero Manufacturing, there is one universal entity: M_Product.
A Patio Furniture Set is an M_Product. Set IsBOM=Y and it has children:
4 chairs, 1 table, 1 optional shade — each an M_Product in its own right.
The chairs are leaf products (IsBOM=N): they have no children, they reference
inventory directly. The set is a BOM product: it has a recipe (M_BOM) with
lines (M_BOM_Line) that point to its children.
This is the entire model. Products all the way down. BOMs are not a separate entity — they are a property of a product. A building is a product. A floor is a product. A room is a product. A door is a product. A bridge span is a product. A road segment is a product. The tree is universal.
The root product has no parent. Every other product is a child of something. M_Product_Category determines what kind of thing it is — not a hardcoded type string, but the category cascade. The tree structure tells you nesting. The category tells you domain meaning. The compiler doesn't need to know if it's walking a building or a bridge — it walks products.
Residential:
SH (M_Product, IsBOM=Y, M_Product_Category=RE) ← root (no parent)
└─ GF (M_Product, IsBOM=Y, M_Product_Category=GF) ← child of root
└─ LIVING (M_Product, IsBOM=Y, M_Product_Category=LIVING)
├─ WALL_PANEL (M_Product, IsBOM=N → geometry from component library)
├─ DOOR (M_Product, IsBOM=N → geometry from component library)
└─ FURNITURE_SET (M_Product, IsBOM=Y, M_Product_Category=FR)
├─ TABLE (M_Product, IsBOM=N → leaf)
└─ CHAIR × 4 (M_Product, IsBOM=N → leaf)
Infrastructure (same model, different categories):
BR (M_Product, IsBOM=Y, M_Product_Category=IN) ← root (no parent)
└─ SPAN_01 (M_Product, IsBOM=Y, M_Product_Category=SPAN)
└─ PILE_001 (M_Product, IsBOM=N → leaf)
When the compiler encounters a BOM product, it explodes (recurses into children). When it encounters a leaf product, it resolves (looks up geometry in the component library). This is the same operation an ERP system performs when it explodes a manufacturing BOM into work orders. The walker doesn't branch on domain vocabulary — it follows the tree.
The Order — Configure-to-Order¶
In iDempiere, there is one C_DocType per document purpose: SOO (Sales Order), POO (Purchase Order), MOP (Manufacturing Order). Product classification lives on M_Product → M_Product_Category — never on the document type.
This project has exactly one document purpose: "Construction Order." That is the C_DocType. Classification lives where it belongs — on the product's M_Product_Category, not on the order.
The BOM cascade gives you the FULL product tree (SH → floors → rooms → furniture → thousands of leaves). But the C_Order does NOT repeat that tree. This is iDempiere's Configure-to-Order pattern: the order carries only the EXCEPTIONS.
M_Product SH (BOM template): 1099 elements (full cascade)
C_Order "Build me SH": 0 lines (no exceptions — use template as-is)
C_Order "SH but no sofa": 1 line (qty=0 at locator_ref RE.GF.LI.SOFA_001)
C_Order "SH Solar Premium": 6 lines (inherits from SH Solar, adds overrides)
C_Order "200 houses, 6 variants": 200 × ~3 lines = 600 lines (not 200 × 1099)
The BOM template is the PRODUCT (M_Product + M_BOM + M_BOM_Line cascade). The Order is just the delta — Remove (qty=0), Compress (reference class × N), Replace (swap product at locator_ref), Add (new line). Inheritance chains (Ref_Order_ID) let you stack deltas: SH_BASE → SH_SOLAR → SH_SOLAR_PREMIUM.
The category at each level constrains what the thin order can override. You can Replace a LIVING room layout with another LIVING layout, but you can't swap it for a KITCHEN. M_Product_Category is the swap-pool guard.
The Entity-Relationship Model¶
Every table in this project maps to a proven iDempiere entity. No invented abstractions. No BIM-specific data models.
The ERD¶
M_Product_Category (RE, IN, CO) ← WHAT kind of thing (cascade level)
└─ M_Product (SH, DX, BR) ← the thing itself (IsBOM=Y or N)
├─ M_BOM + M_BOM_Line ← children (cascade down, dx/dy/dz tack offsets)
├─ M_AttributeSet ← WHICH attributes vary (BIM_Pipe, BIM_Component)
│ └─ M_AttributeSetInstance ← per-instance values (length=3200mm)
└─ AD_Org ← WHO installs it (ARC, FP, ELEC) — tag, not level
C_DocType ("Construction Order") ← ONE document type, always
└─ C_Order ("Build me SH") ← references M_Product
├─ C_OrderLine ← exceptions only (thin order)
│ ├─ locator_ref ← WHERE in the tree
│ └─ M_Product_Category ← swap pool constraint
├─ Ref_Order_ID ← inheritance chain
└─ C_Campaign ← design theme (orthogonal)
AD_Val_Rule ← jurisdiction rules (MY/UBBL, US/IBC)
AD_ChangeLog ← full provenance (undo/redo stack)
The Mapping: iDempiere → BIM¶
| iDempiere Manufacturing | BIM Compiler | What It Does |
|---|---|---|
| M_Product | Building element or assembly | The universal entity. Everything is a product |
| M_Product_Category | RE, IN, CO, GF, LIVING, IFC_WALL... | Classifies products at every cascade level. WHAT kind of thing |
| AD_Org | ARC, STR, FP, ELEC, ACMV... | Discipline = organisational unit. WHO is responsible |
| M_BOM + M_BOM_Line | Assembly recipe + children | BOM explosion. Each line has dx/dy/dz tack offset |
| C_Order | Construction project | One order = one building. Carries exceptions only |
| C_OrderLine | Exception line | Deviation from BOM template (swap, remove, compress, add) |
| C_DocType | "Construction Order" | ONE document type. Classification lives on M_Product_Category |
| DocAction lifecycle | DR → IP → CO → AP | Draft → In Progress → Complete → Approved |
| AD_Val_Rule | Validation by jurisdiction | Same rule engine, construction codes instead of tax codes |
| C_Campaign | Design theme | Bali, Scandinavian, Industrial — marketing drives variant |
| AD_PrintFormat | Output selection | Which elements to render, which to hide |
| M_AttributeSet | Instance variation | Per-element customization (pipe length, colour, finish) |
| C_Project | Site development | 200 houses under one project. Groups C_Orders |
The extension: Manufacturing MRP has product + quantity + sequence.
We add three columns to M_BOM_Line: dx, dy, dz — parent-relative
tack offsets in millimetres. That is the entire difference between a flat
BOM and a spatial BOM. Three integers turn procurement into construction.
Orthogonal Dimensions¶
Seven dimensions cut ACROSS the product category cascade. None of them appear AS levels within the tree:
| Dimension | iDempiere Entity | What It Controls | Orthogonal To |
|---|---|---|---|
| Classification | M_Product_Category | What kind of thing (swap pool) | — (this IS the cascade) |
| Discipline | AD_Org | Who installs it | Category |
| Design theme | C_Campaign | Bali, Scandinavian, Industrial | Category, Discipline |
| Jurisdiction | AD_Val_Rule | MY/UBBL, US/IBC rules | Category, Discipline, Theme |
| Costing | M_PriceList | Unit cost by region/contract | All above |
| Instance variation | M_AttributeSetInstance | Pipe length, colour, finish | All above |
| Site grouping | C_Project | 200 houses under one project | Everything |
M_AttributeSet — Why Product Count Stays Small¶
Without AttributeSets, TE (Terminal) with 48,428 elements would need 48,428 separate M_Products. That's wrong. In iDempiere, a shirt comes in S/M/L/XL — that's ONE M_Product with an M_AttributeSet (size) and 4 M_AttributeSetInstances. Not 4 products.
Same pattern for construction. An FP (Fire Protection) route has: - START (pipe segment) - MID (pipe segment — different length) - JOINT (elbow, tee, reducer — fixed geometry) - DEVICE (sprinkler head, valve — fixed geometry) - END (cap, terminal)
These are ~5 abstract M_Products, not thousands. The VARIABLE part (pipe length) lives on M_AttributeSetInstance. The FIXED part (elbow geometry) has no instance attributes — it's the same product everywhere.
M_Product: PIPE_CW_50MM (IsBOM=N, M_AttributeSet = BIM_Pipe)
└─ Instance 1: {length_mm: 3200} ← segment in corridor
└─ Instance 2: {length_mm: 4800} ← segment in main run
└─ Instance 3: {length_mm: 1200} ← branch to sprinkler
M_Product: ELBOW_90_50MM (IsBOM=N, M_AttributeSet = BIM_Component)
└─ No instances — fixed geometry, same everywhere
M_Product: SPRINKLER_UPRIGHT_K80 (IsBOM=N, M_AttributeSet = BIM_Component)
└─ No instances — placement varies, product doesn't
The ROUTE verb assembles these into a BOM tree with per-segment instance attributes. TE's 9,345 FP/CW/SP/LPG pipe elements → ~20 abstract products × many instances. Without this, the product table explodes.
The Application Dictionary Heritage¶
Compiere introduced the Application Dictionary (AD) in 2000 — metadata that defines the system itself. ADempiere inherited it. iDempiere perfected it. This project leans on it heavily. If you've administered an iDempiere instance, every pattern below will feel familiar.
iDempiere references: wiki.idempiere.org · Application Dictionary · Manufacturing · Validation Rules · DocAction
AD_Val_Rule — Validation rules as data, not code.
In iDempiere, AD_Val_Rule restricts field values (e.g., "only active Business
Partners"). Here, the same table enforces building codes: sprinkler spacing
= 3000mm, emergency light within 6m of exit, fire door on every corridor. Jurisdiction-scoped — MY/UBBL rules fire for Malaysian buildings, US/IBC for American ones. Exactly like tax rules scoped by
C_Country. → DocValidate.md · DocAction_SRS.md §5
Column Callout — Reactive field logic.
In iDempiere, a Callout fires when a user changes a field value (e.g., selecting
a Business Partner auto-fills the address). Here, DiffVerb + Callout means:
drag a wall in the viewport → cascading consequences fire (room AABB recalculates,
furniture re-validates, MEP re-routes). Same pattern, spatial domain.
→ ProjectOrderBlueprint.md §9
ModelValidator — Event-driven hooks.
iDempiere's ModelValidator fires before/after save, before/after delete. Our
processIt() orchestration follows the identical lifecycle: prepareIt() →
completeIt() → approveIt(). Each discipline routes through DocEvent — the
validation engine discovers applicable rules and fires them. No hardcoded logic.
→ DocAction_SRS.md §1
C_Project — Multi-order grouping.
Any ERP person recognises C_Project instantly: project accounting, milestone
tracking, cross-order budgets. Here, a housing development IS a C_Project.
200 houses = 200 C_Orders under one C_Project. Site layout = C_ProjectLine
per plot. The same entity that manages a manufacturing program manages a
construction site.
→ ProjectOrderBlueprint.md §2
AD_Org — Discipline as organisational unit.
In iDempiere, AD_Org partitions data by business unit. Here, engineering
disciplines partition the BOM validation space. Each discipline is an
organisational concern with its own rules, its own AD_Val_Rule set, its
own validation pass — but sharing the same product catalog.
The Terminal building (TE, 48,428 elements) exercises all active disciplines and proves the partitioning scales to commercial-institutional complexity:
| AD_Org_ID | Code | Name | IFC Classes | TE Elements | Role |
|---|---|---|---|---|---|
| 0 | * | Shared | — | — | Shared infrastructure visible to all trades |
| 1 | ARC | Architecture | IfcWall, IfcDoor, IfcWindow, IfcSlab, IfcPlate, IfcRoof, IfcStair, IfcFurniture, IfcRailing, IfcCovering | 34,724 | Building envelope, internal fit-out, finishes |
| 2 | STR | Structural | IfcColumn, IfcBeam, IfcMember, IfcFooting, IfcElementAssembly | 1,429 | Load-bearing frame, foundations |
| 3 | FP | Fire Protection | IfcFireSuppressionTerminal, IfcAlarm, IfcSensor, IfcController + pipe network | 6,863 | Sprinklers, alarms, risers (NFPA 13) |
| 4 | ELEC | Electrical | IfcLightFixture, IfcElectricAppliance | 1,172 | Lighting, outlets, switches, cable trays |
| 5 | ACMV | HVAC | IfcAirTerminal, IfcDuctSegment, IfcDuctFitting | 1,621 | Ducts, diffusers, AHUs |
| 6 | CW | Cold Water | IfcPipeSegment, IfcPipeFitting, IfcValve, IfcFlowTerminal | 1,431 | Water supply piping |
| 7 | SP | Sanitary/Plumbing | IfcSanitaryTerminal, IfcPipeSegment, IfcPipeFitting | 979 | Waste pipes, fixtures, drainage |
| 8 | LPG | Gas Piping | IfcPipeSegment, IfcPipeFitting, IfcValve | 209 | Gas supply piping, meters |
| 9 | REB | Reinforcement | IfcReinforcingBar | (removed) | Rebar, mesh — generated by Bonsai addon, not construction BOM |
| 10 | MEP | MEP (Generic) | IfcFlowTerminal, IfcFlowSegment, IfcFlowFitting | — | Resolves to FP/ELEC/ACMV/CW/SP/LPG at placement |
| 11 | ROAD | Road | IfcCourse, IfcSurfaceFeature | — | IFC4X3 road infrastructure |
| 12 | GEO | Geotechnical | IfcEarthworksFill | — | Earthworks, cut-and-fill |
| 13 | RAIL | Rail | IfcTrackElement, IfcRail | — | IFC4X3 rail infrastructure |
| 14 | LAND | Landscape | IfcGeographicElement | — | Geographic, landscape elements |
| 15 | SIGN | Signage | IfcSign | — | Signs and signals |
Key design principles:
- Disciplines cut ACROSS the category tree — they don't appear AS levels. Three products in the same room can have three different AD_Orgs (ARC sofa, FP sprinkler, ELEC light).
- MEP (ID 10) is a routing placeholder — the BOM assigns MEP to pipe
elements generically;
BomDropper.resolveDiscipline()resolves to the specific trade (FP/CW/SP/LPG) based onsystem_typeat placement. - REB (ID 9) was removed from the TE pipeline — rebar is generated dynamically by the Bonsai Python addon, not extracted from the IFC construction BOM.
- IDs 11-15 (ROAD, GEO, RAIL, LAND, SIGN) are IFC4X3 infrastructure disciplines — proven on 3 Rosetta Stones (BR, RD, RL).
→ DISC_VALIDATION_DB_SRS.md · TerminalAnalysis.md
AD_ChangeLog — Full provenance and UNDO/REDO.
iDempiere's AD_ChangeLog records every field change on every record: who
changed it, when, old value, new value, which transaction. This is Configure-to-Order's
audit trail — the record that proves a BOM recipe was built correctly.
Our ChangelogDAO applies the identical pattern to spatial operations. Every
PLACE, DELETE, MOVE, and RESIZE is logged with full before/after state. The
schema (bim_changelog table, migration V011) stores:
| Column | Content |
|---|---|
| building_id | Which building |
| entity_type + entity_id | What changed (M_BOM, M_BOM_Line, C_OrderLine) |
| action | SAVE / PLACE / DELETE / MOVE / RESIZE / PROMOTE / UNDO |
| field_name | Which field |
| old_value / new_value | Before and after |
| user_id | Who did it |
| timestamp | When |
This gives us a complete UNDO/REDO stack. Replay the log forward to reconstruct any past state. Replay in reverse to undo. Like Wikipedia's edit history: every BOM state that ever existed can be reconstructed from the changelog, and every change is attributed to a user.
Multi-user conflict detection follows the iDempiere pattern: AD_Session
identifies the editing session, user_id identifies the author. Two users
editing the same BOM line produce two changelog entries — the system detects
the conflict at save time by comparing timestamps.
Current status: ChangelogDAO is fully implemented and tested (TIER1_SRS.md §3).
The bim_changelog table lives in the per-building output database (output.db). Wire protocol supports
changelog (query history) and undoChanges (revert N steps). Not yet
integrated into BOM databases — the audit trail currently covers design
edits in the viewport session.
→ TIER1_SRS.md §3 · ProjectOrderBlueprint.md §10
EntityType (D/U/A) — Dictionary vs User vs Application.
iDempiere protects shipped dictionary records from user modification. Our
X_M_BOM enforces the same: Dictionary records (shipped BOM templates) are
read-only. User records (verb-created BOMs) are fully mutable. GodMode
bypass for migrations only. Three-tier protection at the ORM layer.
→ BBC.md §1 · AUDIT Appendix O.7
AD_PrintFormat — Output selection.
In iDempiere, AD_PrintFormat controls which columns appear on a printed
document. Here, the same concept controls which elements render in the
viewport, which disciplines show in the HTML UI, and which BOM levels
expand in the tree view. Presentation is configuration, not code.
Configure-to-Order — Exception-based ordering. iDempiere's BOM Configurator lets a sales rep exclude optional components or set quantities at order time. Our exception-based ordering (qty=0 removes a subtree, reference class compresses N copies) is the identical pattern applied to buildings. 200 houses, 6 lines of exceptions each. → ProjectOrderBlueprint.md §1
Why This Matters¶
For construction: The industry reportedly loses billions annually to the gap between design tools (geometry) and ERP tools (data). This compiler bridges that gap deterministically. Given a building design, it answers: what do I need to buy, where does each piece go, and can I prove it?
For iDempiere: The manufacturing module, proven over two decades on discrete products, turns out to handle the world's largest product — a building — with minimal extension. This extends the iDempiere architecture to building scale — a validation of the original design that its scope never anticipated.
For the project: Every decision traces to an iDempiere pattern. When we face a design question, we ask: how does iDempiere handle this for manufacturing? The answer is almost always directly applicable:
- Exception-based ordering is iDempiere's Configure-to-Order. 200 houses, 6 lines of exceptions each — not 200 × 1099 elements. The BOM template is the product; the order is just the delta.
- Two kinds of rules work in symbiosis: spatial rules mined from 35 real buildings tell the compiler where things go; regulatory rules (UBBL, NFPA 13, IBC) tell it what the law requires. Spatial proposes, regulatory validates — the Three Concerns in action.
- 4D scheduling is a topological sort of the BOM tree. No Primavera needed. Material logistics follow via M_InOut — iDempiere's goods receipt applied to construction deliveries.
- 5D cost is inherent in the data model. Every M_Product has a price. The cost of a building is
SUM(price × qty)— a query, not a feature. - Design themes are C_Campaign — Bali, Scandinavian, Industrial. Marketing drives variant selection, orthogonal to product category and discipline.
- Site developments are C_Project. 200 houses under one project, each a C_Order on a plot. The same entity that manages a manufacturing program manages a construction site.
The test: 35 real buildings compiled. 48,428 elements in the largest. 6 verification gates. 19 buildings ALL GREEN. Not a prototype — a working compiler with witness verification at every step.
Reading Order¶
After this manifesto:
- BBC.md §1 — the entity mapping table and technical detail
- DATA_MODEL.md — schema, 4-DB architecture
- TestArchitecture.md — verification gates, tamper seal
- ProjectOrderBlueprint.md — what's next (exception ordering, inheritance, C_Project)
- SourceCodeGuide.md — where the code is
For the full academic treatment: BIMERPPaper.md