<?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
                      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.27.xsd">

  <!--
    Approval Workflow v2 — Phase 0: schema foundation.

    Decisions made (auto, per design doc recommendations):
    - D1=A: per-dict policy через колонки на dictionary_definitions.
    - D2=A: legacy POST на approval-required dict → 409 (handled в service).
    - D3=A: pool model для reviewer'ов (no assigned column в schema).
    - D4=A: soft-archive rejected drafts (status='rejected' kept).

    Layered model (Approach A из design doc):
    - record_drafts (DRAFT layer) — pending/approved/rejected/withdrawn
    - dictionary_records (LIVE layer) — only approved versions
    - ON APPROVE: COPY draft → live + DELETE draft + outbox event

    Source: ~/.gstack/projects/claude/zimin-main-design-approval-workflow-v2-20260507-121632.md
  -->
  <changeSet id="0019-1-record-drafts" author="ordinis">
    <comment>record_drafts table — DRAFT layer для maker-checker workflow</comment>
    <createTable tableName="record_drafts">
      <column name="id" type="UUID" defaultValueComputed="gen_random_uuid()">
        <constraints primaryKey="true" nullable="false"/>
      </column>
      <column name="dictionary_id" type="UUID">
        <constraints nullable="false" foreignKeyName="fk_draft_dictionary"
                     references="dictionary_definitions(id)"/>
      </column>
      <column name="business_key" type="VARCHAR(256)">
        <constraints nullable="false"/>
      </column>
      <!-- NULL для CREATE; точка истории для UPDATE/CLOSE (live record id). -->
      <column name="parent_record_id" type="UUID"/>
      <column name="operation" type="VARCHAR(16)">
        <constraints nullable="false"/>
      </column>

      <!-- Payload (для CREATE/UPDATE — full record; для CLOSE — пусто). -->
      <column name="data" type="JSONB"/>
      <column name="geometry" type="GEOMETRY(Geometry, 4326)"/>
      <column name="proposed_valid_from" type="TIMESTAMPTZ"/>
      <column name="proposed_valid_to" type="TIMESTAMPTZ"/>

      <!-- Workflow state. -->
      <column name="status" type="VARCHAR(16)">
        <constraints nullable="false"/>
      </column>
      <column name="maker_id" type="VARCHAR(128)">
        <constraints nullable="false"/>
      </column>
      <column name="maker_comment" type="TEXT"/>
      <column name="submitted_at" type="TIMESTAMPTZ" defaultValueComputed="NOW()">
        <constraints nullable="false"/>
      </column>
      <column name="reviewer_id" type="VARCHAR(128)"/>
      <column name="reviewed_at" type="TIMESTAMPTZ"/>
      <column name="review_comment" type="TEXT"/>
      <column name="version" type="BIGINT" defaultValueNumeric="0">
        <constraints nullable="false"/>
      </column>
    </createTable>

    <sql>
      ALTER TABLE record_drafts
      ADD CONSTRAINT record_drafts_status_check
      CHECK (status IN ('pending', 'approved', 'rejected', 'withdrawn'));
    </sql>
    <sql>
      ALTER TABLE record_drafts
      ADD CONSTRAINT record_drafts_operation_check
      CHECK (operation IN ('CREATE', 'UPDATE', 'CLOSE'));
    </sql>

    <!-- D3 pool model + D4 self-approval guard:
         maker_id != reviewer_id если оба set'ы. -->
    <sql>
      ALTER TABLE record_drafts
      ADD CONSTRAINT record_drafts_no_self_approve
      CHECK (reviewer_id IS NULL OR maker_id != reviewer_id);
    </sql>

    <!-- Только один pending draft на business_key одновременно
         (concurrent edits = последний wins на submit, prevents merge conflicts). -->
    <sql>
      ALTER TABLE record_drafts
      ADD CONSTRAINT record_drafts_one_pending_per_key
      EXCLUDE USING btree (
        dictionary_id WITH =,
        business_key WITH =
      ) WHERE (status = 'pending');
    </sql>

    <createIndex indexName="idx_drafts_pending_by_dict" tableName="record_drafts">
      <column name="dictionary_id"/>
      <column name="submitted_at"/>
    </createIndex>
    <createIndex indexName="idx_drafts_by_maker" tableName="record_drafts">
      <column name="maker_id"/>
      <column name="submitted_at" descending="true"/>
    </createIndex>
    <createIndex indexName="idx_drafts_pending_global" tableName="record_drafts">
      <column name="status"/>
      <column name="submitted_at"/>
    </createIndex>
  </changeSet>

  <changeSet id="0019-2-dict-approval-policy" author="ordinis">
    <comment>Per-dictionary opt-in: approval_required + min reviewer role (D1=A)</comment>
    <addColumn tableName="dictionary_definitions">
      <column name="approval_required" type="BOOLEAN" defaultValueBoolean="false">
        <constraints nullable="false"/>
      </column>
      <column name="approval_min_role" type="VARCHAR(64)"/>
    </addColumn>
    <createIndex indexName="idx_dict_def_approval_required"
                 tableName="dictionary_definitions">
      <column name="approval_required"/>
    </createIndex>
  </changeSet>

</databaseChangeLog>
