Files
cannaiq/backend/migrations/052_add_state_cannabis_flags.sql
Kelly b4a2fb7d03 feat: Add v2 architecture with multi-state support and orchestrator services
Major additions:
- Multi-state expansion: states table, StateSelector, NationalDashboard, StateHeatmap, CrossStateCompare
- Orchestrator services: trace service, error taxonomy, retry manager, proxy rotator
- Discovery system: dutchie discovery service, geo validation, city seeding scripts
- Analytics infrastructure: analytics v2 routes, brand/pricing/stores intelligence pages
- Local development: setup-local.sh starts all 5 services (postgres, backend, cannaiq, findadispo, findagram)
- Migrations 037-056: crawler profiles, states, analytics indexes, worker metadata

Frontend pages added:
- Discovery, ChainsDashboard, IntelligenceBrands, IntelligencePricing, IntelligenceStores
- StateHeatmap, CrossStateCompare, SyncInfoPanel

Components added:
- StateSelector, OrchestratorTraceModal, WorkflowStepper

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 11:30:57 -07:00

128 lines
7.0 KiB
SQL

-- ============================================================================
-- Migration 052: Add Cannabis Legalization Flags to States
-- ============================================================================
--
-- Purpose: Add recreational/medical cannabis legalization status and years
-- to the existing states table, then seed all 50 states + DC.
--
-- SAFETY RULES:
-- - Uses ADD COLUMN IF NOT EXISTS (idempotent)
-- - Uses INSERT ... ON CONFLICT (code) DO UPDATE (idempotent)
-- - NO DROP, DELETE, TRUNCATE, or destructive operations
-- - Safe to run multiple times
--
-- Run with:
-- psql "$DATABASE_URL" -f migrations/052_add_state_cannabis_flags.sql
--
-- ============================================================================
-- ============================================================================
-- SECTION 1: Add cannabis legalization columns
-- ============================================================================
ALTER TABLE states ADD COLUMN IF NOT EXISTS recreational_legal BOOLEAN;
ALTER TABLE states ADD COLUMN IF NOT EXISTS rec_year INTEGER;
ALTER TABLE states ADD COLUMN IF NOT EXISTS medical_legal BOOLEAN;
ALTER TABLE states ADD COLUMN IF NOT EXISTS med_year INTEGER;
COMMENT ON COLUMN states.recreational_legal IS 'Whether recreational cannabis is legal in this state';
COMMENT ON COLUMN states.rec_year IS 'Year recreational cannabis was legalized (NULL if not legal)';
COMMENT ON COLUMN states.medical_legal IS 'Whether medical cannabis is legal in this state';
COMMENT ON COLUMN states.med_year IS 'Year medical cannabis was legalized (NULL if not legal)';
-- ============================================================================
-- SECTION 2: Seed all 50 states + DC with cannabis legalization data
-- ============================================================================
-- Data sourced from state legalization records as of 2024
-- States ordered by medical legalization year, then alphabetically
INSERT INTO states (code, name, timezone, recreational_legal, rec_year, medical_legal, med_year)
VALUES
-- Recreational + Medical States (ordered by rec year)
('WA', 'Washington', 'America/Los_Angeles', TRUE, 2012, TRUE, 1998),
('CO', 'Colorado', 'America/Denver', TRUE, 2012, TRUE, 2000),
('AK', 'Alaska', 'America/Anchorage', TRUE, 2014, TRUE, 1998),
('OR', 'Oregon', 'America/Los_Angeles', TRUE, 2014, TRUE, 1998),
('DC', 'District of Columbia', 'America/New_York', TRUE, 2015, TRUE, 2011),
('CA', 'California', 'America/Los_Angeles', TRUE, 2016, TRUE, 1996),
('NV', 'Nevada', 'America/Los_Angeles', TRUE, 2016, TRUE, 1998),
('ME', 'Maine', 'America/New_York', TRUE, 2016, TRUE, 1999),
('MA', 'Massachusetts', 'America/New_York', TRUE, 2016, TRUE, 2012),
('MI', 'Michigan', 'America/Detroit', TRUE, 2018, TRUE, 2008),
('IL', 'Illinois', 'America/Chicago', TRUE, 2019, TRUE, 2013),
('AZ', 'Arizona', 'America/Phoenix', TRUE, 2020, TRUE, 2010),
('MT', 'Montana', 'America/Denver', TRUE, 2020, TRUE, 2004),
('NJ', 'New Jersey', 'America/New_York', TRUE, 2020, TRUE, 2010),
('VT', 'Vermont', 'America/New_York', TRUE, 2020, TRUE, 2004),
('CT', 'Connecticut', 'America/New_York', TRUE, 2021, TRUE, 2012),
('NM', 'New Mexico', 'America/Denver', TRUE, 2021, TRUE, 2007),
('NY', 'New York', 'America/New_York', TRUE, 2021, TRUE, 2014),
('VA', 'Virginia', 'America/New_York', TRUE, 2021, TRUE, 2020),
('MD', 'Maryland', 'America/New_York', TRUE, 2022, TRUE, 2013),
('MO', 'Missouri', 'America/Chicago', TRUE, 2022, TRUE, 2018),
('RI', 'Rhode Island', 'America/New_York', TRUE, 2022, TRUE, 2006),
('DE', 'Delaware', 'America/New_York', TRUE, 2023, TRUE, 2011),
('MN', 'Minnesota', 'America/Chicago', TRUE, 2023, TRUE, 2014),
('OH', 'Ohio', 'America/New_York', TRUE, 2023, TRUE, 2016),
-- Medical Only States (no recreational)
('HI', 'Hawaii', 'Pacific/Honolulu', FALSE, NULL, TRUE, 2000),
('NH', 'New Hampshire', 'America/New_York', FALSE, NULL, TRUE, 2013),
('GA', 'Georgia', 'America/New_York', FALSE, NULL, TRUE, 2015),
('LA', 'Louisiana', 'America/Chicago', FALSE, NULL, TRUE, 2015),
('TX', 'Texas', 'America/Chicago', FALSE, NULL, TRUE, 2015),
('AR', 'Arkansas', 'America/Chicago', FALSE, NULL, TRUE, 2016),
('FL', 'Florida', 'America/New_York', FALSE, NULL, TRUE, 2016),
('ND', 'North Dakota', 'America/Chicago', FALSE, NULL, TRUE, 2016),
('PA', 'Pennsylvania', 'America/New_York', FALSE, NULL, TRUE, 2016),
('IA', 'Iowa', 'America/Chicago', FALSE, NULL, TRUE, 2017),
('WV', 'West Virginia', 'America/New_York', FALSE, NULL, TRUE, 2017),
('OK', 'Oklahoma', 'America/Chicago', FALSE, NULL, TRUE, 2018),
('UT', 'Utah', 'America/Denver', FALSE, NULL, TRUE, 2018),
('SD', 'South Dakota', 'America/Chicago', FALSE, NULL, TRUE, 2020),
('AL', 'Alabama', 'America/Chicago', FALSE, NULL, TRUE, 2021),
('MS', 'Mississippi', 'America/Chicago', FALSE, NULL, TRUE, 2022),
('KY', 'Kentucky', 'America/New_York', FALSE, NULL, TRUE, 2023),
('NE', 'Nebraska', 'America/Chicago', FALSE, NULL, TRUE, 2024),
-- No Cannabis Programs (neither rec nor medical)
('ID', 'Idaho', 'America/Boise', FALSE, NULL, FALSE, NULL),
('IN', 'Indiana', 'America/Indiana/Indianapolis', FALSE, NULL, FALSE, NULL),
('KS', 'Kansas', 'America/Chicago', FALSE, NULL, FALSE, NULL),
('NC', 'North Carolina', 'America/New_York', FALSE, NULL, FALSE, NULL),
('SC', 'South Carolina', 'America/New_York', FALSE, NULL, FALSE, NULL),
('TN', 'Tennessee', 'America/Chicago', FALSE, NULL, FALSE, NULL),
('WI', 'Wisconsin', 'America/Chicago', FALSE, NULL, FALSE, NULL),
('WY', 'Wyoming', 'America/Denver', FALSE, NULL, FALSE, NULL)
ON CONFLICT (code) DO UPDATE SET
name = EXCLUDED.name,
timezone = COALESCE(states.timezone, EXCLUDED.timezone),
recreational_legal = EXCLUDED.recreational_legal,
rec_year = EXCLUDED.rec_year,
medical_legal = EXCLUDED.medical_legal,
med_year = EXCLUDED.med_year,
updated_at = NOW();
-- ============================================================================
-- SECTION 3: Add indexes for common queries
-- ============================================================================
CREATE INDEX IF NOT EXISTS idx_states_recreational ON states(recreational_legal) WHERE recreational_legal = TRUE;
CREATE INDEX IF NOT EXISTS idx_states_medical ON states(medical_legal) WHERE medical_legal = TRUE;
-- ============================================================================
-- SECTION 4: Verification query (informational only)
-- ============================================================================
SELECT
'Migration 052 completed successfully.' AS status,
(SELECT COUNT(*) FROM states WHERE recreational_legal = TRUE) AS rec_states,
(SELECT COUNT(*) FROM states WHERE medical_legal = TRUE AND recreational_legal = FALSE) AS med_only_states,
(SELECT COUNT(*) FROM states WHERE medical_legal = FALSE OR medical_legal IS NULL) AS no_program_states,
(SELECT COUNT(*) FROM states) AS total_states;