Files
QR-master/manual-billing-sql.txt
Timo Knuth 192c186027 sql
2026-07-06 00:38:26 +02:00

91 lines
2.3 KiB
Plaintext

QR Master automatic billing alarm SQL
=====================================
Run this SQL once in the database.
After it is installed, every database update of "User"."plan" automatically
creates a "UserLifecycleLog" entry.
That means:
- FREE -> PRO or BUSINESS creates reason = subscription_created
- PRO/BUSINESS -> FREE creates reason = subscription_deleted
- PRO -> BUSINESS or BUSINESS -> PRO creates reason = subscription_updated
No customer email needs to be typed into this file.
No manual log insert is needed after this is installed.
CREATE OR REPLACE FUNCTION qrmaster_log_plan_change()
RETURNS trigger AS $$
DECLARE
next_stage TEXT;
log_reason TEXT;
BEGIN
IF NEW."plan" IS NOT DISTINCT FROM OLD."plan" THEN
RETURN NEW;
END IF;
IF NEW."plan"::TEXT IN ('PRO', 'BUSINESS') THEN
next_stage := 'paid';
ELSIF COALESCE(NEW."leadScore", 0) >= 70 THEN
next_stage := 'upgrade_candidate';
ELSIF COALESCE(NEW."leadScore", 0) >= 55 THEN
next_stage := 'hot';
ELSIF COALESCE(NEW."leadScore", 0) >= 30 THEN
next_stage := 'warm';
ELSIF NEW."activationAt" IS NOT NULL THEN
next_stage := 'activated';
ELSE
next_stage := 'cold';
END IF;
IF OLD."plan"::TEXT = 'FREE' AND NEW."plan"::TEXT IN ('PRO', 'BUSINESS') THEN
log_reason := 'subscription_created';
ELSIF OLD."plan"::TEXT IN ('PRO', 'BUSINESS') AND NEW."plan"::TEXT = 'FREE' THEN
log_reason := 'subscription_deleted';
ELSE
log_reason := 'subscription_updated';
END IF;
NEW."lifecycleStage" := next_stage;
NEW."lastScoredAt" := NOW();
IF next_stage IN ('paid', 'hot', 'upgrade_candidate') THEN
NEW."lastQualifiedAt" := NOW();
END IF;
INSERT INTO "UserLifecycleLog" (
"id",
"userId",
"fromStage",
"toStage",
"fitScore",
"intentScore",
"leadScore",
"reason",
"createdAt"
)
VALUES (
CONCAT('planlog_', MD5(NEW."id" || clock_timestamp()::TEXT || random()::TEXT)),
NEW."id",
OLD."lifecycleStage",
next_stage,
COALESCE(NEW."fitScore", 0),
COALESCE(NEW."intentScore", 0),
COALESCE(NEW."leadScore", 0),
log_reason,
NOW()
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS qrmaster_user_plan_change_alarm ON "User";
CREATE TRIGGER qrmaster_user_plan_change_alarm
BEFORE UPDATE OF "plan" ON "User"
FOR EACH ROW
EXECUTE FUNCTION qrmaster_log_plan_change();