-- t-paliad-216 Slice A — add the "Suggest changes" action to the approval -- flow alongside Approve / Reject / Revoke. Design: -- docs/design-approval-suggest-changes-2026-05-19.md. -- -- Mental model (m's 2026-05-19 decisions, §0a of the design doc): -- "Suggest changes" is not a soft-reject with a hint. It is the approver -- AUTHORING A COUNTER-PROPOSAL that gets re-injected into the approval -- flow as a fresh `pending` row. The original requester (no longer the -- new row's requested_by) becomes potentially-eligible to approve the -- counter — 4-Augen still holds via the standard self-approval guard. -- -- Three schema additions to paliad.approval_requests: -- 1. Extend the status CHECK to allow 'changes_requested'. -- 2. counter_payload jsonb NULL — the approver's edited values, -- stored on the OLD (changes_requested) row so the audit chain -- can show "approver edited X, Y, Z" without joining forward. -- Also used as the `payload` for the NEW row spawned in the same -- tx by ApprovalService.SuggestChanges. -- 3. previous_request_id uuid NULL FK — back-pointer on the NEW row -- to the OLD (changes_requested) row that spawned it. ON DELETE -- SET NULL keeps a survivor row intact if either end is ever -- pruned. Partial index covers chain traversal. -- -- The set_config('paliad.audit_reason', ...) line is the universal -- convention for paliad migrations (mig 079 trigger pattern) — even -- pure-DDL migrations set it so an audit trigger that fires on any -- migration-touched table has a non-NULL reason string to record. SELECT set_config( 'paliad.audit_reason', 'mig 103: add suggest-changes action — extend approval_requests.status CHECK with changes_requested, add counter_payload jsonb + previous_request_id FK (t-paliad-216 Slice A)', true); -- 1. Extend approval_requests.status CHECK. ALTER TABLE paliad.approval_requests DROP CONSTRAINT IF EXISTS approval_requests_status_check; ALTER TABLE paliad.approval_requests ADD CONSTRAINT approval_requests_status_check CHECK (status IN ( 'pending', 'approved', 'rejected', 'revoked', 'superseded', 'changes_requested' )); -- 2. counter_payload — the approver's edited values when suggesting -- changes. Stays NULL for every status other than changes_requested. ALTER TABLE paliad.approval_requests ADD COLUMN counter_payload jsonb; -- 3. previous_request_id — back-pointer FK. NULL for first-attempt rows; -- set to the prior (changes_requested) row's id on the NEW row spawned -- by SuggestChanges. ON DELETE SET NULL keeps survivor rows intact. ALTER TABLE paliad.approval_requests ADD COLUMN previous_request_id uuid REFERENCES paliad.approval_requests(id) ON DELETE SET NULL; CREATE INDEX IF NOT EXISTS approval_requests_previous_idx ON paliad.approval_requests (previous_request_id) WHERE previous_request_id IS NOT NULL;