● Zion Boggan
repos/Drophawk/backend/migrations/20260101000003_events.sql
zionboggan.com ↗
44 lines · sql
History for this file →
1
CREATE TABLE events (
2
    id                   BIGSERIAL PRIMARY KEY,
3
    source_id            TEXT NOT NULL REFERENCES sources(id) ON DELETE RESTRICT,
4
    source_event_id      TEXT NOT NULL,
5
    title                TEXT NOT NULL CHECK (length(title) BETWEEN 1 AND 512),
6
    subtitle             TEXT,
7
    category             TEXT NOT NULL CHECK (category IN ('concert','sports','festival','theater','other')),
8
    sport                TEXT CHECK (sport IS NULL OR sport IN ('nfl','nba','nhl','mlb','tennis','f1','soccer','golf','boxing','other')),
9
    starts_at            TIMESTAMPTZ,
10
    venue_name           TEXT,
11
    city                 TEXT,
12
    country              CHAR(2),
13
    latitude             DOUBLE PRECISION CHECK (latitude IS NULL OR (latitude BETWEEN -90 AND 90)),
14
    longitude            DOUBLE PRECISION CHECK (longitude IS NULL OR (longitude BETWEEN -180 AND 180)),
15
    image_url            TEXT,
16
    on_sale_at           TIMESTAMPTZ,
17
    presale_on_sale_at   TIMESTAMPTZ,
18
    status               TEXT NOT NULL CHECK (status IN ('announced','presale','onsale','soldout','cancelled')),
19
    price_min            INTEGER CHECK (price_min IS NULL OR price_min >= 0),
20
    price_max            INTEGER CHECK (price_max IS NULL OR price_max >= 0),
21
    currency             CHAR(3),
22
    inventory_remaining  INTEGER CHECK (inventory_remaining IS NULL OR inventory_remaining >= 0),
23
    buy_url              TEXT NOT NULL,
24
    raw                  JSONB,
25
    content_hash         CHAR(64) NOT NULL,
26
    first_seen_at        TIMESTAMPTZ NOT NULL DEFAULT NOW(),
27
    updated_at           TIMESTAMPTZ NOT NULL DEFAULT NOW(),
28
    UNIQUE (source_id, source_event_id),
29
    CONSTRAINT price_range CHECK (price_min IS NULL OR price_max IS NULL OR price_min <= price_max)
30
);
31
 
32
CREATE INDEX idx_events_status           ON events(status);
33
CREATE INDEX idx_events_on_sale          ON events(on_sale_at) WHERE on_sale_at IS NOT NULL;
34
CREATE INDEX idx_events_category         ON events(category);
35
CREATE INDEX idx_events_sport            ON events(sport) WHERE sport IS NOT NULL;
36
CREATE INDEX idx_events_starts_at        ON events(starts_at) WHERE starts_at IS NOT NULL;
37
CREATE INDEX idx_events_source_status    ON events(source_id, status);
38
CREATE INDEX idx_events_updated_at       ON events(updated_at DESC);
39
CREATE INDEX idx_events_title_trgm       ON events USING gin (title gin_trgm_ops);
40
CREATE INDEX idx_events_starts_at_source ON events(starts_at, source_id);
41
 
42
CREATE TRIGGER events_set_updated_at
43
    BEFORE UPDATE ON events
44
    FOR EACH ROW EXECUTE FUNCTION set_updated_at();