diff --git a/ROADMAP.md b/ROADMAP.md index 3bd6f40..61f209f 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -107,6 +107,11 @@ Each milestone ends at a gate: tests run, results reported, and the maintainer a - **2026-10-20** — Search Console's crawl reports (#9) and the Bing sitemap (#7) leave M7 for later. Both wait on Google and Bing rather than on this project, and neither needs a change here: crawl requests are 99% OK, the one 404 is a guessed `/favicon.ico`, and Bing's live test fetches a convention page. That gives up a finished indexing report before the release. Page URLs freeze at 1.0, so if a report turns up a URL problem before then, it becomes an M8 issue. This replaces "the search-engine follow-ups" in the 2026-10-18 decision on M7. - **2026-10-20** — East Texas becomes the sixth region (#10), with its own page at `/regions/east-texas/` and its own feed, decided before 1.0 freezes the region URLs. It covers the Piney Woods (Tyler, Longview, Texarkana, Nacogdoches, Lufkin); Beaumont and Port Arthur stay Gulf Coast. Anime Tyler moves there from North Texas, so the North Texas feed stops carrying it, which the v1.0.0 notes must say. That gives a region page with one convention for now. The Panhandle gets no region, since nothing is listed there. This replaces the 2026-10-12 decision that put East Texas cities in North Texas. - **2026-10-20** — Each convention gets an archive page at `/cons//` (#12), from the convention's `slug`, beside its editions' pages (`/cons/odessa-geek-fest/` next to `/cons/odessa-geek-fest-2027/`). It lists the upcoming editions as cards, then every past one, and each edition page's breadcrumb links to it. Sharing `/cons/` reads as "the convention" and gives each one an address that stays the same from year to year. The cost is a validation rule that keeps convention and edition slugs apart; `/series//` would have needed none but uses an internal word. +- **2026-10-20** — The last review of the public contract before 1.0 (#38) looked at every page and feed URL pattern, the id rules and every field in `data/README.md`: + - **Changed:** a slug must match its id, so a page's URL keeps the id's promise never to change. Conventions lose `city` and `region`, which the site never read and nothing checked against their editions, so where a convention takes place comes only from its editions; that breaks the record format for data reusers, and the v1.0.0 notes must say so. `data/README.md` now lists every field. + - **Written down:** published records are never renamed or deleted; a cancelled edition is marked `cancelled` and a convention that stops is marked `ended`. A second edition in the same city and year adds the organizer's name for it (`example-con-winter-2027`). + - **Kept:** feeds are named by region id (`feeds/north.ics`) while region pages use the name (`/regions/north-texas/`); renaming either would break subscribers or links. Month pages (`/calendar/YYYY-MM/`) are a rolling window from the current month and outside the stable contract, so a past month's URL can stop resolving. + - **Moving:** the site gets its own domain before 1.0 (#47). Every page and feed URL includes the host, and moving after 1.0 would lean on redirects for every feed subscriber. Calendar UIDs don't include the host, so subscribed events aren't duplicated. - **2026-10-11** — `ROADMAP.md` lives at the repo root (the handoff suggested `docs/ROADMAP.md`) to match the maintainer's repo-first workflow. ## Shipped @@ -124,9 +129,9 @@ Each milestone's checklist and status report are in git history. ## Next -Open work is in [GitHub issues](https://github.com/hazeliscoding/conatlas-tx/issues), and the [project board](https://github.com/users/hazeliscoding/projects/8) shows where each one stands. The current milestone is [M8: settle the public contract and v1.0.0](https://github.com/hazeliscoding/conatlas-tx/milestone/3), the last milestone before 1.0: the regions question (#10), archive pages per series (#12), a last review of the contract (#38), maintenance that runs without being remembered (#11, #39), the next dates of conventions waiting on them (#33), and the v1.0.0 release (#40). +Open work is in [GitHub issues](https://github.com/hazeliscoding/conatlas-tx/issues), and the [project board](https://github.com/users/hazeliscoding/projects/8) shows where each one stands. The current milestone is [M8: settle the public contract and v1.0.0](https://github.com/hazeliscoding/conatlas-tx/milestone/3), the last milestone before 1.0: the regions question (#10), archive pages per series (#12), a last review of the contract (#38), maintenance that runs without being remembered (#11, #39), the next dates of conventions waiting on them (#33), a domain of its own (#47), and the v1.0.0 release (#40). -Done when: the regions question is decided, archive pages are live, the public contract (page and feed URLs, edition ids, the data format) has had its last review, data maintenance pings on its own, and v1.0.0 is published. +Done when: the regions question is decided, archive pages are live, the public contract (page and feed URLs, edition ids, the data format) has had its last review, the site is on its own domain, data maintenance pings on its own, and v1.0.0 is published. Issues without a milestone are ideas for later. diff --git a/data/README.md b/data/README.md index 7c199a5..accb225 100644 --- a/data/README.md +++ b/data/README.md @@ -18,8 +18,6 @@ id: example-con # stable forever; editions reference it slug: example-con # URL path name: Example Convention website: https://example.org -city: Houston -region: gulf-coast # north | east | central | gulf-coast | south | west status: active # active | hiatus | ended sources: - example-con-site # an id in sources/ @@ -62,9 +60,76 @@ supports: [existence, dates, venue, city] # existence, dates, venue, city, statu last_checked: 2026-10-11 # YYYY-MM-DD, last successful check ``` +## Every field + +Fields not marked optional are required. Dates are `YYYY-MM-DD` strings, URLs are `https://`, and text can't be empty. + +### Conventions + +| Field | What it holds | +| ------------- | -------------------------------------------------------------------------------------- | +| `id` | Stable forever; editions and sources reference it | +| `slug` | The page at `/cons//`; always the same as `id` | +| `name` | The convention's name as the organizer writes it | +| `description` | Optional. Up to 500 characters about the convention | +| `website` | The official site | +| `organizer` | Optional. Who runs it | +| `status` | `active`, `hiatus` or `ended` | +| `status_note` | Optional; required for `hiatus` and `ended`. A summary of the organizer's announcement | +| `sources` | Ids in `sources/` about the convention as a whole | + +Where a convention takes place is on its editions, since a touring convention has several cities. + +### Editions + +| Field | What it holds | +| ------------------- | -------------------------------------------------------------------------------------------------------------------------------- | +| `id` | Stable forever; saved lists and calendar UIDs use it | +| `series` | The convention's id | +| `edition` | The label after the name: `2026`, or `Houston 2027` for a touring convention | +| `slug` | The page at `/cons//`; always the same as `id` | +| `name` | Optional. A name for this edition when it differs from the convention's | +| `status` | `confirmed`, `dates_tba`, `postponed`, `cancelled` or `completed` | +| `status_note` | Optional; required for `postponed` and `cancelled`. A summary of the organizer's announcement | +| `start_date` | Optional. The first day the organizer advertises | +| `end_date` | Optional. The last day; left out for a one-day event | +| `announced_window` | Optional. Only what the organizer said, such as `Summer 2027`, never a guess | +| `venue` | Optional. `name`, and optionally `address` | +| `city` | The city, without "TX" | +| `region` | `north`, `east`, `central`, `gulf-coast`, `south` or `west` | +| `timezone` | `America/Chicago`, or `America/Denver` for far West Texas | +| `url` | The official page for this edition | +| `tickets_url` | Optional. The official ticket page | +| `min_age` | Optional. The organizer's minimum age to attend (18 for an 18+ convention) | +| `description` | Optional. Up to 500 characters about this edition | +| `evidence` | At least one: `source`, `facts`, `checked_at`, and optionally `excerpt` (up to 300 characters, the organizer's words) and `note` | +| `last_verified_at` | The last day the facts were confirmed against the evidence | +| `last_attempted_at` | Optional. The last check, including ones that failed | +| `updated_at` | The last edit to the file | +| `revision` | Starts at 0 and goes up by one whenever a published fact changes | + +### Sources + +| Field | What it holds | +| -------------- | ---------------------------------------------------------------------------------------------- | +| `id` | Stable forever; evidence cites it | +| `series` | The convention's id | +| `url` | The page | +| `type` | `official_site`, `official_announcement`, `official_feed`, `organizer_social` or `third_party` | +| `supports` | The facts it can back: `existence`, `dates`, `venue`, `city`, `status`, `tickets`, `age` | +| `last_checked` | The last day the page was checked successfully | +| `access_notes` | Optional. How the page can be read and where on it the facts are | +| `notes` | Optional | + +## Ids + +- A convention's id is its name in lowercase-kebab-case (`san-japan`). +- An edition's id is `-` (`san-japan-2027`), or `--` for a touring convention's city edition (`kimokawaii-conroe-2027`). A second edition in the same city and year adds the organizer's name for it (`example-con-winter-2027`). +- Published records are never renamed or deleted. A cancelled edition is marked `cancelled`, a convention that stops is marked `ended`, and an edition that ends stays as a past edition, so every page, saved list and calendar UID keeps working. + ## Rules the validator enforces -- IDs are lowercase-kebab-case and match the file name. IDs and slugs are unique, and a convention's slug never matches an edition's, since both pages live under `/cons/`. +- IDs are lowercase-kebab-case and match the file name, and a slug always matches its id. IDs and slugs are unique, and a convention's slug never matches an edition's, since both pages live under `/cons/`. - Every edition has evidence from an official source. Third-party listings never count. - Shown dates, venues and cancellation or postponement statuses each need official evidence for that fact. - `confirmed` and `completed` need dates; `dates_tba` must not have them; `completed` must be in the past. diff --git a/data/conventions/akatsuki-con.yaml b/data/conventions/akatsuki-con.yaml index a6c6beb..7ff9364 100644 --- a/data/conventions/akatsuki-con.yaml +++ b/data/conventions/akatsuki-con.yaml @@ -3,8 +3,6 @@ slug: akatsuki-con name: Akatsuki Con description: Akatsuki Con is a Naruto convention. website: https://akatsukicon.com/ -city: Pasadena -region: gulf-coast status: active sources: - akatsuki-con-site diff --git a/data/conventions/anime-at-the-modern.yaml b/data/conventions/anime-at-the-modern.yaml index ffa5f16..e759f82 100644 --- a/data/conventions/anime-at-the-modern.yaml +++ b/data/conventions/anime-at-the-modern.yaml @@ -3,8 +3,6 @@ slug: anime-at-the-modern name: Anime at the Modern website: https://www.themodern.org/anime-modern-2026 organizer: Modern Art Museum of Fort Worth -city: Fort Worth -region: north status: active sources: - anime-at-the-modern-site diff --git a/data/conventions/anime-by-the-bay.yaml b/data/conventions/anime-by-the-bay.yaml index efa6ec9..4cb41b1 100644 --- a/data/conventions/anime-by-the-bay.yaml +++ b/data/conventions/anime-by-the-bay.yaml @@ -3,8 +3,6 @@ slug: anime-by-the-bay name: Anime by the Bay description: Anime by the Bay is a one-day anime event in Palacios with vendors, music, food and a cosplay contest. website: https://www.instagram.com/animebythebay/ -city: Palacios -region: gulf-coast status: active sources: - anime-by-the-bay-instagram diff --git a/data/conventions/anime-dallas.yaml b/data/conventions/anime-dallas.yaml index ebba439..1b40d4d 100644 --- a/data/conventions/anime-dallas.yaml +++ b/data/conventions/anime-dallas.yaml @@ -2,8 +2,6 @@ id: anime-dallas slug: anime-dallas name: Anime Dallas website: https://animedallas.com/ -city: Frisco -region: north status: active sources: - anime-dallas-site diff --git a/data/conventions/anime-el-paso.yaml b/data/conventions/anime-el-paso.yaml index 0fe26df..cb03f6a 100644 --- a/data/conventions/anime-el-paso.yaml +++ b/data/conventions/anime-el-paso.yaml @@ -2,8 +2,6 @@ id: anime-el-paso slug: anime-el-paso name: Anime El Paso website: https://animeelpaso.com/ -city: El Paso -region: west status: active sources: - anime-el-paso-site diff --git a/data/conventions/anime-fiesta.yaml b/data/conventions/anime-fiesta.yaml index e2b5ba7..5292b05 100644 --- a/data/conventions/anime-fiesta.yaml +++ b/data/conventions/anime-fiesta.yaml @@ -2,8 +2,6 @@ id: anime-fiesta slug: anime-fiesta name: Anime Fiesta website: https://animefiesta.net/ -city: McAllen -region: south status: active sources: - anime-fiesta-site diff --git a/data/conventions/anime-frontier.yaml b/data/conventions/anime-frontier.yaml index 148839b..44a850b 100644 --- a/data/conventions/anime-frontier.yaml +++ b/data/conventions/anime-frontier.yaml @@ -3,8 +3,6 @@ slug: anime-frontier name: Anime Frontier website: https://animefrontier.com/ organizer: LeftField Media -city: Fort Worth -region: north status: active sources: - anime-frontier-faqs diff --git a/data/conventions/anime-matsuri.yaml b/data/conventions/anime-matsuri.yaml index fabd969..f5fdeda 100644 --- a/data/conventions/anime-matsuri.yaml +++ b/data/conventions/anime-matsuri.yaml @@ -2,8 +2,6 @@ id: anime-matsuri slug: anime-matsuri name: Anime Matsuri website: https://animematsuri.com/ -city: Houston -region: gulf-coast status: active sources: - anime-matsuri-site diff --git a/data/conventions/anime-mundo.yaml b/data/conventions/anime-mundo.yaml index eeca1f4..3e93b44 100644 --- a/data/conventions/anime-mundo.yaml +++ b/data/conventions/anime-mundo.yaml @@ -2,8 +2,6 @@ id: anime-mundo slug: anime-mundo name: Anime Mundo website: https://animemundo.com/ -city: El Paso -region: west status: active sources: - anime-mundo-site diff --git a/data/conventions/anime-north-texas.yaml b/data/conventions/anime-north-texas.yaml index 219fcb1..652eb5e 100644 --- a/data/conventions/anime-north-texas.yaml +++ b/data/conventions/anime-north-texas.yaml @@ -2,8 +2,6 @@ id: anime-north-texas slug: anime-north-texas name: Anime North Texas website: https://www.animenorthtexas.com/ -city: Irving -region: north status: active sources: - anime-north-texas-site diff --git a/data/conventions/anime-san-angelo.yaml b/data/conventions/anime-san-angelo.yaml index 383715a..f7e1973 100644 --- a/data/conventions/anime-san-angelo.yaml +++ b/data/conventions/anime-san-angelo.yaml @@ -3,8 +3,6 @@ slug: anime-san-angelo name: Anime San Angelo website: https://www.animesanangelo.com/ organizer: Galactic Events -city: San Angelo -region: west status: active sources: - anime-san-angelo-quicklink diff --git a/data/conventions/anime-sekai.yaml b/data/conventions/anime-sekai.yaml index 267de1e..b1c546c 100644 --- a/data/conventions/anime-sekai.yaml +++ b/data/conventions/anime-sekai.yaml @@ -3,8 +3,6 @@ slug: anime-sekai name: Anime Sekai website: https://animesekaitx.com/ organizer: Anime Sekai LLC -city: Abilene -region: west status: active sources: - anime-sekai-site diff --git a/data/conventions/anime-sunika.yaml b/data/conventions/anime-sunika.yaml index 7a0f239..7bbd256 100644 --- a/data/conventions/anime-sunika.yaml +++ b/data/conventions/anime-sunika.yaml @@ -2,8 +2,6 @@ id: anime-sunika slug: anime-sunika name: Anime Sunika website: https://www.animesunika.com/ -city: Belton -region: central status: active sources: - anime-sunika-site diff --git a/data/conventions/anime-tyler.yaml b/data/conventions/anime-tyler.yaml index 156a890..04d22e4 100644 --- a/data/conventions/anime-tyler.yaml +++ b/data/conventions/anime-tyler.yaml @@ -2,8 +2,6 @@ id: anime-tyler slug: anime-tyler name: Anime Tyler website: https://animetyler.com/ -city: Tyler -region: east status: active sources: - anime-tyler-site diff --git a/data/conventions/centex-anime-fest.yaml b/data/conventions/centex-anime-fest.yaml index 9cb1ad6..8f88253 100644 --- a/data/conventions/centex-anime-fest.yaml +++ b/data/conventions/centex-anime-fest.yaml @@ -3,8 +3,6 @@ slug: centex-anime-fest name: CenTex Anime Fest website: https://comanchecon.com/ organizer: Comanche Con -city: Comanche -region: central status: active sources: - centex-anime-fest-site diff --git a/data/conventions/colossalcon-texas.yaml b/data/conventions/colossalcon-texas.yaml index 35f077d..2e2c1c1 100644 --- a/data/conventions/colossalcon-texas.yaml +++ b/data/conventions/colossalcon-texas.yaml @@ -2,8 +2,6 @@ id: colossalcon-texas slug: colossalcon-texas name: Colossalcon Texas website: https://colossalcontexas.com/ -city: Round Rock -region: central status: active sources: - colossalcon-texas-site diff --git a/data/conventions/delta-h-con.yaml b/data/conventions/delta-h-con.yaml index b2f7895..98e16c0 100644 --- a/data/conventions/delta-h-con.yaml +++ b/data/conventions/delta-h-con.yaml @@ -3,8 +3,6 @@ slug: delta-h-con name: Delta H Con website: https://deltahcon.com/ organizer: Stardust Entertainment, LLC -city: Houston -region: gulf-coast status: active sources: - delta-h-con-site diff --git a/data/conventions/ecchi-fiesta.yaml b/data/conventions/ecchi-fiesta.yaml index 26ddde6..c3915bb 100644 --- a/data/conventions/ecchi-fiesta.yaml +++ b/data/conventions/ecchi-fiesta.yaml @@ -2,8 +2,6 @@ id: ecchi-fiesta slug: ecchi-fiesta name: Ecchi Fiesta website: https://www.ecchifiesta.com/ -city: San Antonio -region: south status: active sources: - ecchi-fiesta-site diff --git a/data/conventions/halloweebtown.yaml b/data/conventions/halloweebtown.yaml index a837815..084177b 100644 --- a/data/conventions/halloweebtown.yaml +++ b/data/conventions/halloweebtown.yaml @@ -2,8 +2,6 @@ id: halloweebtown slug: halloweebtown name: Halloweebtown website: https://www.halloweebtown.com/ -city: Grapevine -region: north status: active sources: - halloweebtown-site diff --git a/data/conventions/ikkicon.yaml b/data/conventions/ikkicon.yaml index 781b678..2e70f47 100644 --- a/data/conventions/ikkicon.yaml +++ b/data/conventions/ikkicon.yaml @@ -2,8 +2,6 @@ id: ikkicon slug: ikkicon name: IKKiCON website: https://www.ikkicon.com/ -city: Round Rock -region: central status: active sources: - ikkicon-site diff --git a/data/conventions/kameha-con.yaml b/data/conventions/kameha-con.yaml index 96d4e8d..6c63c74 100644 --- a/data/conventions/kameha-con.yaml +++ b/data/conventions/kameha-con.yaml @@ -2,8 +2,6 @@ id: kameha-con slug: kameha-con name: Kameha Con website: https://kamehacon.com/ -city: San Antonio -region: south status: active sources: - kameha-con-site diff --git a/data/conventions/komori-con.yaml b/data/conventions/komori-con.yaml index 2393582..ff54d3a 100644 --- a/data/conventions/komori-con.yaml +++ b/data/conventions/komori-con.yaml @@ -2,8 +2,6 @@ id: komori-con slug: komori-con name: Kōmori Con website: https://www.komoricon.com/ -city: Austin -region: central status: active sources: - komori-con-faqs diff --git a/data/conventions/moricon.yaml b/data/conventions/moricon.yaml index 3e5fe5e..5a6876a 100644 --- a/data/conventions/moricon.yaml +++ b/data/conventions/moricon.yaml @@ -3,8 +3,6 @@ slug: moricon name: MoriCon website: https://www.thewoodlandstownship-tx.gov/Events-directory/2025/September/091325-MoriCon organizer: The Woodlands Township Parks and Recreation Department -city: The Woodlands -region: gulf-coast status: active sources: - moricon-2025-event diff --git a/data/conventions/odessa-geek-fest.yaml b/data/conventions/odessa-geek-fest.yaml index 30b3aee..1a207a1 100644 --- a/data/conventions/odessa-geek-fest.yaml +++ b/data/conventions/odessa-geek-fest.yaml @@ -3,8 +3,6 @@ slug: odessa-geek-fest name: Odessa Geek Fest website: https://www.odessageekfest.com/ organizer: Sukeban Entertainment LLC -city: Odessa -region: west status: active sources: - odessa-geek-fest-site diff --git a/data/conventions/oni-con.yaml b/data/conventions/oni-con.yaml index 2267d41..d9bd89e 100644 --- a/data/conventions/oni-con.yaml +++ b/data/conventions/oni-con.yaml @@ -2,8 +2,6 @@ id: oni-con slug: oni-con name: Oni-Con website: https://oni-con.net/ -city: Houston -region: gulf-coast status: active sources: - oni-con-site diff --git a/data/conventions/otaku-odyssey.yaml b/data/conventions/otaku-odyssey.yaml index 0e089f6..451f6f4 100644 --- a/data/conventions/otaku-odyssey.yaml +++ b/data/conventions/otaku-odyssey.yaml @@ -2,8 +2,6 @@ id: otaku-odyssey slug: otaku-odyssey name: Otaku Odyssey website: https://www.otaku-odyssey.com/ -city: Mesquite -region: north status: active sources: - otaku-odyssey-site diff --git a/data/conventions/pop-city-con.yaml b/data/conventions/pop-city-con.yaml index 71d21d1..77cfda8 100644 --- a/data/conventions/pop-city-con.yaml +++ b/data/conventions/pop-city-con.yaml @@ -4,8 +4,6 @@ name: Pop City Con description: 'Pop City Con is a women-owned anime, K-pop and gaming convention in El Paso, where, in its own words, "K-pop, anime, and books collide".' website: https://www.popcitycon.net/ organizer: Pop City Events LLC -city: El Paso -region: west status: active sources: - pop-city-con-site diff --git a/data/conventions/riverwalk-anime.yaml b/data/conventions/riverwalk-anime.yaml index 9bf52de..6f30ab5 100644 --- a/data/conventions/riverwalk-anime.yaml +++ b/data/conventions/riverwalk-anime.yaml @@ -2,8 +2,6 @@ id: riverwalk-anime slug: riverwalk-anime name: Riverwalk Anime website: https://www.riverwalkanime.com/ -city: San Antonio -region: south status: active sources: - riverwalk-anime-site diff --git a/data/conventions/san-japan.yaml b/data/conventions/san-japan.yaml index 716b5f1..b0a3acd 100644 --- a/data/conventions/san-japan.yaml +++ b/data/conventions/san-japan.yaml @@ -2,8 +2,6 @@ id: san-japan slug: san-japan name: San Japan website: https://www.san-japan.org/ -city: San Antonio -region: south status: active sources: - san-japan-site diff --git a/data/conventions/star-con-texas.yaml b/data/conventions/star-con-texas.yaml index 0434c20..c0c478a 100644 --- a/data/conventions/star-con-texas.yaml +++ b/data/conventions/star-con-texas.yaml @@ -3,8 +3,6 @@ slug: star-con-texas name: Star Con Texas website: https://www.starcontexas.com/ organizer: The Starving Artist -city: Portland -region: south status: active sources: - star-con-texas-site diff --git a/data/conventions/tokyo-x.yaml b/data/conventions/tokyo-x.yaml index 705b871..75f48c3 100644 --- a/data/conventions/tokyo-x.yaml +++ b/data/conventions/tokyo-x.yaml @@ -2,8 +2,6 @@ id: tokyo-x slug: tokyo-x name: Tokyo X website: https://www.tokyonightfest.com/ -city: Houston -region: gulf-coast status: active sources: - tokyo-x-site diff --git a/data/conventions/tsumicon-texas.yaml b/data/conventions/tsumicon-texas.yaml index 6e648e3..87f8cb9 100644 --- a/data/conventions/tsumicon-texas.yaml +++ b/data/conventions/tsumicon-texas.yaml @@ -2,8 +2,6 @@ id: tsumicon-texas slug: tsumicon-texas name: TsumiCon Texas website: https://tsumicon.com/ -city: Houston -region: gulf-coast status: active sources: - tsumicon-texas-site diff --git a/data/conventions/ushicon.yaml b/data/conventions/ushicon.yaml index 0bed99c..8780947 100644 --- a/data/conventions/ushicon.yaml +++ b/data/conventions/ushicon.yaml @@ -3,8 +3,6 @@ slug: ushicon name: Ushicon description: Ushicon is a convention for fans 18 and up. website: https://www.ushicon.com/ -city: Austin -region: central status: active sources: - ushicon-site diff --git a/data/conventions/weebcon.yaml b/data/conventions/weebcon.yaml index 274444a..08da84d 100644 --- a/data/conventions/weebcon.yaml +++ b/data/conventions/weebcon.yaml @@ -2,8 +2,6 @@ id: weebcon slug: weebcon name: WeebCon website: https://weebcon.net/ -city: Grapevine -region: north status: active sources: - weebcon-site diff --git a/data/conventions/yumicon.yaml b/data/conventions/yumicon.yaml index b241887..f2debfb 100644 --- a/data/conventions/yumicon.yaml +++ b/data/conventions/yumicon.yaml @@ -2,8 +2,6 @@ id: yumicon slug: yumicon name: YUMiCON website: https://www.yumicon.com/ -city: San Antonio -region: south status: active sources: - yumicon-site diff --git a/packages/core/src/schema.ts b/packages/core/src/schema.ts index 511909c..a773ad7 100644 --- a/packages/core/src/schema.ts +++ b/packages/core/src/schema.ts @@ -72,8 +72,6 @@ export const SeriesSchema = z.strictObject({ description: text.max(500).optional(), website: url, organizer: text.optional(), - city: text.optional(), - region: z.enum(REGIONS).optional(), status: z.enum(SERIES_STATUSES), /** For a series on hiatus or ended: a summary of the organizer's announcement. */ status_note: text.optional(), diff --git a/packages/core/src/validate.ts b/packages/core/src/validate.ts index 634d6ee..0d09630 100644 --- a/packages/core/src/validate.ts +++ b/packages/core/src/validate.ts @@ -29,6 +29,11 @@ export function validateDataset(data: Dataset, today: IsoDate): Issue[] { for (const id of duplicates(records.map((r) => r.id))) error(`${dir}/${id}`, `duplicate id "${id}"`); } + // A page's URL keeps the id's promise never to change. + for (const [dir, records] of [kinds[0], kinds[1]]) { + for (const r of records) + if (r.slug !== r.id) error(`${dir}/${r.id}`, `slug "${r.slug}" must match the id`); + } // Convention and edition pages share /cons//, so a slug is unique across both. for (const slug of duplicates([...data.series, ...data.editions].map((r) => r.slug))) { const dir = data.editions.some((e) => e.slug === slug) ? 'editions' : 'conventions'; diff --git a/packages/core/test/core.test.ts b/packages/core/test/core.test.ts index e3c5b91..c036218 100644 --- a/packages/core/test/core.test.ts +++ b/packages/core/test/core.test.ts @@ -227,6 +227,9 @@ describe('validateDataset', () => { expect(errorsFor({ slug: 'lone-star-anime-fest-2027' })).toContain( 'editions/lone-star-anime-fest-2027: slug "lone-star-anime-fest-2027" is used by more than one record', ); + expect(errorsFor({ slug: 'lone-star-2026' })).toContain( + `${ed2026}: slug "lone-star-2026" must match the id`, + ); // A convention's archive page and an edition's page would share /cons//. expect(errorsFor({ slug: 'lone-star-anime-fest' })).toContain( 'editions/lone-star-anime-fest: slug "lone-star-anime-fest" is used by more than one record', diff --git a/packages/core/test/fixtures/data/conventions/lone-star-anime-fest.yaml b/packages/core/test/fixtures/data/conventions/lone-star-anime-fest.yaml index 55a389e..152891d 100644 --- a/packages/core/test/fixtures/data/conventions/lone-star-anime-fest.yaml +++ b/packages/core/test/fixtures/data/conventions/lone-star-anime-fest.yaml @@ -3,8 +3,6 @@ id: lone-star-anime-fest slug: lone-star-anime-fest name: Lone Star Anime Fest website: https://example.org/lone-star-anime-fest -city: Austin -region: central status: active sources: - lone-star-anime-fest-site diff --git a/packages/ingestion/test/cli.test.ts b/packages/ingestion/test/cli.test.ts index 37b08e7..6df8ae3 100644 --- a/packages/ingestion/test/cli.test.ts +++ b/packages/ingestion/test/cli.test.ts @@ -55,8 +55,6 @@ describe('data:diff', () => { slug: lone-star-anime-festival name: Lone Star Anime Festival website: https://www.example.org/lsaf - city: Austin - region: central status: active Verification sources: [lone-star-anime-festival-site] diff --git a/packages/ingestion/test/fixtures/data/conventions/lone-star-anime-fest.yaml b/packages/ingestion/test/fixtures/data/conventions/lone-star-anime-fest.yaml index 55a389e..152891d 100644 --- a/packages/ingestion/test/fixtures/data/conventions/lone-star-anime-fest.yaml +++ b/packages/ingestion/test/fixtures/data/conventions/lone-star-anime-fest.yaml @@ -3,8 +3,6 @@ id: lone-star-anime-fest slug: lone-star-anime-fest name: Lone Star Anime Fest website: https://example.org/lone-star-anime-fest -city: Austin -region: central status: active sources: - lone-star-anime-fest-site diff --git a/packages/ingestion/test/fixtures/data/drafts/conventions/lone-star-anime-festival.yaml b/packages/ingestion/test/fixtures/data/drafts/conventions/lone-star-anime-festival.yaml index e9eaa38..80ffca6 100644 --- a/packages/ingestion/test/fixtures/data/drafts/conventions/lone-star-anime-festival.yaml +++ b/packages/ingestion/test/fixtures/data/drafts/conventions/lone-star-anime-festival.yaml @@ -3,8 +3,6 @@ id: lone-star-anime-festival slug: lone-star-anime-festival name: Lone Star Anime Festival website: https://www.example.org/lsaf -city: Austin -region: central status: active sources: - lone-star-anime-festival-site