-- migrate:up CREATE TABLE domain.accounts ( account_id text PRIMARY KEY, name text NOT NULL, app_key text NOT NULL, is_active boolean NOT NULL DEFAULT true, created_at timestamptz NOT NULL DEFAULT now() ); CREATE TABLE domain.vehicles ( vehicle_id bigserial PRIMARY KEY, plate text NOT NULL UNIQUE, cost_centre text, assigned_city text, vehicle_class text, service_interval_km_override int, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX vehicles_cost_centre_idx ON domain.vehicles (cost_centre); CREATE INDEX vehicles_assigned_city_idx ON domain.vehicles (assigned_city); CREATE TABLE domain.devices ( imei text PRIMARY KEY, account_id text NOT NULL REFERENCES domain.accounts(account_id), vehicle_id bigint REFERENCES domain.vehicles(vehicle_id), device_type text NOT NULL CHECK (device_type IN ('tracker', 'camera')), model text, lifecycle text NOT NULL CHECK (lifecycle IN ( 'provisioned', 'active', 'suspended', 'decommissioned' )), activation_at timestamptz, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX devices_account_lifecycle_idx ON domain.devices (account_id, lifecycle); CREATE INDEX devices_vehicle_idx ON domain.devices (vehicle_id) WHERE vehicle_id IS NOT NULL; CREATE TABLE domain.devices_audit ( audit_id bigserial PRIMARY KEY, imei text NOT NULL, from_lifecycle text, to_lifecycle text NOT NULL, actor text NOT NULL, reason text, occurred_at timestamptz NOT NULL DEFAULT now() ); CREATE INDEX devices_audit_imei_idx ON domain.devices_audit (imei, occurred_at DESC); -- migrate:down DROP TABLE IF EXISTS domain.devices_audit; DROP TABLE IF EXISTS domain.devices; DROP TABLE IF EXISTS domain.vehicles; DROP TABLE IF EXISTS domain.accounts;