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",
"private": true,
"version": "1.2.28",
"version": "1.2.29",
"type": "module",
"homepage": "https://skate-spots.com",
"scripts": {

View file

@ -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