| invoice_item_id | string, UUID | ✅ Yes | unique; generated by gen_random_uuid() at creation | — | Public stable identifier for this invoice line item. Used in all API surfaces and references. |
| line_id | string | ✅ Yes | max length 50; table-wide composite-unique with invoice (no two lines — active or deleted — on the same invoice share a line_id) | — | Provider-assigned or pipeline-generated identifier for this line within the parent invoice. Used to deduplicate re-ingested lines. The unique constraint is not partial: a soft-deleted line_id blocks reuse on the same invoice until the row is hard-deleted. |
| sku | string | ⚪ No | max length 100 | — | Stock-keeping unit or product code from the originating system (ERP, e-commerce, MCP connector). |
| name | string | ✅ Yes | max length 255 | — | Human-readable label for the line item. Mapped directly from the originating document’s line description. |
| description | string | ⚪ No | max length 1000 | — | Extended free-text description of the line item, supplying additional context beyond the name. |
| unit_price | decimal(15,2) | ✅ Yes | CHECK unit_price >= 0 | — | Price per unit in the invoice’s currency, before any discount or tax. Always non-negative. |
| currency | string, enum (CurrencyCodeEnum) | ✅ Yes | PostgreSQL native enum currency_code_enum | ISO 4217 three-letter codes, e.g. USD, EUR, GBP, JPY, CHF, CAD, AUD, … | Currency of unit_price, line_total, tax_amount, discount, and quantity-derived amounts on this line. |
| unit | string, enum (InvoiceLineUnitEnum) | ⚪ No | PostgreSQL native enum invoice_line_unit_enum; nullable | EA, PC, SET, PR, DZ, C62, MIL, KT, PK, BX, HUR, MIN, SEC, DAY, WEE, MON, ANN, QT, KGM, GRM, TNE, LBR, ONZ, CWT, STN, LTN, MTR, CMT, MMT, KMT, INH, FOT, YRD, SMI, MTK, CMK, INK, FTK, YDK, ACR, HAR, LTR, MLT, MTQ, CMQ, INQ, FTQ, YDQ, GAL, PT, BYT, KBY, MBY, GBY, TBY, BIT, KBI, MBI, GBI, KWH, MWH, WHR, KWT, MWT, BTU, CAL, CEL, FAH, KEL, BAR, PSI, PAL, SRV, LIC, USR, SES, TXN, REQ, PAG, VIS, CLI, IMP, PTC, BPS, SHR, LOT, PNT, TOL, MOL, PPM, PPB, PH, UNT, OTH, NA | UN/CEFACT unit-of-measure code for the quantity on this line. Covers physical quantities, time, data, and service units. |
| quantity | decimal(15,2) | ⚪ No | CHECK quantity >= 0; nullable | — | Number of units. Stored as decimal(15,2) to accommodate fractional service quantities. Populated by the pipeline ingestion from connector data. |
| min_quantity | decimal(15,2) | ⚪ No | CHECK min_quantity >= 0; nullable | — | Minimum purchasable quantity for this line, used when the invoice carries tiered or min/max quantity brackets. |
| max_quantity | decimal(15,2) | ⚪ No | CHECK max_quantity >= min_quantity; nullable | — | Maximum purchasable quantity for this line. Must be >= min_quantity when both are present. |
| line_total | decimal(15,2) | ⚪ No | CHECK line_total >= 0; nullable | — | Total amount for this line (unit_price × quantity − discount), excl. tax. Populated by the pipeline; may differ from a client-computed product when rounding rules apply. |
| discount | decimal(15,2) | ⚪ No | CHECK discount >= 0; nullable; default 0 | — | Discount amount applied to this line, expressed as an absolute monetary value in the line’s currency. Always non-negative. |
| tax_rate | decimal(5,2) | ⚪ No | CHECK tax_rate >= 0 AND tax_rate <= 100; nullable | 0.00 – 100.00 | Percentage rate of tax applied to this line, e.g. 20.00 for 20% VAT. Distinct from the applied_tax_rate relationship which links to the well-catalog tax rate entry. |
| tax_category | string, enum (TaxCategoryEnum) | ⚪ No | PostgreSQL native enum tax_category_enum; nullable | standard, reduced, super_reduced, zero_rated, exempt, reverse_charge, out_of_scope, government, municipal, regulatory, statutory, administrative, medical_exempt, medical_reduced, medical_standard, pharmaceutical, hospital, dental, veterinary, education_exempt, education_reduced, books, cultural, research, library, food_basic, food_standard, food_luxury, beverages_non_alcoholic, beverages_alcoholic, restaurant, catering, property_residential, property_commercial, construction_new, construction_renovation, land, property_management, transport_public, transport_passenger, transport_freight, vehicle_sales, vehicle_parts, fuel, parking, utilities_domestic, utilities_commercial, water, sewage, waste_management, telecommunications, energy_renewable, financial_exempt, insurance_exempt, investment, banking, credit, foreign_exchange, software_license, software_saas, digital_services, cloud_computing, data_processing, telecommunications_digital, electronic_delivery, manufacturing, industrial_equipment, raw_materials, chemicals, mining, agriculture, forestry, entertainment, sports, gambling, tourism, hospitality, recreation, export, import, intrastat, customs, free_trade_zone, diplomatic, legal_services, accounting, consulting, professional, notary, mixed_rate, threshold_based, seasonal, promotional, margin_scheme, reverse_auction, unknown, pending, other, not_applicable | Semantic classification of the tax treatment on this line, aligned to EU/global tax-code taxonomy. |
| tax_scheme | string, enum (TaxSchemeEnum) | ⚪ No | PostgreSQL native enum tax_scheme_enum; nullable | VAT, EU_VAT, UK_VAT, MOSS_VAT, OSS_VAT, IOSS_VAT, GST, AU_GST, CA_GST, CA_HST, CA_PST, CA_QST, IN_GST, IN_CGST, IN_SGST, IN_IGST, IN_UTGST, SG_GST, MY_GST, MY_SST, NZ_GST, SALES_TAX, US_STATE_TAX, US_LOCAL_TAX, US_USE_TAX, CA_RETAIL_TAX, NY_SALES_TAX, TX_SALES_TAX, JCT, KR_VAT, CN_VAT, RU_VAT, BR_ICMS, BR_IPI, BR_PIS_COFINS, MX_IVA, AR_IVA, CL_IVA, EXCISE_TAX, LUXURY_TAX, SIN_TAX, CARBON_TAX, FUEL_TAX, TOBACCO_TAX, ALCOHOL_TAX, DIGITAL_TAX, CORPORATE_TAX, WITHHOLDING_TAX, BRANCH_PROFITS_TAX, TURNOVER_TAX, GROSS_RECEIPTS_TAX, CUSTOMS_DUTY, IMPORT_DUTY, EXPORT_DUTY, ANTI_DUMPING_DUTY, COUNTERVAILING_DUTY, TARIFF, PROPERTY_TAX, TRANSFER_TAX, STAMP_DUTY, INHERITANCE_TAX, GIFT_TAX, WEALTH_TAX, PAYROLL_TAX, SOCIAL_SECURITY_TAX, UNEMPLOYMENT_TAX, DISABILITY_TAX, MEDICARE_TAX, MUNICIPAL_TAX, CITY_TAX, COUNTY_TAX, DISTRICT_TAX, TOURIST_TAX, OCCUPANCY_TAX, FINANCIAL_TRANSACTION_TAX, BANK_TAX, INSURANCE_PREMIUM_TAX, TELECOM_TAX, UTILITY_TAX, AVIATION_TAX, SHIPPING_TAX, ENVIRONMENTAL_TAX, PLASTIC_TAX, PACKAGING_TAX, WASTE_TAX, CONGESTION_TAX, OTHER, MIXED, UNKNOWN, NONE, PENDING | The tax framework under which the line is taxed, e.g. EU_VAT, GST, US_STATE_TAX. Covers 90+ global tax schemes. |
| tax_amount | decimal(15,2) | ⚪ No | CHECK tax_amount >= 0; nullable | — | Absolute tax amount for this line in the line’s currency, derived from unit_price × quantity × tax_rate / 100. |
| accounting_unit_price | decimal(15,2) | ⚪ No | nullable | — | Unit price converted to the workspace’s functional accounting currency. Set by the FX-matching pipeline when the invoice currency differs from the workspace currency. |
| accounting_line_total | decimal(15,2) | ⚪ No | nullable | — | Line total converted to the workspace’s functional accounting currency. Parallel to accounting_unit_price for full multi-currency double-entry support. |
| period_start | timestamp | ⚪ No | nullable | — | Start of the service period covered by this line item. Used for subscription, retainer, and recurring-service invoices. |
| period_end | timestamp | ⚪ No | nullable | — | End of the service period covered by this line item. Paired with period_start for accrual accounting period allocation. |
| accounting_classification | jsonb | ⚪ No | nullable; partial functional index on (accounting_classification->>‘status’) WHERE deleted_at IS NULL (idx_invoice_items_accounting_classification_status — defined in Migration20260525101000 only, not expressible via MikroORM decorators) | { status: ‘ready’, wellCoaVersion: string, intent: WellPostingIntent, rawFacts: InvoiceItemAccountingLLMFacts } | { status: ‘needs_review’, wellCoaVersion: string, reason: InvoiceItemAccountingReviewReason, rawFacts?: …, details?: string } | AI-produced Well-taxonomy accounting classification for this line. Written by the journal-entry draft builder. status=‘ready’ means a valid WellPostingIntent was resolved and the line can be posted to the ledger. status=‘needs_review’ carries a reason code (missing_accounting_facts, llm_requested_review, unknown_semantic_role, unsupported_invoice_item_posting_kind, unsupported_invoice_item_transfer_role, invalid_accounting_qualifier, posting_intent_halt) and blocks automatic posting. |
| created_at | timestamp, 🔒 system | ✅ Yes | set once on insert via onCreate lifecycle hook | — | ISO 8601 timestamp recording when the invoice item row was first persisted. |
| updated_at | timestamp, 🔒 system | ⚪ No | set on insert and refreshed on every update via onCreate/onUpdate lifecycle hooks | — | ISO 8601 timestamp of the most recent write to this row. |
| deleted_at | timestamp | ⚪ No | nullable; soft-delete sentinel; partial indexes exclude rows where deleted_at IS NOT NULL | — | When set, marks this line as logically deleted. All active-record queries filter deleted_at IS NULL. Cleared only by an explicit restore operation. |