krona-staff/migrations/0010_employee_push_notifications.up.sql

58 lines
2.7 KiB
SQL

-- Push subscriptions and delivery tracking for mobile employee notifications.
-- Protected by PostgreSQL Row Level Security (RLS) and tenant isolation.
CREATE TABLE staff_push_subscriptions (
id VARCHAR(26) PRIMARY KEY CHECK (id ~ '^[0-9A-HJKMNP-TV-Z]{26}$'),
tenant_id VARCHAR(26) NOT NULL CHECK (tenant_id ~ '^[0-9A-HJKMNP-TV-Z]{26}$'),
employee_id VARCHAR(26) NOT NULL,
endpoint TEXT NOT NULL,
p256dh TEXT NOT NULL,
auth TEXT NOT NULL,
user_agent TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (tenant_id, id),
UNIQUE (tenant_id, endpoint),
FOREIGN KEY (tenant_id, employee_id) REFERENCES staff_employees (tenant_id, id) ON DELETE CASCADE
);
CREATE INDEX staff_push_subscriptions_employee_idx
ON staff_push_subscriptions (tenant_id, employee_id);
ALTER TABLE staff_push_subscriptions ENABLE ROW LEVEL SECURITY;
ALTER TABLE staff_push_subscriptions FORCE ROW LEVEL SECURITY;
CREATE POLICY staff_push_subscriptions_tenant_isolation
ON staff_push_subscriptions
USING (tenant_id = current_setting('app.tenant_id', true))
WITH CHECK (tenant_id = current_setting('app.tenant_id', true));
CREATE TABLE staff_notification_deliveries (
id VARCHAR(26) PRIMARY KEY CHECK (id ~ '^[0-9A-HJKMNP-TV-Z]{26}$'),
tenant_id VARCHAR(26) NOT NULL CHECK (tenant_id ~ '^[0-9A-HJKMNP-TV-Z]{26}$'),
employee_id VARCHAR(26) NOT NULL,
outbox_id VARCHAR(26) NOT NULL CHECK (outbox_id ~ '^[0-9A-HJKMNP-TV-Z]{26}$'),
endpoint TEXT NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'delivered', 'failed')),
attempts INTEGER NOT NULL DEFAULT 0,
last_error TEXT,
delivered_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (tenant_id, id),
UNIQUE (tenant_id, outbox_id, endpoint),
FOREIGN KEY (tenant_id, employee_id) REFERENCES staff_employees (tenant_id, id) ON DELETE CASCADE,
FOREIGN KEY (outbox_id) REFERENCES staff_outbox (id) ON DELETE CASCADE
);
CREATE INDEX staff_notification_deliveries_pending_idx
ON staff_notification_deliveries (tenant_id, status) WHERE status = 'pending';
ALTER TABLE staff_notification_deliveries ENABLE ROW LEVEL SECURITY;
ALTER TABLE staff_notification_deliveries FORCE ROW LEVEL SECURITY;
CREATE POLICY staff_notification_deliveries_tenant_isolation
ON staff_notification_deliveries
USING (tenant_id = current_setting('app.tenant_id', true))
WITH CHECK (tenant_id = current_setting('app.tenant_id', true));
GRANT SELECT, INSERT, UPDATE, DELETE ON staff_push_subscriptions TO krona_staff_app;
GRANT SELECT, INSERT, UPDATE, DELETE ON staff_notification_deliveries TO krona_staff_app;