-- migrate:up CREATE TABLE events.raw ( event_id bigserial, received_at timestamptz NOT NULL DEFAULT now(), source text NOT NULL CHECK (source IN ( 'tracksolid_push', 'tracksolid_poll_list', 'tracksolid_poll_get', 'whatsapp_fuel', 'hr_extract', 'ops_action', 'legacy_import' )), account_id text, imei text, msg_type text, payload jsonb NOT NULL, parser_version int, parsed_at timestamptz, PRIMARY KEY (event_id, received_at) ); SELECT create_hypertable('events.raw', 'received_at', chunk_time_interval => INTERVAL '1 day'); CREATE INDEX events_raw_unparsed_idx ON events.raw (received_at) WHERE parsed_at IS NULL; CREATE INDEX events_raw_account_imei_idx ON events.raw (account_id, imei, received_at DESC); CREATE TABLE events.parsed ( parsed_id bigserial, raw_event_id bigint NOT NULL, raw_received_at timestamptz NOT NULL, occurred_at timestamptz NOT NULL, kind text NOT NULL, account_id text NOT NULL, imei text NOT NULL, payload jsonb NOT NULL, parser_version int NOT NULL, inserted_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY (parsed_id, occurred_at) ); SELECT create_hypertable('events.parsed', 'occurred_at', chunk_time_interval => INTERVAL '1 day'); CREATE INDEX events_parsed_kind_imei_idx ON events.parsed (kind, imei, occurred_at DESC); CREATE TABLE events.parser_errors ( error_id bigserial PRIMARY KEY, raw_event_id bigint NOT NULL, raw_received_at timestamptz NOT NULL, parser_version int NOT NULL, error_class text NOT NULL, error_message text NOT NULL, payload jsonb NOT NULL, inserted_at timestamptz NOT NULL DEFAULT now() ); CREATE OR REPLACE FUNCTION events.notify_raw_new() RETURNS trigger AS $$ BEGIN PERFORM pg_notify('events_raw_new', NEW.event_id::text); RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER events_raw_new_trigger AFTER INSERT ON events.raw FOR EACH ROW EXECUTE FUNCTION events.notify_raw_new(); CREATE OR REPLACE FUNCTION events.notify_parsed_new() RETURNS trigger AS $$ BEGIN PERFORM pg_notify('events_parsed_new', NEW.parsed_id::text); RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER events_parsed_new_trigger AFTER INSERT ON events.parsed FOR EACH ROW EXECUTE FUNCTION events.notify_parsed_new(); -- migrate:down DROP TRIGGER IF EXISTS events_parsed_new_trigger ON events.parsed; DROP TRIGGER IF EXISTS events_raw_new_trigger ON events.raw; DROP FUNCTION IF EXISTS events.notify_parsed_new(); DROP FUNCTION IF EXISTS events.notify_raw_new(); DROP TABLE IF EXISTS events.parser_errors; DROP TABLE IF EXISTS events.parsed; DROP TABLE IF EXISTS events.raw;