-- 009: Entity cache — stores bulk-downloaded business entity records -- from state Secretary of State open data portals. -- Used by Verilex Data Professional API via internal bulk export endpoint. CREATE TABLE IF NOT EXISTS entity_cache ( id SERIAL PRIMARY KEY, jurisdiction TEXT NOT NULL, -- US_CO, US_NY, etc. entity_name TEXT NOT NULL, entity_number TEXT, -- state filing number entity_type TEXT, -- LLC, CORPORATION, LP, LLP, etc. status TEXT, -- ACTIVE, DISSOLVED, SUSPENDED, DELINQUENT formation_date DATE, dissolution_date DATE, registered_agent TEXT, principal_address TEXT, state TEXT NOT NULL, -- 2-letter source TEXT DEFAULT 'socrata', -- socrata, sftp, csv, playwright raw_data JSONB, -- original source record for debugging last_synced TIMESTAMPTZ DEFAULT NOW(), created_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(jurisdiction, entity_number) ); CREATE INDEX IF NOT EXISTS idx_ec_state ON entity_cache (state); CREATE INDEX IF NOT EXISTS idx_ec_name ON entity_cache USING gin (entity_name gin_trgm_ops); CREATE INDEX IF NOT EXISTS idx_ec_number ON entity_cache (entity_number); CREATE INDEX IF NOT EXISTS idx_ec_status ON entity_cache (status); CREATE INDEX IF NOT EXISTS idx_ec_synced ON entity_cache (last_synced); -- Name search cache — stores results of live name availability searches -- to avoid hammering state portals. Entries expire after 24 hours. CREATE TABLE IF NOT EXISTS name_search_cache ( id SERIAL PRIMARY KEY, state_code CHAR(2) NOT NULL, searched_name TEXT NOT NULL, available BOOLEAN, exact_match BOOLEAN DEFAULT FALSE, similar_names TEXT[], raw_response TEXT, searched_at TIMESTAMPTZ DEFAULT NOW(), expires_at TIMESTAMPTZ DEFAULT NOW() + INTERVAL '24 hours', UNIQUE(state_code, searched_name) ); CREATE INDEX IF NOT EXISTS idx_nsc_lookup ON name_search_cache (state_code, searched_name) WHERE expires_at > NOW(); -- Enable trigram extension if not already enabled CREATE EXTENSION IF NOT EXISTS pg_trgm;