EditEventPage: stop stripping unmanaged tags on edit (linked spots/crews, entry fee, Pro listing) (1.2.29)

Calendar events (NIP-52 kind 31923) are addressable, so re-publishing replaces
the entire tag set. The edit form only rebuilt the handful of fields it exposes
(title/start/end/location/geohash/types/image) plus sponsor tags. Everything
else a CreateEventPage event can carry was silently dropped on any edit:
  - linked spot / crew host / tour / musician `a` refs + their readable
    name/category tags (spot-name, crew-name, tour-name, music-act, …)
  - entry-fee and the 'paid' topic tag
  - the paid 'featured' (Pro) listing the organiser may have bought

So a founder editing their event's start time would lose the crew-host link,
the entry fee, and their Pro featured status — real, paid-for data loss.

Fix: after rebuilding the managed fields, carry through every OTHER tag from
the original event untouched. `t` (topic) tags are handled specially — the
form fully owns 'skateboarding' + selected types, but foreign topics like
'paid' are preserved. Replaces the narrow sponsor-only passthrough.

Audit note: CrewForm (create + edit) and EditSpotPage were reviewed in the
same pass and correctly reuse their identifier / preserve state — no changes
needed there. Crews are intentionally many-per-user (timestamped identifier),
so re-creating is by design, not a clobber.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
shakespeare.diy 2026-09-07 22:10:34 +07:00
parent 1cb7c109e7
commit 9bd639f109
2 changed files with 21 additions and 5 deletions

View file

@ -1,7 +1,7 @@
{ {
"name": "skate-spots", "name": "skate-spots",
"private": true, "private": true,
"version": "1.2.28", "version": "1.2.29",
"type": "module", "type": "module",
"homepage": "https://skate-spots.com", "homepage": "https://skate-spots.com",
"scripts": { "scripts": {

View file

@ -289,10 +289,26 @@ export default function EditEventPage() {
tags.push(['image', image]); tags.push(['image', image]);
} }
// Preserve sponsors from the original event (the edit form doesn't manage // Carry through every tag the edit form doesn't manage, untouched. This
// them yet, so carry them through untouched instead of dropping them). // is an addressable event, so re-publishing REPLACES the whole tag set —
for (const sponsorTag of event.event.tags.filter(([name]) => name === 'sponsor')) { // if we only rebuilt the fields on this form we'd silently strip linked
tags.push(sponsorTag); // spots/crews/tours/musicians, the entry fee, the paid "featured" (Pro)
// listing, sponsors, and any other tags an event was created with.
const MANAGED_TAGS = new Set([
'd', 'title', 'start', 'end', 'location', 'g', 'image', 'alt',
]);
// `t` is special: we fully rebuild the topic tags this form owns
// (skateboarding + selected types), but must preserve OTHER `t` values
// like 'paid' that other parts of the app set.
const managedTopics = new Set(['skateboarding', ...selectedTypes]);
for (const tag of event.event.tags) {
const [name, value] = tag;
if (MANAGED_TAGS.has(name)) continue;
if (name === 't') {
if (!managedTopics.has(value)) tags.push(tag); // keep foreign topics (e.g. 'paid')
continue;
}
tags.push(tag); // a-refs, *-name, entry-fee, featured, sponsor, etc.
} }
// Detect the changes attendees care about (time / location) BEFORE we // Detect the changes attendees care about (time / location) BEFORE we