Add SMS templates, prepaid IRT billing, and advertising shortcode 9000590009.

Charge ceil(len/64)*400 IRT per recipient across OTP, customer, and partner SMS; seed new businesses with 500k IRT; default partner sends to the advertising line.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-09-08 16:24:15 +03:30
co-authored by Cursor
parent 4623061a4f
commit 4a1d60dbef
29 changed files with 1170 additions and 61 deletions
+36
View File
@@ -0,0 +1,36 @@
-- SMS templates per business (verified by super-admin → Meshkee service shortcode).
CREATE TABLE IF NOT EXISTS sms_templates (
id BIGSERIAL PRIMARY KEY,
business_id BIGINT NOT NULL REFERENCES businesses (id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
body TEXT NOT NULL,
is_verified BOOLEAN NOT NULL DEFAULT FALSE,
verified_at TIMESTAMPTZ NULL,
verified_by BIGINT NULL REFERENCES users (id) ON DELETE SET NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_sms_templates_business_id
ON sms_templates (business_id);
CREATE INDEX IF NOT EXISTS idx_sms_templates_business_verified
ON sms_templates (business_id, is_verified);
CREATE INDEX IF NOT EXISTS idx_sms_templates_created_at
ON sms_templates (created_at DESC);
CREATE OR REPLACE FUNCTION sms_templates_set_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = now();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS sms_templates_set_updated_at ON sms_templates;
CREATE TRIGGER sms_templates_set_updated_at
BEFORE UPDATE ON sms_templates
FOR EACH ROW
EXECUTE FUNCTION sms_templates_set_updated_at();
@@ -0,0 +1,7 @@
-- Per-business prepaid SMS credit (messages). Deducted when customer SMS is sent.
ALTER TABLE businesses
ADD COLUMN IF NOT EXISTS sms_balance INTEGER NOT NULL DEFAULT 0;
COMMENT ON COLUMN businesses.sms_balance IS
'Prepaid SMS message credits for this business; decremented on customer SMS send.';
@@ -0,0 +1,21 @@
-- SMS template verification workflow: free | pending | verified
ALTER TABLE sms_templates
ADD COLUMN IF NOT EXISTS verification_status VARCHAR(32) NOT NULL DEFAULT 'free';
UPDATE sms_templates
SET verification_status = 'verified'
WHERE is_verified = TRUE;
ALTER TABLE sms_templates
DROP CONSTRAINT IF EXISTS sms_templates_verification_status_check;
ALTER TABLE sms_templates
ADD CONSTRAINT sms_templates_verification_status_check
CHECK (verification_status IN ('free', 'pending', 'verified'));
CREATE INDEX IF NOT EXISTS idx_sms_templates_verification_status
ON sms_templates (verification_status);
CREATE INDEX IF NOT EXISTS idx_sms_templates_business_status
ON sms_templates (business_id, verification_status);
@@ -0,0 +1,6 @@
-- SMS balance is prepaid IRT (not message counts).
-- Billing: ceil(message_length / 64) * 400 IRT per recipient
-- (login OTP, customer SMS, partner/public SMS, etc.).
COMMENT ON COLUMN businesses.sms_balance IS
'Prepaid SMS balance in IRT. Each 64-character segment costs 400 IRT per recipient.';