v0.1.0:25–40 — tier model, edit forms, force-delete, license counts, migration 0009 (and hotfix); KEYSAT_INTEGRATION.md merged with downstream-LLM revisions
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
-- Allow `kind = 'set_price'` on discount_codes (added at the daemon
|
||||
-- level in v0.1.0:26 but the migration that created the CHECK constraint
|
||||
-- in 0004 didn't include it, so existing instances reject the new kind
|
||||
-- with "CHECK constraint failed").
|
||||
--
|
||||
-- SQLite doesn't support ALTER TABLE ... DROP CONSTRAINT, so we rebuild
|
||||
-- the table: copy → drop old → rename. sqlx-migrate already wraps each
|
||||
-- .sql file in a transaction, so we DON'T do BEGIN/COMMIT here (nested
|
||||
-- transactions are not supported in SQLite).
|
||||
--
|
||||
-- `PRAGMA defer_foreign_keys = 1` is the transaction-local equivalent
|
||||
-- of `foreign_keys = OFF`: it postpones FK constraint checks until
|
||||
-- COMMIT time. This lets us drop the old discount_codes table without
|
||||
-- the immediate FK check from discount_redemptions.code_id failing.
|
||||
-- The IDs are preserved across the rebuild, so when the FK check runs
|
||||
-- at COMMIT, every referencing row still resolves cleanly.
|
||||
|
||||
PRAGMA defer_foreign_keys = 1;
|
||||
|
||||
CREATE TABLE discount_codes_new (
|
||||
id TEXT PRIMARY KEY,
|
||||
code TEXT NOT NULL UNIQUE,
|
||||
kind TEXT NOT NULL, -- 'percent' | 'fixed_sats' | 'set_price' | 'free_license'
|
||||
amount INTEGER NOT NULL,
|
||||
max_uses INTEGER,
|
||||
used_count INTEGER NOT NULL DEFAULT 0,
|
||||
expires_at TEXT,
|
||||
applies_to_product_id TEXT,
|
||||
applies_to_policy_id TEXT,
|
||||
referrer_label TEXT,
|
||||
description TEXT NOT NULL DEFAULT '',
|
||||
active INTEGER NOT NULL DEFAULT 1,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL,
|
||||
FOREIGN KEY (applies_to_product_id) REFERENCES products(id),
|
||||
FOREIGN KEY (applies_to_policy_id) REFERENCES policies(id),
|
||||
CHECK (kind IN ('percent', 'fixed_sats', 'set_price', 'free_license')),
|
||||
CHECK (amount >= 0),
|
||||
CHECK (used_count >= 0)
|
||||
);
|
||||
|
||||
INSERT INTO discount_codes_new
|
||||
SELECT id, code, kind, amount, max_uses, used_count, expires_at,
|
||||
applies_to_product_id, applies_to_policy_id, referrer_label,
|
||||
description, active, created_at, updated_at
|
||||
FROM discount_codes;
|
||||
|
||||
DROP TABLE discount_codes;
|
||||
ALTER TABLE discount_codes_new RENAME TO discount_codes;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_discount_codes_active ON discount_codes(active);
|
||||
CREATE INDEX IF NOT EXISTS idx_discount_codes_product ON discount_codes(applies_to_product_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_discount_codes_policy ON discount_codes(applies_to_policy_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_discount_codes_expires ON discount_codes(expires_at);
|
||||
Reference in New Issue
Block a user