From 9bd639f1092b08c116be6f3b7a22da42fc075cd3 Mon Sep 17 00:00:00 2001 From: "shakespeare.diy" Date: Mon, 7 Sep 2026 22:10:34 +0700 Subject: [PATCH] EditEventPage: stop stripping unmanaged tags on edit (linked spots/crews, entry fee, Pro listing) (1.2.29) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- package.json | 2 +- src/pages/EditEventPage.tsx | 24 ++++++++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e98ed89..de56bdc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "skate-spots", "private": true, - "version": "1.2.28", + "version": "1.2.29", "type": "module", "homepage": "https://skate-spots.com", "scripts": { diff --git a/src/pages/EditEventPage.tsx b/src/pages/EditEventPage.tsx index bddaa55..7e4016d 100644 --- a/src/pages/EditEventPage.tsx +++ b/src/pages/EditEventPage.tsx @@ -289,10 +289,26 @@ export default function EditEventPage() { tags.push(['image', image]); } - // Preserve sponsors from the original event (the edit form doesn't manage - // them yet, so carry them through untouched instead of dropping them). - for (const sponsorTag of event.event.tags.filter(([name]) => name === 'sponsor')) { - tags.push(sponsorTag); + // Carry through every tag the edit form doesn't manage, untouched. This + // is an addressable event, so re-publishing REPLACES the whole tag set — + // if we only rebuilt the fields on this form we'd silently strip linked + // 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