Skip to content

feat: serve event firmware metadata at GET resource/eventFirmware#97

Draft
jamesarich wants to merge 5 commits into
masterfrom
feat/event-firmware-resource
Draft

feat: serve event firmware metadata at GET resource/eventFirmware#97
jamesarich wants to merge 5 commits into
masterfrom
feat/event-firmware-resource

Conversation

@jamesarich

@jamesarich jamesarich commented Jun 23, 2026

Copy link
Copy Markdown

Adds GET resource/eventFirmware, the API endpoint anticipated by the event-firmware contract in Meshtastic-Android#5920.

That PR defined the JSON Schema and a bundled seed asset but deliberately left the upstream endpoint as a follow-up. This is that follow-up, plus the first hosted event icon.

Endpoints

  • GET resource/eventFirmware — returns the {version, generatedAt, source, editions[]} envelope (mirroring deviceLinks). The seed JSON is already in response shape, so it is served verbatim — no transformation.
  • GET resource/eventFirmware/hamvention.png — serves the Hamvention event icon (PNG).

What this does

  • data/eventFirmware.json — seed metadata for the 4 current editions (Hamvention, Open Sauce, DEFCON, Burning Man). This repo becomes the source of truth the app will sync from.
  • src/lib/eventFirmware.ts — reads + parses the file once per process.
  • src/routes/eventFirmware.ts — serves the metadata, 502 on read failure.
  • static/eventFirmware/hamvention.png + src/routes/eventFirmwareIcon.ts — vendors and serves the Hamvention icon. Renamed from Android's img_event_hamvention.png to drop the drawable-resource prefix; grouped under eventFirmware/ and served under resource/ (same data/resource/* indirection as deviceLinks).

Seed data — verified against official sources

All fields were fact-checked via web search; several seed values were corrected:

Field Result
eventStart/eventEnd All 4 verified. Open Sauce start corrected 07-1807-17 (official festival is July 17–19; the 17th is Industry Day).
location / timeZone / links All 4 correct.
accentColor Hamvention #005DAA#BF1E2E (was blue; official logo is a red Ohio badge — sampled from the logo PNG). DEFCON #C0392B#0D294A (was a Flat-UI placeholder; DC34 style-guide primary). Burning Man #E8552D#EC8819 (official Carrot Orange). Open Sauce #E94F1D kept — its logo is monochrome, no brand color exists.
iconUrl Hamvention now points at the hosted icon above. The other three stay null — they have no bundled art in the app (EventEdition.kt: iconRes = null), and their official logos are unusable to vendor (Burning Man's trademark policy forbids promotional use; DEFCON/Open Sauce publish no openly-licensed assets). Original Meshtastic art is the path forward there, matching the Hamvention precedent.

Not in this PR (deferred, matching the Android PR's staging)

  • Schema validation in CI.
  • A real upstream data sync — generatedAt/source come from the committed snapshot.
  • Icons for the other three editions (pending original art).

Notes

  • iconUrl hardcodes https://api.meshtastic.org, consistent with how deviceLinks hardcodes msh.to URLs.
  • The icon route is a single fixed path for the one icon hosted today; generalize to a slug param when more editions ship art (marked with a ponytail: comment).

Testing

  • biome clean; tsc clean (one pre-existing unrelated error in yieldFromEvent.ts).
  • Metadata lib smoke-tested to parse and return all 4 editions; icon file verified to resolve as a valid PNG via the route's path resolution. Full server not booted (requires Redis/MQTT).

🤖 Generated with Claude Code

jamesarich and others added 5 commits June 23, 2026 16:59
Adds the API endpoint anticipated by the event-firmware contract in
meshtastic/Meshtastic-Android#5920, which defined the JSON Schema and a
bundled seed asset but left the upstream endpoint as a follow-up.

- data/eventFirmware.json: seed metadata for the 4 current editions,
  copied verbatim from the Android PR's bundled asset.
- src/lib/eventFirmware.ts: reads + parses the file once per process.
- src/routes/eventFirmware.ts: serves it at resource/eventFirmware.

The seed JSON is already in the {version, generatedAt, source, editions[]}
envelope (mirroring deviceLinks), so it is served verbatim with no transform.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tart)

Verified all four edition dates against official sources via web search.
Open Sauce is officially July 17-19 (July 17 is Industry Day); the seed
had 07-18 (main public days only). Other three editions confirmed correct.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DEFCON #C0392B was a Flat-UI placeholder; replaced with #0D294A, the primary
color from DEF CON 34's official style guide. Burning Man #E8552D replaced
with #EC8819 (official Carrot Orange). Hamvention/Open Sauce accent colors
have no published brand hex; left as plausible placeholders.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…l logo)

