9c datatables #5

Merged
Lars merged 4 commits from develop into main 2026-03-19 13:00:31 +01:00
Showing only changes of commit a8df7f8359 - Show all commits

View File

@ -70,7 +70,7 @@ CREATE TABLE IF NOT EXISTS features (
-- 4. tier_limits - Tier x Feature matrix -- 4. tier_limits - Tier x Feature matrix
-- ============================================================================ -- ============================================================================
CREATE TABLE IF NOT EXISTS tier_limits ( CREATE TABLE IF NOT EXISTS tier_limits (
id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::TEXT, id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
tier_id TEXT NOT NULL REFERENCES tiers(id) ON DELETE CASCADE, tier_id TEXT NOT NULL REFERENCES tiers(id) ON DELETE CASCADE,
feature_id TEXT NOT NULL REFERENCES features(id) ON DELETE CASCADE, feature_id TEXT NOT NULL REFERENCES features(id) ON DELETE CASCADE,
limit_value INTEGER, -- NULL = unlimited, 0 = disabled limit_value INTEGER, -- NULL = unlimited, 0 = disabled
@ -83,12 +83,12 @@ CREATE TABLE IF NOT EXISTS tier_limits (
-- 5. user_feature_restrictions - Individual user overrides -- 5. user_feature_restrictions - Individual user overrides
-- ============================================================================ -- ============================================================================
CREATE TABLE IF NOT EXISTS user_feature_restrictions ( CREATE TABLE IF NOT EXISTS user_feature_restrictions (
id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::TEXT, id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
profile_id TEXT NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
feature_id TEXT NOT NULL REFERENCES features(id) ON DELETE CASCADE, feature_id TEXT NOT NULL REFERENCES features(id) ON DELETE CASCADE,
limit_value INTEGER, -- NULL = unlimited, 0 = disabled limit_value INTEGER, -- NULL = unlimited, 0 = disabled
reason TEXT, -- Why was this override applied? reason TEXT, -- Why was this override applied?
created_by TEXT, -- Admin profile_id created_by UUID, -- Admin profile_id
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(profile_id, feature_id) UNIQUE(profile_id, feature_id)
@ -98,8 +98,8 @@ CREATE TABLE IF NOT EXISTS user_feature_restrictions (
-- 6. user_feature_usage - Usage tracking -- 6. user_feature_usage - Usage tracking
-- ============================================================================ -- ============================================================================
CREATE TABLE IF NOT EXISTS user_feature_usage ( CREATE TABLE IF NOT EXISTS user_feature_usage (
id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::TEXT, id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
profile_id TEXT NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
feature_id TEXT NOT NULL REFERENCES features(id) ON DELETE CASCADE, feature_id TEXT NOT NULL REFERENCES features(id) ON DELETE CASCADE,
usage_count INTEGER DEFAULT 0, usage_count INTEGER DEFAULT 0,
reset_at TIMESTAMP, -- When does this counter reset? reset_at TIMESTAMP, -- When does this counter reset?
@ -112,7 +112,7 @@ CREATE TABLE IF NOT EXISTS user_feature_usage (
-- 7. coupons - Coupon management -- 7. coupons - Coupon management
-- ============================================================================ -- ============================================================================
CREATE TABLE IF NOT EXISTS coupons ( CREATE TABLE IF NOT EXISTS coupons (
id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::TEXT, id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
code TEXT UNIQUE NOT NULL, code TEXT UNIQUE NOT NULL,
type TEXT NOT NULL, -- 'single_use', 'period', 'wellpass' type TEXT NOT NULL, -- 'single_use', 'period', 'wellpass'
tier_id TEXT REFERENCES tiers(id) ON DELETE SET NULL, tier_id TEXT REFERENCES tiers(id) ON DELETE SET NULL,
@ -122,7 +122,7 @@ CREATE TABLE IF NOT EXISTS coupons (
valid_from TIMESTAMP, valid_from TIMESTAMP,
valid_until TIMESTAMP, valid_until TIMESTAMP,
active BOOLEAN DEFAULT true, active BOOLEAN DEFAULT true,
created_by TEXT, -- Admin profile_id created_by UUID, -- Admin profile_id
description TEXT, -- Internal note description TEXT, -- Internal note
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP
@ -132,11 +132,11 @@ CREATE TABLE IF NOT EXISTS coupons (
-- 8. coupon_redemptions - Redemption history -- 8. coupon_redemptions - Redemption history
-- ============================================================================ -- ============================================================================
CREATE TABLE IF NOT EXISTS coupon_redemptions ( CREATE TABLE IF NOT EXISTS coupon_redemptions (
id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::TEXT, id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
coupon_id TEXT NOT NULL REFERENCES coupons(id) ON DELETE CASCADE, coupon_id UUID NOT NULL REFERENCES coupons(id) ON DELETE CASCADE,
profile_id TEXT NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
redeemed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, redeemed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
access_grant_id TEXT, -- FK to access_grants (created as result) access_grant_id UUID, -- FK to access_grants (created as result)
UNIQUE(coupon_id, profile_id) -- One redemption per user per coupon UNIQUE(coupon_id, profile_id) -- One redemption per user per coupon
); );
@ -144,15 +144,15 @@ CREATE TABLE IF NOT EXISTS coupon_redemptions (
-- 9. access_grants - Time-limited access grants -- 9. access_grants - Time-limited access grants
-- ============================================================================ -- ============================================================================
CREATE TABLE IF NOT EXISTS access_grants ( CREATE TABLE IF NOT EXISTS access_grants (
id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::TEXT, id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
profile_id TEXT NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
tier_id TEXT NOT NULL REFERENCES tiers(id) ON DELETE CASCADE, tier_id TEXT NOT NULL REFERENCES tiers(id) ON DELETE CASCADE,
granted_by TEXT, -- 'coupon', 'admin', 'trial', 'subscription' granted_by TEXT, -- 'coupon', 'admin', 'trial', 'subscription'
coupon_id TEXT REFERENCES coupons(id) ON DELETE SET NULL, coupon_id UUID REFERENCES coupons(id) ON DELETE SET NULL,
valid_from TIMESTAMP NOT NULL, valid_from TIMESTAMP NOT NULL,
valid_until TIMESTAMP NOT NULL, valid_until TIMESTAMP NOT NULL,
is_active BOOLEAN DEFAULT true, -- Can be paused by Wellpass logic is_active BOOLEAN DEFAULT true, -- Can be paused by Wellpass logic
paused_by TEXT, -- access_grant.id that paused this paused_by UUID, -- access_grant.id that paused this
paused_at TIMESTAMP, -- When was it paused? paused_at TIMESTAMP, -- When was it paused?
remaining_days INTEGER, -- Days left when paused (for resume) remaining_days INTEGER, -- Days left when paused (for resume)
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
@ -163,8 +163,8 @@ CREATE TABLE IF NOT EXISTS access_grants (
-- 10. user_activity_log - Activity tracking -- 10. user_activity_log - Activity tracking
-- ============================================================================ -- ============================================================================
CREATE TABLE IF NOT EXISTS user_activity_log ( CREATE TABLE IF NOT EXISTS user_activity_log (
id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::TEXT, id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
profile_id TEXT NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
action TEXT NOT NULL, -- 'login', 'logout', 'coupon_redeemed', 'tier_changed' action TEXT NOT NULL, -- 'login', 'logout', 'coupon_redeemed', 'tier_changed'
details JSONB, -- Flexible metadata details JSONB, -- Flexible metadata
ip_address TEXT, ip_address TEXT,
@ -179,7 +179,7 @@ CREATE INDEX IF NOT EXISTS idx_activity_log_action ON user_activity_log(action,
-- 11. user_stats - Aggregated statistics -- 11. user_stats - Aggregated statistics
-- ============================================================================ -- ============================================================================
CREATE TABLE IF NOT EXISTS user_stats ( CREATE TABLE IF NOT EXISTS user_stats (
profile_id TEXT PRIMARY KEY REFERENCES profiles(id) ON DELETE CASCADE, profile_id UUID PRIMARY KEY REFERENCES profiles(id) ON DELETE CASCADE,
last_login TIMESTAMP, last_login TIMESTAMP,
login_count INTEGER DEFAULT 0, login_count INTEGER DEFAULT 0,
weight_entries_count INTEGER DEFAULT 0, weight_entries_count INTEGER DEFAULT 0,
@ -197,7 +197,7 @@ ALTER TABLE profiles ADD COLUMN IF NOT EXISTS tier TEXT DEFAULT 'free';
ALTER TABLE profiles ADD COLUMN IF NOT EXISTS trial_ends_at TIMESTAMP; ALTER TABLE profiles ADD COLUMN IF NOT EXISTS trial_ends_at TIMESTAMP;
ALTER TABLE profiles ADD COLUMN IF NOT EXISTS email_verified BOOLEAN DEFAULT false; ALTER TABLE profiles ADD COLUMN IF NOT EXISTS email_verified BOOLEAN DEFAULT false;
ALTER TABLE profiles ADD COLUMN IF NOT EXISTS email_verify_token TEXT; ALTER TABLE profiles ADD COLUMN IF NOT EXISTS email_verify_token TEXT;
ALTER TABLE profiles ADD COLUMN IF NOT EXISTS invited_by TEXT REFERENCES profiles(id) ON DELETE SET NULL; ALTER TABLE profiles ADD COLUMN IF NOT EXISTS invited_by UUID REFERENCES profiles(id) ON DELETE SET NULL;
ALTER TABLE profiles ADD COLUMN IF NOT EXISTS invitation_token TEXT; ALTER TABLE profiles ADD COLUMN IF NOT EXISTS invitation_token TEXT;
-- ============================================================================ -- ============================================================================