Derived from 37 migration files (migrations/*.sql, applied in name order). 14 tables + 2 virtual.
erDiagram
spots {
INTEGER id PK
TEXT slug
TEXT name
TEXT country_code
TEXT region
REAL latitude
REAL longitude
TEXT summary
TEXT body
TEXT wave_type
TEXT skill_level
TEXT best_months
TEXT created_at
TEXT updated_at
TEXT tier
TEXT source
}
tags {
INTEGER id PK
TEXT name
}
spot_tags {
INTEGER spot_id PK,FK
INTEGER tag_id PK,FK
}
spot_images {
INTEGER id PK
INTEGER spot_id FK
TEXT url
TEXT alt_text
INTEGER sort_order
TEXT credit
TEXT qa_tier
}
clips {
INTEGER id PK
TEXT slug
TEXT title
TEXT r2_key
TEXT upload_date
INTEGER featured
}
quotes {
INTEGER id PK
TEXT slug
TEXT text
TEXT author
INTEGER surfer_id
TEXT category
TEXT source
TEXT source_url
TEXT credit
INTEGER featured
TEXT created_at
}
surfers {
INTEGER id PK
TEXT slug
TEXT name
TEXT country_code
TEXT region
INTEGER birth_year
INTEGER death_year
TEXT stance
TEXT discipline
TEXT era
TEXT summary
TEXT body
TEXT tier
TEXT source
TEXT source_url
TEXT created_at
TEXT updated_at
}
surfer_images {
INTEGER id PK
INTEGER surfer_id FK
TEXT url
TEXT alt_text
INTEGER sort_order
TEXT credit
TEXT license
}
surfer_spots {
INTEGER surfer_id PK,FK
INTEGER spot_id PK,FK
TEXT relation
}
instagram_feed_cache {
INTEGER id PK
TEXT payload
TEXT fetched_at
}
instagram_account_scores {
TEXT handle PK
TEXT scored_at PK
INTEGER ok
INTEGER followers
TEXT last_post_at
REAL avg_engagement
REAL engagement_rate
INTEGER active
REAL score
}
instagram_curated_accounts {
TEXT handle PK
INTEGER enabled
INTEGER priority
TEXT note
TEXT added_at
}
instagram_publish_log {
TEXT published_date PK
TEXT quote_slug
TEXT ig_media_id
TEXT created_at
}
instagram_publish_config {
INTEGER id PK
INTEGER enabled
}
spots ||--o{ spot_tags : "spot_id"
tags ||--o{ spot_tags : "tag_id"
spots ||--o{ spot_images : "spot_id"
surfers ||--o{ surfer_images : "surfer_id"
surfers ||--o{ surfer_spots : "surfer_id"
spots ||--o{ surfer_spots : "spot_id"
spots_fts (FTS5)surfers_fts (FTS5)