From b107f4ef041b0c7b0d7e35284aed53b974c0d13d Mon Sep 17 00:00:00 2001 From: efrilm Date: Wed, 30 Sep 2026 01:01:02 +0700 Subject: [PATCH] feat(settings): add organization settings and loyalty setting history Migration 000091 creates organization_settings, a key-value store per organization shaped like outlet_settings, for the loyalty settings that must be the same in every outlet (point value, exchange rate, transfer limits, expiry). Until now there was nowhere to keep organization-level settings. Also creates loyalty_setting_changes, the append-only log of who changed which loyalty setting from what to what (PRD F2), for both organization and outlet settings (PC-102). Co-Authored-By: Claude Opus 5.5 --- ...0091_create_organization_settings.down.sql | 2 ++ ...000091_create_organization_settings.up.sql | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 migrations/000091_create_organization_settings.down.sql create mode 100644 migrations/000091_create_organization_settings.up.sql diff --git a/migrations/000091_create_organization_settings.down.sql b/migrations/000091_create_organization_settings.down.sql new file mode 100644 index 0000000..62d6a91 --- /dev/null +++ b/migrations/000091_create_organization_settings.down.sql @@ -0,0 +1,2 @@ +DROP TABLE IF EXISTS loyalty_setting_changes; +DROP TABLE IF EXISTS organization_settings; diff --git a/migrations/000091_create_organization_settings.up.sql b/migrations/000091_create_organization_settings.up.sql new file mode 100644 index 0000000..06e9ed1 --- /dev/null +++ b/migrations/000091_create_organization_settings.up.sql @@ -0,0 +1,35 @@ +-- Settings that must be the same in every outlet of an organization, starting with the +-- loyalty ones (docs/prd-point-coin.md F2, F12): point value, exchange rate, transfer +-- limits and expiry. Same key-value shape as outlet_settings. +CREATE TABLE organization_settings ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE, + key VARCHAR(255) NOT NULL, + value TEXT, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + UNIQUE(organization_id, key) +); + +-- The unique constraint leads with organization_id, so it also serves the plain +-- per-organization lookups and there is no separate index on that column. + +-- Who changed which loyalty setting, from what, to what (F2). Covers both the +-- organization settings above and the per-outlet loyalty keys in outlet_settings. +-- Append-only. Values are stored as text, the same as in the settings tables. +CREATE TABLE loyalty_setting_changes ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + organization_id UUID NOT NULL, + -- NULL for an organization setting. + outlet_id UUID, + key VARCHAR(100) NOT NULL, + -- NULL when the key had no stored value yet (it was on its default). + old_value TEXT, + new_value TEXT, + changed_by UUID NOT NULL, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() +); + +CREATE INDEX idx_loyalty_setting_changes_organization_id_created_at ON loyalty_setting_changes(organization_id, created_at DESC); +CREATE INDEX idx_loyalty_setting_changes_outlet_id_created_at ON loyalty_setting_changes(outlet_id, created_at DESC) + WHERE outlet_id IS NOT NULL;