{
  "$defs": {
    "AccountingJournalSource": {
      "description": "Where a journal entry originated.",
      "oneOf": [
        {
          "const": "manual",
          "description": "Manual entry by a human accountant.",
          "type": "string"
        },
        {
          "const": "bank_import",
          "description": "Imported from a bank feed (HBCI / EBICS / Stripe payouts / etc.).",
          "type": "string"
        },
        {
          "const": "invoice_issued",
          "description": "Generated by an AR invoice issuance.",
          "type": "string"
        },
        {
          "const": "invoice_received",
          "description": "Generated by an AP invoice receipt.",
          "type": "string"
        },
        {
          "const": "payroll",
          "description": "Generated by a payroll run.",
          "type": "string"
        },
        {
          "const": "depreciation",
          "description": "Generated by the depreciation schedule of a FixedAsset.",
          "type": "string"
        },
        {
          "const": "accrual_release",
          "description": "Periodic release of an accrual schedule (deferred revenue, prepaid\nexpense).",
          "type": "string"
        },
        {
          "const": "reversal",
          "description": "A reversal of a prior entry. Pair with `reversal_of`.",
          "type": "string"
        },
        {
          "const": "closing",
          "description": "Period-end closing entry (year-end roll to retained earnings).",
          "type": "string"
        },
        {
          "const": "opening",
          "description": "Opening balance entry (CoA setup, year-start balance).",
          "type": "string"
        },
        {
          "const": "adjustment",
          "description": "Period-end adjusting entry (accrual, prepaid amortisation,\ndepreciation true-up).",
          "type": "string"
        },
        {
          "const": "fx_revaluation",
          "description": "IAS 21 / ASC 830 monthly FX revaluation entry.",
          "type": "string"
        }
      ]
    },
    "Dimension": {
      "description": "Per-line dimensional tags. Drive cross-pillar reporting (segment P&L,\nproduct P&L, project burndown, customer / vendor sub-ledger).",
      "properties": {
        "cost_center": {
          "anyOf": [
            {
              "$ref": "#/$defs/PathRef"
            },
            {
              "type": "null"
            }
          ]
        },
        "customer": {
          "anyOf": [
            {
              "$ref": "#/$defs/PathRef"
            },
            {
              "type": "null"
            }
          ],
          "description": "PathRef into BDR 0078 Customer or its underlying Party."
        },
        "product": {
          "anyOf": [
            {
              "$ref": "#/$defs/PathRef"
            },
            {
              "type": "null"
            }
          ],
          "description": "PathRef into BDR 0065 plural Product."
        },
        "project": {
          "anyOf": [
            {
              "$ref": "#/$defs/PathRef"
            },
            {
              "type": "null"
            }
          ]
        },
        "segment": {
          "anyOf": [
            {
              "$ref": "#/$defs/PathRef"
            },
            {
              "type": "null"
            }
          ],
          "description": "PathRef into BDR 0065 OperatingSegment."
        },
        "vendor": {
          "anyOf": [
            {
              "$ref": "#/$defs/PathRef"
            },
            {
              "type": "null"
            }
          ],
          "description": "PathRef into BDR 0078 Vendor or its underlying Party."
        }
      },
      "type": "object"
    },
    "IsoCurrency": {
      "description": "ISO 4217 currency code.",
      "pattern": "^[A-Z]{3}$",
      "type": "string"
    },
    "IsoDate": {
      "description": "ISO 8601 date (YYYY-MM-DD).",
      "format": "date",
      "type": "string"
    },
    "JournalLine": {
      "description": "One line of a journal entry.\n\nInvariant (L4-JE-2 from BDR 0066): exactly one of `debit` or `credit`\nis `Some(_)`. The validator rejects entries that violate this.",
      "properties": {
        "account": {
          "$ref": "#/$defs/PathRef",
          "description": "PathRef into a CoA account record. By convention this is a fully-\nqualified `financials/chart-of-accounts/<entity>-<basis>#<code>`\nreference; the validator resolves `#<code>` against the CoA\n`accounts[]`."
        },
        "credit": {
          "description": "Credit amount in the entry currency. Mutually exclusive with\n`debit`.",
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "debit": {
          "description": "Debit amount in the entry currency. Mutually exclusive with\n`credit`. Stored as a positive float; negative values are\nrejected by the validator.",
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "description": {
          "description": "Line-level description; overrides entry-level description for\nstatement rendering.",
          "type": [
            "string",
            "null"
          ]
        },
        "dimension": {
          "anyOf": [
            {
              "$ref": "#/$defs/Dimension"
            },
            {
              "type": "null"
            }
          ],
          "description": "Per-line dimensional tags."
        },
        "fx_rate": {
          "description": "FX rate used to convert to the entry currency. Sourced from\n`FxRateTable` (BDR 0068) at the entry's effective date.",
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "original_amount": {
          "description": "Amount in the original currency.",
          "format": "double",
          "type": [
            "number",
            "null"
          ]
        },
        "original_currency": {
          "anyOf": [
            {
              "$ref": "#/$defs/IsoCurrency"
            },
            {
              "type": "null"
            }
          ],
          "description": "Optional original currency when the underlying transaction was\nnot in the entry currency."
        }
      },
      "required": [
        "account"
      ],
      "type": "object"
    },
    "JournalStatus": {
      "description": "Lifecycle status of a journal entry.",
      "oneOf": [
        {
          "const": "draft",
          "description": "Pre-post — editable.",
          "type": "string"
        },
        {
          "const": "posted",
          "description": "Posted — immutable per HGB §239 / GoBD. Corrections become\nreversing entries.",
          "type": "string"
        },
        {
          "const": "reversed",
          "description": "Reversed — a sibling `Reversal` entry has been posted that flips\nevery line.",
          "type": "string"
        }
      ]
    },
    "PathRef": {
      "description": "Path-based cross-reference relative to .corpospec/ root.\nPattern: `^[a-z0-9_-]+(/[a-z0-9_.-]+)+$`",
      "pattern": "^[a-z0-9_-]+(/[a-z0-9_.-]+)+$",
      "type": "string"
    }
  },
  "$id": "https://corpospec.com/schemas/v0.16.0/journal.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false,
  "description": "The atomic posting unit.\n\nFile layout: `.corpospec/financials/journal/<YYYY>/<MM>/<entity>/<id>.yaml`.\nOne file per entry; never overwrite once `status: posted`.",
  "properties": {
    "approved_by": {
      "anyOf": [
        {
          "$ref": "#/$defs/PathRef"
        },
        {
          "type": "null"
        }
      ],
      "description": "PathRef into `people/**` for approver. Required when entry amount\nexceeds policy threshold (configured per entity)."
    },
    "content_hash": {
      "description": "SHA-256 of canonicalised payload (excluding this field). The\nvalidator recomputes on every read for tamper detection.",
      "type": "string"
    },
    "currency": {
      "$ref": "#/$defs/IsoCurrency",
      "description": "Default currency of the entry; per-line `original_currency` may\noverride."
    },
    "description": {
      "description": "One-line summary; appears on the statement.",
      "type": "string"
    },
    "effective_date": {
      "$ref": "#/$defs/IsoDate",
      "description": "Accounting effective date (drives period assignment)."
    },
    "entity": {
      "$ref": "#/$defs/PathRef",
      "description": "The bookkeeping entity."
    },
    "git_commit_sha": {
      "description": "Git commit SHA recorded by a pre-commit hook.",
      "type": [
        "string",
        "null"
      ]
    },
    "id": {
      "$ref": "#/$defs/PathRef",
      "description": "PathRef identifier, conventionally\n`financials/journal/<entity>/<YYYY-MM-DD>-<seq>`."
    },
    "lines": {
      "description": "Lines. Must be ≥2 for a valid double-entry posting.",
      "items": {
        "$ref": "#/$defs/JournalLine"
      },
      "type": "array"
    },
    "note": {
      "description": "Free-form internal commentary; visible to bookkeeper only.",
      "type": [
        "string",
        "null"
      ]
    },
    "period": {
      "$ref": "#/$defs/PathRef",
      "description": "PathRef into the `AccountingPeriod` this entry posts to."
    },
    "posted_at": {
      "$ref": "#/$defs/IsoDate",
      "description": "RFC 3339 instant the entry was recorded."
    },
    "posted_by": {
      "$ref": "#/$defs/PathRef",
      "description": "PathRef into `people/**` for who posted."
    },
    "references": {
      "description": "PathRefs into source documents (invoices, contracts, bank lines).",
      "items": {
        "$ref": "#/$defs/PathRef"
      },
      "type": "array"
    },
    "reversal_of": {
      "anyOf": [
        {
          "$ref": "#/$defs/PathRef"
        },
        {
          "type": "null"
        }
      ],
      "description": "When this entry reverses a prior one."
    },
    "source": {
      "$ref": "#/$defs/AccountingJournalSource",
      "description": "Source classification."
    },
    "status": {
      "$ref": "#/$defs/JournalStatus",
      "description": "Lifecycle status."
    }
  },
  "required": [
    "id",
    "entity",
    "posted_at",
    "effective_date",
    "period",
    "currency",
    "source",
    "description",
    "lines",
    "posted_by",
    "status",
    "content_hash"
  ],
  "title": "AccountingJournalEntry",
  "type": "object",
  "x-corpospec-pillar": "financials"
}