BEGIN; CREATE TABLE IF NOT EXISTS soundbox_vendors ( id TEXT PRIMARY KEY, vendor_code TEXT NOT NULL UNIQUE, name TEXT NOT NULL, country TEXT, support_contact TEXT, status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'inactive')), created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ NOT NULL ); CREATE TABLE IF NOT EXISTS soundbox_models ( id TEXT PRIMARY KEY, vendor_id TEXT NOT NULL REFERENCES soundbox_vendors (id) ON DELETE CASCADE, model_code TEXT NOT NULL, name TEXT NOT NULL, communication_mode TEXT NOT NULL DEFAULT 'mqtt' CHECK (communication_mode IN ('static', 'mqtt', 'api')), screen_flag BOOLEAN NOT NULL DEFAULT false, qr_mode TEXT NOT NULL DEFAULT 'static' CHECK (qr_mode IN ('static', 'dynamic_mqtt', 'dynamic_api')), mqtt_payload_profile TEXT, capability_template_json JSONB NOT NULL DEFAULT '{}'::jsonb, status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'inactive')), created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ NOT NULL, UNIQUE (vendor_id, model_code) ); CREATE INDEX IF NOT EXISTS idx_soundbox_models_vendor ON soundbox_models (vendor_id, status); INSERT INTO soundbox_vendors (id, vendor_code, name, country, support_contact, status, created_at, updated_at) VALUES ('vendor_qf', 'QF', 'QF', NULL, NULL, 'active', NOW(), NOW()) ON CONFLICT (vendor_code) DO NOTHING; INSERT INTO soundbox_models ( id, vendor_id, model_code, name, communication_mode, screen_flag, qr_mode, mqtt_payload_profile, capability_template_json, status, created_at, updated_at ) VALUES ( 'model_qf100', 'vendor_qf', 'QF100', 'QF100', 'mqtt', false, 'static', 'qf100', '{"device_type":"static_soundbox","screen":false,"qr_mode":"static","mqtt_payload_profile":"qf100","flows":["static_payment_notification"],"features":{"payment_sound":true,"dynamic_qr":false}}'::jsonb, 'active', NOW(), NOW() ) ON CONFLICT (vendor_id, model_code) DO NOTHING; COMMIT;