create schema if not exists kbx;

-- Operational projection only. OMS/WMS/ERP remain the source of truth.
create table if not exists kbx.work_items (
    id uuid primary key,
    tenant_id varchar(100) not null,
    source_module varchar(20) not null,
    source_type varchar(100) not null,
    source_id varchar(200) not null,
    reference_no varchar(200) not null,
    source_screen_id varchar(100),
    source_version bigint,
    code varchar(120) not null,
    title varchar(240) not null,
    detail text,
    severity varchar(20) not null check (severity in ('info','warning','critical')),
    status varchar(20) not null check (status in ('open','claimed','resolved','ignored')),
    owner_id varchar(200),
    owner_name varchar(200),
    retry_action_key varchar(160),
    allow_manual_resolution boolean not null default false,
    context jsonb not null default '{}'::jsonb,
    occurred_at timestamptz not null,
    due_at timestamptz,
    resolved_at timestamptz,
    resolution_reason text,
    version bigint not null default 1,
    created_at timestamptz not null default now(),
    updated_at timestamptz not null default now(),
    unique(tenant_id, source_module, source_type, source_id, code)
);

create index if not exists ix_work_items_queue
  on kbx.work_items(tenant_id, status, severity, occurred_at desc);
create index if not exists ix_work_items_owner
  on kbx.work_items(tenant_id, owner_id, status, occurred_at desc);
create index if not exists ix_work_items_source
  on kbx.work_items(tenant_id, source_module, source_type, source_id);
create index if not exists ix_work_items_reference
  on kbx.work_items(tenant_id, reference_no);

create table if not exists kbx.work_item_audit (
    id uuid primary key,
    work_item_id uuid not null references kbx.work_items(id) on delete cascade,
    tenant_id varchar(100) not null,
    action varchar(80) not null,
    actor_id varchar(200) not null,
    actor_name varchar(200) not null,
    reason text,
    before_status varchar(20),
    after_status varchar(20),
    occurred_at timestamptz not null default now()
);

create index if not exists ix_work_item_audit_item
  on kbx.work_item_audit(work_item_id, occurred_at desc);

-- Comparison projection. It stores evidence/result, not authoritative inventory/order state.
create table if not exists kbx.reconcile_items (
    id uuid primary key,
    tenant_id varchar(100) not null,
    reconcile_type varchar(120) not null,
    reference_no varchar(200) not null,
    source_label varchar(160) not null,
    target_label varchar(160) not null,
    expected_value varchar(300) not null,
    actual_value varchar(300) not null,
    difference_value varchar(300),
    reason_code varchar(120),
    reason_text text,
    status varchar(20) not null check (status in ('matched','mismatch','pending','resolved')),
    source_id varchar(200),
    target_id varchar(200),
    identity_key varchar(420) not null,
    evidence jsonb not null default '{}'::jsonb,
    occurred_at timestamptz not null,
    resolved_at timestamptz,
    version bigint not null default 1,
    updated_at timestamptz not null default now(),
    unique(tenant_id, reconcile_type, reference_no, identity_key)
);

create index if not exists ix_reconcile_queue
  on kbx.reconcile_items(tenant_id, reconcile_type, status, occurred_at desc);
create index if not exists ix_reconcile_reference
  on kbx.reconcile_items(tenant_id, reference_no);
