﻿{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://customshive.local/schemas/canonical/declaration.schema.json",
  "title": "CanonicalDeclaration",
  "description": "Unified ingestion contract for all customs regimes (IM/EX/T1/T2). Send via POST /api/declarations or publish to the canonical ServiceBus queue. Property names are case-insensitive; snake_case is the recommended format. Unknown fields are accepted and ignored.",
  "type": "object",
  "required": ["declaration_type"],
  "properties": {
    "declaration_type": {
      "type": "string",
      "enum": ["IM", "EX", "T1", "T2"],
      "description": "Customs regime. Determines which adapter processes the dossier."
    },
    "regime": {
      "type": ["string", "null"],
      "description": "Regime sub-type (e.g. H1, H2, B1). Derived from declaration_type when omitted."
    },
    "ucr": {
      "type": ["string", "null"],
      "description": "Caller-supplied house bill / UCR reference. Auto-generated when omitted."
    },
    "client_code": {
      "type": ["string", "null"],
      "description": "Internal Client.Code shortcut. Takes precedence over EORI party lookup when set."
    },
    "auto_dispatch": {
      "type": ["boolean", "null"],
      "description": "Transit only (T1/T2): file this declaration automatically, without a declarant reviewing it. Absent means no automatic dispatch. Present on any other declaration type is rejected."
    },
    "security_code": {
      "type": ["integer", "null"],
      "description": "Safety and security indicator: 0 none, 1 ENS+EXS, 2 ENS, 3 EXS. Export and transit. Absent keeps the app-level value."
    },
    "binding_itinerary": {
      "type": ["boolean", "null"],
      "description": "Transit only: whether the itinerary is binding. Absent means 0."
    },
    "limit_date": {
      "type": ["string", "null"],
      "description": "Transit only (yyyy-MM-dd): the date by which the goods must be presented at the office of destination. Absent means eight days out."
    },
    "parties": { "$ref": "#/$defs/CanonicalParties" },
    "shipment": { "$ref": "#/$defs/CanonicalShipment" },
    "transport": { "$ref": "#/$defs/CanonicalTransport" },
    "customs_offices": { "$ref": "#/$defs/CanonicalOffices" },
    "authorised_location_of_goods": { "$ref": "#/$defs/CanonicalLocationOfGoods" },
    "loading_location": { "$ref": "#/$defs/CanonicalLoadingLocation" },
    "totals": { "$ref": "#/$defs/CanonicalTotals" },
    "costs": {
      "type": ["array", "null"],
      "items": { "$ref": "#/$defs/CanonicalCost" },
      "description": "Header-level coded costs (e.g. AK air/insurance, CA transport) to apportion over items."
    },
    "supporting_documents": {
      "type": ["array", "null"],
      "items": { "$ref": "#/$defs/CanonicalDocument" },
      "description": "Documents produced for the declaration as a whole (CL213 and the national codes). Named for the element it becomes, as the goods item's lists are."
    },
    "additional_references": {
      "type": ["array", "null"],
      "items": { "$ref": "#/$defs/CanonicalDocument" },
      "description": "Additional references for the declaration (CL380 Y-codes). The reference is optional on most."
    },
    "transport_documents": {
      "type": ["array", "null"],
      "items": { "$ref": "#/$defs/CanonicalDocument" },
      "description": "Transport contract documents (CL754), e.g. N730 with the CMR number. The import declaration files the first."
    },
    "authorisations": {
      "type": ["array", "null"],
      "items": { "$ref": "#/$defs/CanonicalAuthorisation" }
    },
    "guarantees": {
      "type": ["array", "null"],
      "items": { "$ref": "#/$defs/CanonicalGuarantee" }
    },
    "attachments": {
      "type": ["array", "null"],
      "items": { "$ref": "#/$defs/CanonicalAttachment" },
      "description": "Source documents embedded in the message (e.g. the pro-forma invoice PDF). Saved to the dossier's document slots on ingest; no AI extraction is triggered."
    },
    "house_consignments": {
      "type": ["array", "null"],
      "items": { "$ref": "#/$defs/CanonicalHouseConsignment" },
      "description": "T2 groupage only. Each consignment groups one or more goods_items via house_consignment_sequence."
    },
    "goods_items": {
      "type": "array",
      "items": { "$ref": "#/$defs/CanonicalGoodsItem" },
      "default": []
    }
  },

  "$defs": {
    "CanonicalParties": {
      "type": "object",
      "properties": {
        "declarant":          { "$ref": "#/$defs/CanonicalParty" },
        "representative":     { "$ref": "#/$defs/CanonicalParty" },
        "exporter":           { "$ref": "#/$defs/CanonicalParty" },
        "importer":           { "$ref": "#/$defs/CanonicalParty" },
        "consignee":          { "$ref": "#/$defs/CanonicalParty", "description": "Top-level consignee (simple declarations). Per-HC consignees go inside house_consignments." },
        "consignor":          { "$ref": "#/$defs/CanonicalParty", "description": "T1/T2 — typically the forwarder." },
        "transit_principal":  { "$ref": "#/$defs/CanonicalParty", "description": "T1/T2 — holder of the transit procedure; often the same as consignor." },
        "buyer":              { "$ref": "#/$defs/CanonicalParty" },
        "seller":             { "$ref": "#/$defs/CanonicalParty" }
      }
    },

    "CanonicalParty": {
      "type": "object",
      "properties": {
        "eori":             { "type": ["string", "null"] },
        "vat_number":       { "type": ["string", "null"] },
        "name":             { "type": ["string", "null"] },
        "street_and_number":{ "type": ["string", "null"] },
        "postcode":         { "type": ["string", "null"] },
        "city":             { "type": ["string", "null"] },
        "country":          { "type": ["string", "null"], "description": "ISO 3166-1 alpha-2 country code." },
        "contact_name":     { "type": ["string", "null"] },
        "contact_phone":    { "type": ["string", "null"] },
        "contact_email":    { "type": ["string", "null"] }
      }
    },

    "CanonicalShipment": {
      "type": "object",
      "properties": {
        "invoice_number":       { "type": ["string", "null"] },
        "invoice_date":         { "type": ["string", "null"], "description": "ISO 8601 date string, e.g. 2025-03-15." },
        "currency":             { "type": ["string", "null"], "description": "ISO 4217 currency code, e.g. EUR." },
        "total_invoice_amount": { "type": ["number", "null"] },
        "exchange_rate_to_eur": { "type": ["number", "null"] },
        "incoterm":             { "type": ["string", "null"], "description": "Incoterm code, e.g. DAP." },
        "incoterm_location":    { "type": ["string", "null"] },
        "incoterm_country":     { "type": ["string", "null"], "description": "ISO 3166-1 alpha-2 country of the incoterm place." },
        "country_of_dispatch":    { "type": ["string", "null"], "description": "ISO 3166-1 alpha-2." },
        "country_of_destination": { "type": ["string", "null"], "description": "ISO 3166-1 alpha-2." },
        "nature_of_transaction":  { "type": ["integer", "null"], "description": "Nature of transaction code (UCC DE 8/5), e.g. 11 = outright sale." },
        "region_of_dispatch":     { "type": ["string", "null"], "description": "Region within the country of dispatch (BE: 1/2/3, FR: department). Filed as originRegionCode on every export goods item." },
        "transport_charges_method_of_payment": { "type": ["string", "null"], "description": "Transport charges method of payment (UCC DE 4/2), e.g. H." }
      }
    },

    "CanonicalTransport": {
      "type": "object",
      "properties": {
        "mode_at_border":              { "type": ["integer", "null"], "description": "EU transport mode code at border crossing." },
        "border_means_id":             { "type": ["string", "null"], "description": "Registration number / ID of the means at border." },
        "border_means_nationality":    { "type": ["string", "null"], "description": "ISO 3166-1 alpha-2 country of registration." },
        "inland_means_id":             { "type": ["string", "null"] },
        "inland_means_nationality":    { "type": ["string", "null"] },
        "departure_means_id":          { "type": ["string", "null"], "description": "Vehicle plate used for T2 departure transport means." },
        "departure_means_nationality": { "type": ["string", "null"] },
        "departure_means_mode_code":   { "type": ["integer", "null"] },
        "departure_means_type_code":   { "type": ["string", "null"] },
        "route": {
          "type": ["array", "null"],
          "items": { "type": "string" },
          "description": "Ordered list of ISO 3166-1 alpha-2 transit country codes."
        }
      }
    },

    "CanonicalOffices": {
      "type": "object",
      "properties": {
        "departure":   { "type": ["string", "null"], "description": "Office of departure (T1/T2)." },
        "export":      { "type": ["string", "null"], "description": "Customs office of export (EX)." },
        "exit":        { "type": ["string", "null"], "description": "Office of exit." },
        "import":      { "type": ["string", "null"], "description": "Office of import (IM)." },
        "destination": { "type": ["string", "null"], "description": "Office of destination (T1/T2)." },
        "transit":     { "type": ["string", "null"], "description": "Office of transit (T1/T2 en-route)." }
      }
    },

    "CanonicalLocationOfGoods": {
      "type": "object",
      "properties": {
        "type_of_location":           { "type": ["string", "null"] },
        "qualifier_of_identification": { "type": ["string", "null"] },
        "un_locode":                  { "type": ["string", "null"] },
        "location_code":              { "type": ["string", "null"], "description": "National goods-location code (e.g. Belgian BECUIZG000015)." },
        "authorisation_number":       { "type": ["string", "null"] },
        "street_and_number":          { "type": ["string", "null"], "description": "Free-address form — for senders that only know a street address; the declarant completes the coded identification in the review UI." },
        "postcode":                   { "type": ["string", "null"] },
        "city":                       { "type": ["string", "null"] },
        "country":                    { "type": ["string", "null"], "description": "ISO 3166-1 alpha-2." }
      }
    },

    "CanonicalLoadingLocation": {
      "type": "object",
      "properties": {
        "loading_place":                { "type": ["string", "null"] },
        "loading_place_code":           { "type": ["string", "null"] },
        "loading_place_additional_code":{ "type": ["string", "null"] }
      }
    },

    "CanonicalTotals": {
      "type": "object",
      "properties": {
        "gross_mass":     { "type": ["number", "null"] },
        "net_mass":       { "type": ["number", "null"] },
        "packages":       { "type": ["integer", "null"] },
        "invoice_amount": { "type": ["number", "null"] }
      }
    },

    "CanonicalDocument": {
      "type": "object",
      "properties": {
        "sequence_number": { "type": ["integer", "null"] },
        "type":            { "type": ["string", "null"] },
        "reference":       { "type": ["string", "null"] },
        "date":            { "type": ["string", "null"] }
      }
    },

    "CanonicalAttachment": {
      "type": "object",
      "properties": {
        "file_name":    { "type": ["string", "null"] },
        "content_type": { "type": ["string", "null"], "description": "MIME type, e.g. application/pdf." },
        "kind":         { "type": ["string", "null"], "description": "invoice (default) | packing_list | other." },
        "data":         { "type": ["string", "null"], "description": "Base64-encoded file content." }
      }
    },

    "CanonicalCost": {
      "type": "object",
      "properties": {
        "code":     { "type": ["string", "null"], "description": "Cost code, e.g. AK, CA, FA." },
        "amount":   { "type": ["number", "null"] },
        "currency": { "type": ["string", "null"] }
      }
    },

    "CanonicalAuthorisation": {
      "type": "object",
      "properties": {
        "type":      { "type": ["string", "null"] },
        "reference": { "type": ["string", "null"] }
      }
    },

    "CanonicalGuarantee": {
      "type": "object",
      "required": ["sequence_number"],
      "properties": {
        "sequence_number":  { "type": "integer" },
        "type":             { "type": ["string", "null"] },
        "grn":              { "type": ["string", "null"], "description": "Guarantee Reference Number." },
        "access_code":      { "type": ["string", "null"] },
        "amount":           { "type": ["number", "null"] },
        "currency":         { "type": ["string", "null"] },
        "pot_customs_debt": { "type": ["string", "null"] }
      }
    },

    "CanonicalHouseConsignment": {
      "type": "object",
      "required": ["sequence_number"],
      "description": "One consignment within a T2 groupage. Sequence numbers are Navision/Qargo internal IDs — not necessarily sequential from 1.",
      "properties": {
        "sequence_number":      { "type": "integer", "description": "Navision/Qargo shipment line ID. Preserved as-is." },
        "gross_mass":           { "type": ["number", "null"] },
        "reference_number_ucr": { "type": ["string", "null"] },
        "consignee":            { "$ref": "#/$defs/CanonicalParty" }
      }
    },

    "CanonicalGoodsItem": {
      "type": "object",
      "required": ["sequence_number"],
      "properties": {
        "sequence_number":              { "type": "integer" },
        "declaration_goods_item_number":{ "type": ["integer", "null"] },
        "description":                  { "type": ["string", "null"] },
        "commodity_code":               { "type": ["string", "null"], "description": "Combined nomenclature code (8 or 10 digits)." },
        "country_of_origin":            { "type": ["string", "null"], "description": "ISO 3166-1 alpha-2." },
        "preferential":                 { "type": ["boolean", "null"], "description": "Preferential origin claim for this item (communityPreference 400 vs 100)." },
        "invoice_number":               { "type": ["string", "null"], "description": "Commercial invoice covering this item, when it differs per line." },
        "requested_procedure":          { "type": ["string", "null"], "description": "Requested procedure code (UCC DE 1/10 first part), e.g. 40, 31." },
        "previous_procedure":           { "type": ["string", "null"], "description": "Previous procedure code (UCC DE 1/10 second part), e.g. 00, 51." },
        "gross_mass":                   { "type": ["number", "null"] },
        "net_mass":                     { "type": ["number", "null"] },
        "statistical_value":            { "type": ["number", "null"] },
        "house_consignment_sequence":   { "type": ["integer", "null"], "description": "Links to CanonicalHouseConsignment.sequence_number. Null for simple (non-groupage) declarations." },
        "packages": {
          "type": ["array", "null"],
          "items": { "$ref": "#/$defs/CanonicalPackage" }
        },
        "containers": {
          "type": ["array", "null"],
          "items": { "$ref": "#/$defs/CanonicalContainer" }
        },
        "additional_references": {
          "type": ["array", "null"],
          "items": { "$ref": "#/$defs/CanonicalDocument" }
        },
        "previous_documents": {
          "type": ["array", "null"],
          "items": { "$ref": "#/$defs/CanonicalDocument" }
        },
        "supporting_documents": {
          "type": ["array", "null"],
          "items": { "$ref": "#/$defs/CanonicalDocument" }
        },
        "unit_price":             { "type": ["number", "null"] },
        "total_price":            { "type": ["number", "null"] },
        "extra_cost":             { "type": ["number", "null"] },
        "supplementary_unit":     { "type": ["string", "null"] },
        "supplementary_quantity": { "type": ["number", "null"] },
        "currency":               { "type": ["string", "null"], "description": "Currency for this line when it differs from the shipment's. Absent = the shipment's." },
        "undg_numbers": {
          "type": ["array", "null"],
          "items": { "type": "string" },
          "description": "UN dangerous-goods numbers (CL101), e.g. [\"1263\"]. Export and transit only."
        }
      }
    },

    "CanonicalPackage": {
      "type": "object",
      "properties": {
        "type":           { "type": ["string", "null"], "description": "Package type code (e.g. CT, BX, PK)." },
        "quantity":       { "type": ["integer", "null"] },
        "shipping_marks": { "type": ["string", "null"] }
      }
    },

    "CanonicalContainer": {
      "type": "object",
      "properties": {
        "container_number": { "type": ["string", "null"] },
        "seals": {
          "type": ["array", "null"],
          "items": { "type": "string" },
          "description": "Seal numbers attached to this container."
        }
      }
    }
  }
}
