56 lines
2.1 KiB
SQL
56 lines
2.1 KiB
SQL
CREATE TYPE aftersale_kind AS ENUM ('refund_only', 'return_refund');
|
|
|
|
CREATE TYPE aftersale_status AS ENUM (
|
|
'pending',
|
|
'approved',
|
|
'rejected',
|
|
'buyer_shipping',
|
|
'merchant_confirmed',
|
|
'refunded',
|
|
'cancelled'
|
|
);
|
|
|
|
-- Authoritative per-order refund total; every increment is a guarded UPDATE.
|
|
ALTER TABLE orders
|
|
ADD COLUMN refund_total_minor BIGINT NOT NULL DEFAULT 0
|
|
CHECK (refund_total_minor >= 0);
|
|
|
|
CREATE TABLE aftersales (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
order_id UUID NOT NULL REFERENCES orders (id),
|
|
order_item_id UUID NOT NULL REFERENCES order_items (id),
|
|
shop_id UUID NOT NULL REFERENCES shops (id),
|
|
user_id UUID NOT NULL REFERENCES users (id),
|
|
kind aftersale_kind NOT NULL,
|
|
status aftersale_status NOT NULL DEFAULT 'pending',
|
|
reason JSONB NOT NULL,
|
|
amount_minor BIGINT NOT NULL CHECK (amount_minor > 0),
|
|
evidence JSONB NOT NULL DEFAULT '[]',
|
|
reopened BOOLEAN NOT NULL DEFAULT false,
|
|
return_carrier TEXT,
|
|
return_tracking_no TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- At most one active (non-terminal) aftersale per order item.
|
|
CREATE UNIQUE INDEX aftersales_one_active_per_item
|
|
ON aftersales (order_item_id)
|
|
WHERE status NOT IN ('refunded', 'rejected', 'cancelled');
|
|
CREATE INDEX idx_aftersales_user ON aftersales (user_id);
|
|
CREATE INDEX idx_aftersales_shop ON aftersales (shop_id);
|
|
CREATE INDEX idx_aftersales_order ON aftersales (order_id);
|
|
|
|
-- Append-only bilateral message log; no UPDATE/DELETE paths exist.
|
|
CREATE TABLE aftersale_messages (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
aftersale_id UUID NOT NULL REFERENCES aftersales (id) ON DELETE CASCADE,
|
|
author_role TEXT NOT NULL CHECK (author_role IN ('buyer', 'merchant', 'platform')),
|
|
author_id UUID NOT NULL REFERENCES users (id),
|
|
content JSONB NOT NULL,
|
|
evidence JSONB NOT NULL DEFAULT '[]',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX idx_aftersale_messages_aftersale ON aftersale_messages (aftersale_id);
|