001-orders-sales-init.xml 4.73 KB
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
                                       https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.27.xsd">

    <!--
        pbc-orders-sales initial schema (P5.5).

        Owns: orders_sales__sales_order, orders_sales__sales_order_line.

        vibe_erp is single-tenant per instance — no tenant_id columns,
        no Row-Level Security policies.

        NEITHER table has a foreign key to:
          • partners__partner (cross-PBC reference enforced by PartnersApi)
          • catalog__item     (cross-PBC reference enforced by CatalogApi)
        A database FK across PBCs would couple their schemas at the
        storage level, defeating the bounded-context rule.

        The line table HAS a foreign key to its parent order because
        the relationship is intra-PBC and the framework's "PBCs own
        their own tables" guarantee makes the FK safe.

        Conventions enforced for every business table in vibe_erp:
          • UUID primary key
          • Audit columns: created_at, created_by, updated_at, updated_by
          • Optimistic-locking version column
          • ext jsonb NOT NULL DEFAULT '{}' on aggregate root only
            (sales order has it; lines do not — see SalesOrderLine doc)
    -->

    <changeSet id="orders-sales-init-001" author="vibe_erp">
        <comment>Create orders_sales__sales_order table (header)</comment>
        <sql>
            CREATE TABLE orders_sales__sales_order (
                id              uuid PRIMARY KEY,
                code            varchar(64)   NOT NULL,
                partner_code    varchar(64)   NOT NULL,
                status          varchar(16)   NOT NULL,
                order_date      date          NOT NULL,
                currency_code   varchar(3)    NOT NULL,
                total_amount    numeric(18,4) NOT NULL DEFAULT 0,
                ext             jsonb         NOT NULL DEFAULT '{}'::jsonb,
                created_at      timestamptz   NOT NULL,
                created_by      varchar(128)  NOT NULL,
                updated_at      timestamptz   NOT NULL,
                updated_by      varchar(128)  NOT NULL,
                version         bigint        NOT NULL DEFAULT 0
            );
            CREATE UNIQUE INDEX orders_sales__sales_order_code_uk
                ON orders_sales__sales_order (code);
            CREATE INDEX orders_sales__sales_order_partner_idx
                ON orders_sales__sales_order (partner_code);
            CREATE INDEX orders_sales__sales_order_status_idx
                ON orders_sales__sales_order (status);
            CREATE INDEX orders_sales__sales_order_date_idx
                ON orders_sales__sales_order (order_date);
            CREATE INDEX orders_sales__sales_order_ext_gin
                ON orders_sales__sales_order USING GIN (ext jsonb_path_ops);
        </sql>
        <rollback>
            DROP TABLE orders_sales__sales_order;
        </rollback>
    </changeSet>

    <changeSet id="orders-sales-init-002" author="vibe_erp">
        <comment>Create orders_sales__sales_order_line table (FK to header, no FK to catalog__item)</comment>
        <sql>
            CREATE TABLE orders_sales__sales_order_line (
                id              uuid PRIMARY KEY,
                sales_order_id  uuid          NOT NULL REFERENCES orders_sales__sales_order(id) ON DELETE CASCADE,
                line_no         integer       NOT NULL,
                item_code       varchar(64)   NOT NULL,
                quantity        numeric(18,4) NOT NULL,
                unit_price      numeric(18,4) NOT NULL,
                currency_code   varchar(3)    NOT NULL,
                created_at      timestamptz   NOT NULL,
                created_by      varchar(128)  NOT NULL,
                updated_at      timestamptz   NOT NULL,
                updated_by      varchar(128)  NOT NULL,
                version         bigint        NOT NULL DEFAULT 0,
                CONSTRAINT orders_sales__sales_order_line_qty_pos CHECK (quantity &gt; 0),
                CONSTRAINT orders_sales__sales_order_line_price_nonneg CHECK (unit_price &gt;= 0)
            );
            CREATE UNIQUE INDEX orders_sales__sales_order_line_order_lineno_uk
                ON orders_sales__sales_order_line (sales_order_id, line_no);
            CREATE INDEX orders_sales__sales_order_line_item_idx
                ON orders_sales__sales_order_line (item_code);
        </sql>
        <rollback>
            DROP TABLE orders_sales__sales_order_line;
        </rollback>
    </changeSet>

</databaseChangeLog>