-- Accrual A/P guard: link a bank transaction to the bill it settles, and enforce
-- that a bill-linked payment never carries an expense category.
--
-- Under accrual, a vendor expense is recognized once — when the bill is entered
-- (Dr Expense / Cr A/P). Paying the bill must only relieve the liability
-- (Dr A/P / Cr Bank) via accounting.post_transaction_gl's vendor → A/P branch,
-- which only runs when coa_account_id IS NULL. So any transaction that settles a
-- bill must have coa_account_id NULL; otherwise it re-recognizes the expense.

alter table accounting.transactions
  add column if not exists bill_id uuid references accounting.bills(id) on delete set null;

create index if not exists idx_transactions_bill_id
  on accounting.transactions(bill_id) where bill_id is not null;

-- Invariant: a transaction linked to a bill posts against Accounts Payable, never
-- an expense account. This makes the accrual rule enforceable, not just convention.
alter table accounting.transactions
  drop constraint if exists chk_bill_payment_no_coa;
alter table accounting.transactions
  add constraint chk_bill_payment_no_coa
  check (bill_id is null or coa_account_id is null);
