-- KBX Golden Screen reference schema.
-- In a real modular monolith, schema ownership should stay with the owning module.

create schema if not exists oms;
create schema if not exists catalog;
create schema if not exists inventory;
create schema if not exists audit;
create schema if not exists integration;

create table if not exists oms.customers (
    id uuid primary key,
    code varchar(50) not null unique,
    name varchar(200) not null,
    is_active boolean not null default true
);

create table if not exists catalog.items (
    id uuid primary key,
    code varchar(80) not null unique,
    name varchar(300) not null,
    is_active boolean not null default true
);

create table if not exists inventory.warehouses (
    id uuid primary key,
    code varchar(50) not null unique,
    name varchar(200) not null,
    is_active boolean not null default true
);

create table if not exists oms.orders (
    id uuid primary key,
    order_no varchar(80) not null unique,
    order_date date not null,
    customer_id uuid not null references oms.customers(id),
    warehouse_id uuid not null references inventory.warehouses(id),
    receiver_name varchar(100) not null,
    phone varchar(50) not null,
    postal_code varchar(20),
    address1 varchar(500) not null,
    address2 varchar(500),
    status varchar(30) not null,
    version bigint not null default 1 check (version > 0),
    created_at timestamptz not null default now(),
    created_by varchar(200) not null,
    updated_at timestamptz,
    updated_by varchar(200)
);

create index if not exists ix_orders_order_date on oms.orders(order_date desc);
create index if not exists ix_orders_customer on oms.orders(customer_id, order_date desc);
create index if not exists ix_orders_status on oms.orders(status, order_date desc);

create table if not exists oms.order_lines (
    id uuid primary key,
    order_id uuid not null references oms.orders(id),
    line_no integer not null check (line_no > 0),
    item_id uuid not null references catalog.items(id),
    quantity numeric(18,4) not null check (quantity > 0),
    unit_price numeric(18,4) not null check (unit_price >= 0),
    amount numeric(20,4) not null check (amount >= 0),
    remark varchar(500),
    unique(order_id, line_no)
);

create index if not exists ix_order_lines_item on oms.order_lines(item_id);

create table if not exists audit.entries (
    id uuid primary key,
    aggregate_type varchar(100) not null,
    aggregate_id uuid not null,
    action varchar(100) not null,
    actor varchar(200) not null,
    occurred_at timestamptz not null,
    data jsonb not null default '{}'::jsonb
);
create index if not exists ix_audit_aggregate on audit.entries(aggregate_type, aggregate_id, occurred_at desc);

create table if not exists integration.outbox (
    id uuid primary key,
    event_type varchar(200) not null,
    aggregate_id uuid not null,
    payload jsonb not null,
    occurred_at timestamptz not null,
    status varchar(30) not null,
    processed_at timestamptz,
    retry_count integer not null default 0 check (retry_count >= 0),
    last_error text
);
create index if not exists ix_outbox_pending on integration.outbox(status, occurred_at) where status = 'PENDING';