Hamvention's official primary logo is a red Ohio-shaped badge (#BF1E2E),
not blue; the seed's #005DAA was wrong. Sampled directly from the logo PNG
published at hamvention.org/logos. Open Sauce's logo is monochrome black/white
with no brand color, so its accent stays a best-guess orange placeholder.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Hamvention is the only edition with bundled art in Meshtastic-Android
(EventEdition.kt; the others are iconRes = null). Vendors the PNG into
static/eventFirmware/hamvention.png and serves it at
resource/eventFirmware/hamvention.png, mirroring how data/ files map to
resource/* routes. Renamed from Android's img_event_hamvention.png to drop
the drawable-resource prefix. HAMVENTION.iconUrl now points at it; the other
three editions stay null until they have art.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jamesarich

Copy link
Copy Markdown
Author

@thebentern noted that we have additional metadata in the flasher that could be housed here as well

@jamesarich

jamesarich commented Jun 24, 2026

Copy link
Copy Markdown
Author

Follow-up scoping: moving flasher event config into this API

Per @thebentern's suggestion, looked at moving event-manifest config out of web-flasher and into this API. Summary for tracking — assessment only, nothing built here.

What's movable

The flasher hardcodes per-event EventModeConfig objects in types/resources.ts and selects the active one via export const eventMode = …. Every event switch is a code edit + redeploy. The flasher already calls api.meshtastic.org for hardware/firmware lists, so serving this config from the API is a natural fit and removes the redeploy-per-event friction.

Per-event payload that would move: domain, enabled/active selection, eventName, eventTag, pathPrefix (builds the firmware URL event/{pathPrefix}/firmware-{ver}), and firmware (id, title, zip_url, a long markdown release_notes).

Recommendation: a separate endpoint, not an extension of eventFirmware

The two "event" datasets look related but are different concerns:

eventFirmware (this PR, Android contract) flasher eventMode
Purpose in-app display / theming which firmware to flash + flasher branding
Fields edition, displayName, welcomeMessage, dates, tz, location, iconUrl, accentColor, links domain, pathPrefix, firmware zip_url, release_notes, eventTag
Event set Hamvention, Open Sauce, DEFCON, Burning Man Hamcation, Hamvention
Contract frozen JSON Schema, additionalProperties: false none yet

Near-zero field overlap, the event lists don't match (Hamcation isn't a FirmwareEdition enum), and overloading the published Android schema couples two unrelated consumers. A parallel resource/eventFlasher (name TBD) can reuse the exact committed-file-served-verbatim pattern this PR introduces.

Flags before building

  1. eventTag is a code smell, not just data. LogoHeader.vue has hardcoded per-tag markup (v-else-if eventTag === 'Hamvention'). Moving config to the API won't remove the per-event branding deploy unless logos are also data-driven (icon URLs — the direction this PR started for the Android side).
  2. release_notes are large markdown blocks — decide inline vs. separate fetch.
  3. Firmware binaries stay at meshtastic.github.io/event/{pathPrefix}/…; the API would only carry the pointer.
  4. Two-PR rollout: API endpoint first, then a flasher PR to fetch instead of hardcode (keeping the static config as fallback).

Bottom line

Worth doing — kills the redeploy-per-event friction. Cleanest as a new resource/eventFlasher endpoint mirroring deviceLinks, not folded into the Android eventFirmware contract. The one thing data-in-API won't fix by itself is the hardcoded per-event branding markup in the flasher.

cc @thebentern — does a separate endpoint sound right, and should the flasher migration be its own follow-up?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants