refactor(events): rename activities module to events + wire VITE_APP_NAME for per-deployment branding #94

Merged
padreug merged 9 commits from refactor/events-module-rename into dev 2026-06-09 18:18:27 +00:00
Owner

Why

The module was named activities originally to avoid colliding with Nostr's Event type. In practice that defense added friction without preventing confusion — the backend extension is named events, NIP-52 calls them "Calendar Events", and the UI already displayed "Events". The collision with nostr-tools Event is handled cleanly by the existing import { Event as NostrEvent } alias pattern (already in 5 files inside the module). Renaming collapses the 4-way mismatch into one consistent term.

Separately, deployments needed per-instance app names. VITE_APP_NAME was already plumbed per-standalone via NixOS services.webapp-standalones.<app>.displayName (e.g. cfaun shipped "Sortir", now rebranded to "Bouge"), but nothing in the standalone consumed it — PWA manifest, HTML title, and runtime branding were all hardcoded. This PR wires the env through every app-name display point so any deploy can flip displayName = "Bouge" (or anything) and pick up the brand end-to-end.

What

Nine commits on the branch:

  1. refactor(events): rename activities module to events — 70-file rename. src/modules/activities/src/modules/events/, src/activities-app/src/events-app/, types/services/composables/views/components/store renamed (ActivityEvent, ActivitiesEvents). Routes /activities/*/events/*; the legacy /events (ticketing management) moves to /my-events so /events belongs to the canonical feed. DI tokens ACTIVITIES_*EVENTS_*. i18n namespace renamed; English domain strings updated, French/Spanish title key realigned. npm scripts :activities:events. Build output dist-activities/dist-events/.

  2. feat(events): wire VITE_APP_NAME through PWA manifest, HTML, runtime — PWA manifest name/short_name template from process.env.VITE_APP_NAME with fallback 'Events'. events.html uses Vite's %VITE_APP_NAME% substitution. src/events-app/app.ts + main.ts runtime brand string drives console logs, offline notification, and acceptTokenFromUrl(). events.title route meta sources from VITE_APP_NAME. .env.example updated with per-standalone scoping notes.

  3. docs(events): update activities→events referencesdocs/nostr-patterns/*.md "Canonical: src/modules/activities/composables/useRSVP.ts" anchors point at renamed paths. CLAUDE.md Payment Rails Pattern section updated.

  4. fix(events): drop lowercase from PWA description brand name — minor casing fix caught during verification.

  5. fix(events): use domain noun in description, not brand name — manifest + HTML description switched from "Discover ${BRAND} near you" to static "Discover events near you". Description is about what the app does, not the brand.

  6. chore(events): scrub leftover sortir/activities references — nginx.conf.example, package.json (concurrently process label + build:demo BASE_PATH), router-helpers comment, useMarket comment, and vite.events.config.ts doc-comment.

  7. refactor(events): conditional brand in console label, tighten docs — adds APP_LABEL next to APP_NAME in events-app/app.ts. Reads as Events on unbranded builds and Events (Bouge) (etc.) when VITE_APP_NAME is set to anything other than "Events" (case-insensitive). Used by all four console messages; acceptTokenFromUrl keeps the raw APP_NAME (it's a token-namespace identifier, not display copy). Also collapses the redundant "cfaun sets X; future deployments can override (e.g. X)" doc-comment.

  8. i18n(events): finish activité/actividad → événement/evento sweep — completes the i18n rename in fr.ts and es.ts (search placeholders, favorites prompts, settings prompt) and fixes five gender-agreement errors that came along with the masculine événement/evento switch (French: Aucune ... trouvéeAucun ... trouvé, préféréespréférés, d'une ... la sauvegarderd'un ... le sauvegarder; Spanish: favoritasfavoritos, guardarlaguardarlo).

  9. chore(events): finish sortir → bouge sweep in .env.example — four remaining doc-comment refs in .env.example (cfaun branding, ticket-scanner comment, section header, subdomain-mode URL example).

Cross-repo coordination

This PR has matching changes already pushed to two other repos. They have to land in a coordinated bump because the names are tightly coupled.

  • aiolabs/webapp-module main — commit 9d82016. Renames hubActivitiesUrlhubEventsUrl and VITE_HUB_ACTIVITIES_URLVITE_HUB_EVENTS_URL. No backwards-compat shim.
  • aiolabs/server-deploy main — commits f15e1eb, bf4698b, d46a520:
    • standalones.nix apps.events uses build:events / dist-events / events.html; hubUrlOption maps events → "hubEventsUrl"; comment + cfaun-as-example doc switched from sortir/Sortir to bouge/Bouge.
    • hosts/cfaun/default.nix rebranded: subdomain = "bouge" + displayName = "Bouge". (Native-French feedback retired the "Sortir" branding as awkward.)
    • hosts/atio/default.nix stale "activities app" comment dropped (atio's displayName = "Eventos" config is unchanged).

server-deploy's flake.lock still pins the OLD webapp + OLD webapp-module, so nix builds from server-deploy main will fail until the bumps. Suggested order after this PR merges to dev: one server-deploy commit that does nix flake lock --update-input webapp-module + --update-input webapp-demo together. DNS for bouge.ariege.io needs to point at the cfaun host before the deploy lands.

Verification

  • pnpm typecheck — clean ✓
  • pnpm build:events (default) — dist-events/manifest.webmanifest has name: "Events", description "Discover events near you" ✓
  • VITE_APP_NAME=Bouge pnpm build:eventsname: "Bouge", HTML title "Bouge", console label resolves to Events (Bouge)
  • Cross-repo grep sweep: no Sortir/sortir/activities/Activities references in events-module scope. (Domain false positives — "Market Activity" in market dashboard, "time-based activities" in nostr-feed content filters, "Activity Lifecycle Kills" in CLAUDE.md mobile-browser docs — are unrelated and intentionally left alone.)

Not verified in-browser (no GUI in this session) — needs a manual smoke at app.ariege.io/bouge/ once the coordinated flake bump lands on cfaun. Watch for: feed loads, /events/calendar, /events/map, /events/favorites, /events/:id routes work; "My Events" appears in the user dropdown and /my-events shows the management page; PWA install prompt shows "Bouge".

Out of scope (deferred)

  • Backend extension rename — aiolabs/events is already named correctly.
  • Nix standalone attribute name — services.webapp-standalones.events is already correct.
  • Overriding domain-noun strings ("Your event was created", RSVP labels) — those stay locale-driven; VITE_APP_NAME covers app-name only.
  • Backwards-compat redirects from /activities/* to /events/* — pre-launch, public URL was /sortir/ (path-mode) or sortir.ariege.io (subdomain-mode), never /activities/. No external bookmarks to preserve. (sortir.ariege.iobouge.ariege.io is a separate decision; up to the deploy operator whether to keep a 301 for word-of-mouth referrers.)
## Why The module was named `activities` originally to avoid colliding with Nostr's `Event` type. In practice that defense added friction without preventing confusion — the backend extension is named `events`, NIP-52 calls them "Calendar Events", and the UI already displayed "Events". The collision with `nostr-tools` `Event` is handled cleanly by the existing `import { Event as NostrEvent }` alias pattern (already in 5 files inside the module). Renaming collapses the 4-way mismatch into one consistent term. Separately, deployments needed per-instance app names. `VITE_APP_NAME` was already plumbed per-standalone via NixOS `services.webapp-standalones.<app>.displayName` (e.g. cfaun shipped `"Sortir"`, now rebranded to `"Bouge"`), but nothing in the standalone consumed it — PWA manifest, HTML title, and runtime branding were all hardcoded. This PR wires the env through every app-name display point so any deploy can flip `displayName = "Bouge"` (or anything) and pick up the brand end-to-end. ## What Nine commits on the branch: 1. **`refactor(events): rename activities module to events`** — 70-file rename. `src/modules/activities/` → `src/modules/events/`, `src/activities-app/` → `src/events-app/`, types/services/composables/views/components/store renamed (`Activity`→`Event`, `Activities`→`Events`). Routes `/activities/*` → `/events/*`; the legacy `/events` (ticketing management) moves to `/my-events` so `/events` belongs to the canonical feed. DI tokens `ACTIVITIES_*` → `EVENTS_*`. i18n namespace renamed; English domain strings updated, French/Spanish title key realigned. npm scripts `:activities` → `:events`. Build output `dist-activities/` → `dist-events/`. 2. **`feat(events): wire VITE_APP_NAME through PWA manifest, HTML, runtime`** — PWA manifest `name`/`short_name` template from `process.env.VITE_APP_NAME` with fallback `'Events'`. `events.html` uses Vite's `%VITE_APP_NAME%` substitution. `src/events-app/app.ts` + `main.ts` runtime brand string drives console logs, offline notification, and `acceptTokenFromUrl()`. `events.title` route meta sources from VITE_APP_NAME. `.env.example` updated with per-standalone scoping notes. 3. **`docs(events): update activities→events references`** — `docs/nostr-patterns/*.md` "Canonical: src/modules/activities/composables/useRSVP.ts" anchors point at renamed paths. CLAUDE.md Payment Rails Pattern section updated. 4. **`fix(events): drop lowercase from PWA description brand name`** — minor casing fix caught during verification. 5. **`fix(events): use domain noun in description, not brand name`** — manifest + HTML description switched from `"Discover ${BRAND} near you"` to static `"Discover events near you"`. Description is about *what* the app does, not the brand. 6. **`chore(events): scrub leftover sortir/activities references`** — nginx.conf.example, package.json (concurrently process label + `build:demo` BASE_PATH), router-helpers comment, useMarket comment, and vite.events.config.ts doc-comment. 7. **`refactor(events): conditional brand in console label, tighten docs`** — adds `APP_LABEL` next to `APP_NAME` in `events-app/app.ts`. Reads as `Events` on unbranded builds and `Events (Bouge)` (etc.) when `VITE_APP_NAME` is set to anything other than "Events" (case-insensitive). Used by all four console messages; `acceptTokenFromUrl` keeps the raw `APP_NAME` (it's a token-namespace identifier, not display copy). Also collapses the redundant "cfaun sets X; future deployments can override (e.g. X)" doc-comment. 8. **`i18n(events): finish activité/actividad → événement/evento sweep`** — completes the i18n rename in fr.ts and es.ts (search placeholders, favorites prompts, settings prompt) and fixes five gender-agreement errors that came along with the masculine `événement`/`evento` switch (French: `Aucune ... trouvée`→`Aucun ... trouvé`, `préférées`→`préférés`, `d'une ... la sauvegarder`→`d'un ... le sauvegarder`; Spanish: `favoritas`→`favoritos`, `guardarla`→`guardarlo`). 9. **`chore(events): finish sortir → bouge sweep in .env.example`** — four remaining doc-comment refs in `.env.example` (cfaun branding, ticket-scanner comment, section header, subdomain-mode URL example). ## Cross-repo coordination This PR has matching changes already pushed to two other repos. They have to land in a coordinated bump because the names are tightly coupled. - **`aiolabs/webapp-module` main** — commit `9d82016`. Renames `hubActivitiesUrl` → `hubEventsUrl` and `VITE_HUB_ACTIVITIES_URL` → `VITE_HUB_EVENTS_URL`. No backwards-compat shim. - **`aiolabs/server-deploy` main** — commits `f15e1eb`, `bf4698b`, `d46a520`: - `standalones.nix` `apps.events` uses `build:events` / `dist-events` / `events.html`; `hubUrlOption` maps `events → "hubEventsUrl"`; comment + cfaun-as-example doc switched from sortir/Sortir to bouge/Bouge. - `hosts/cfaun/default.nix` rebranded: `subdomain = "bouge"` + `displayName = "Bouge"`. (Native-French feedback retired the "Sortir" branding as awkward.) - `hosts/atio/default.nix` stale "activities app" comment dropped (atio's `displayName = "Eventos"` config is unchanged). server-deploy's `flake.lock` still pins the OLD webapp + OLD webapp-module, so nix builds from server-deploy main will fail until the bumps. Suggested order after this PR merges to `dev`: one server-deploy commit that does `nix flake lock --update-input webapp-module` + `--update-input webapp-demo` together. DNS for `bouge.ariege.io` needs to point at the cfaun host before the deploy lands. ## Verification - `pnpm typecheck` — clean ✓ - `pnpm build:events` (default) — `dist-events/manifest.webmanifest` has `name: "Events"`, description "Discover events near you" ✓ - `VITE_APP_NAME=Bouge pnpm build:events` — `name: "Bouge"`, HTML title "Bouge", console label resolves to `Events (Bouge)` ✓ - Cross-repo grep sweep: no `Sortir`/`sortir`/`activities`/`Activities` references in events-module scope. (Domain false positives — "Market Activity" in market dashboard, "time-based activities" in nostr-feed content filters, "Activity Lifecycle Kills" in CLAUDE.md mobile-browser docs — are unrelated and intentionally left alone.) Not verified in-browser (no GUI in this session) — needs a manual smoke at `app.ariege.io/bouge/` once the coordinated flake bump lands on cfaun. Watch for: feed loads, `/events/calendar`, `/events/map`, `/events/favorites`, `/events/:id` routes work; "My Events" appears in the user dropdown and `/my-events` shows the management page; PWA install prompt shows "Bouge". ## Out of scope (deferred) - Backend extension rename — `aiolabs/events` is already named correctly. - Nix standalone attribute name — `services.webapp-standalones.events` is already correct. - Overriding domain-noun strings ("Your event was created", RSVP labels) — those stay locale-driven; `VITE_APP_NAME` covers app-name only. - Backwards-compat redirects from `/activities/*` to `/events/*` — pre-launch, public URL was `/sortir/` (path-mode) or `sortir.ariege.io` (subdomain-mode), never `/activities/`. No external bookmarks to preserve. (`sortir.ariege.io` → `bouge.ariege.io` is a separate decision; up to the deploy operator whether to keep a 301 for word-of-mouth referrers.)
The module name "activities" was originally chosen to avoid colliding
with Nostr's `Event` type. In practice the defense added friction without
preventing confusion: the backend extension is named `events`, NIP-52
calls them "Calendar Events", and the UI already displayed "Events".
The collision with `nostr-tools` `Event` is handled cleanly by the
existing `import { Event as NostrEvent }` alias pattern (already in 5
files inside the module).

Renames `src/modules/activities` → `src/modules/events` and
`src/activities-app` → `src/events-app`. Touches:

- Module dir + 48 internal files (types, services, composables, views,
  components, store) renamed with case-sensitive replacement
  (`Activity`→`Event`, `Activities`→`Events`).
- Route paths: `/activities/*` → `/events/*`. The existing legacy
  `/events` route (ticketing management view) moves to `/my-events`,
  freeing `/events` for the canonical feed/discovery page. A new
  "My Events" entry is added to the user dropdown menu for access.
- Standalone PWA entry: `activities.html` → `events.html`,
  `vite.activities.config.ts` → `vite.events.config.ts`.
- npm scripts: `dev:activities`/`build:activities`/`preview:activities`
  → `:events`. `build:demo` and `dev:all` updated accordingly.
- DI tokens: `SERVICE_TOKENS.ACTIVITIES_*` → `EVENTS_*`.
- Hub config: `appConfig.modules.activities` → `modules.events`.
- i18n: `activities.*` namespace → `events.*` in en/fr/es locales;
  English domain strings updated ("Activities"→"Events", "Search
  activities..."→"Search events..."). French/Spanish display values
  realigned to "Événements"/"Eventos" at the title key; deeper
  translation cleanup left for a follow-up.
- Hub icon label: "Activities" → "Events"; env key
  `VITE_HUB_ACTIVITIES_URL` → `VITE_HUB_EVENTS_URL` (also updated in
  `.env.example`).
- Stale `CreateActivityDialog.vue` removed (only referenced from a
  defunct comment; `CreateEventDialog.vue` is the live one).

Build-output dir renamed `dist-activities/` → `dist-events/`; the
`build:events` npm script reflects the new name. server-deploy still
hardcodes `buildScript = "build:activities"` and `distDir =
"dist-activities"` in `modules/services/standalones.nix:46-47`; a
matching update there needs to land before this branch's webapp commit
gets a flake-input bump.

`Event` naming inside the module no longer collides with the Nostr
`Event` import — those 5 files already use the `NostrEvent` alias.
Disambiguation inside `EventsNostrService.queryCalendarEvents` was
needed: local `events`/`event` variables for the domain side, with
`nostrEvent`/`nostrEvents` for the protocol side.

vue-tsc passes. PWA manifest still hardcodes "Sortir" branding; that
is templated through `VITE_APP_NAME` in a follow-up commit on the
same branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The standalone events app was hardcoded to "Sortir" branding (PWA name
"Sortir — Activités & Événements", HTML title, console logs, URL token
handler ID). VITE_APP_NAME was already plumbed per-standalone via NixOS
`services.webapp-standalones.<app>.displayName` in server-deploy, but
nothing inside the app consumed it.

Routes the env through every app-name display point:

- PWA manifest `name` / `short_name` (vite.events.config.ts): both pull
  from `process.env.VITE_APP_NAME`, defaulting to `'Events'` when
  unset. Description, `id`, and `lang` un-frenched to brand-agnostic
  defaults. The Vite config also writes the resolved value back to
  `process.env` so Vite's built-in HTML `%VITE_APP_NAME%` substitution
  picks up the fallback.

- HTML title + apple-mobile-web-app-title + description (events.html):
  use `%VITE_APP_NAME%` for build-time substitution. `<html lang>` drops
  the hardcoded `fr` (locale is now runtime-driven via i18n).

- Runtime branding (events-app/app.ts, main.ts): a top-level
  `APP_NAME = (import.meta.env.VITE_APP_NAME as string) || 'Events'`
  feeds the console logs, the offline-ready notification, and the
  `acceptTokenFromUrl()` cross-subdomain handler.

- Main events route title (modules/events/index.ts:32): reads
  VITE_APP_NAME so document.title / breadcrumbs show the deployment
  brand. Sub-route titles (Calendar, Map, Favorites) stay literal —
  they're contextual labels, not the app name.

- .env.example now explains the per-standalone scoping and points at
  the NixOS knob for production deploys.

Domain-noun strings ("Search events…", RSVP labels, "Your event was
created") stay in i18n and translate per language — VITE_APP_NAME does
not flow into those.

Verification: `pnpm dev:events` → default `Events` brand;
`VITE_APP_NAME=Bouge pnpm dev:events` → PWA manifest, tab title, console
logs all show "Bouge". cfaun's existing `displayName = "Sortir"` keeps
producing a Sortir-branded build via the same path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Updates documentation that referenced the pre-rename `src/modules/
activities/` paths, useActivities composables, and ACTIVITIES_*
SERVICE_TOKENS to match the new `src/modules/events/` layout.

Touched:
- docs/nostr-patterns/{README,publishing,subscriptions,replaceable-events}.md:
  the "Canonical: src/modules/activities/composables/useRSVP.ts" anchors
  used throughout these pattern docs now point at the renamed paths.
- CLAUDE.md Payment Rails Pattern section: "Activities is the first
  consumer" / "Activities passes [...]" → "Events".

The mobile-browser docs reference to "Activity Lifecycle Kills" (line
810) is left alone — that's Android browser terminology, not the
events module.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The description template was `Discover ${APP_NAME.toLowerCase()} near
you`, producing "Discover bouge near you" / "Discover events near you"
— inconsistent with the title casing. The brand should match the
PWA name/short_name, not be lowercased.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PWA manifest description and HTML meta description were templating
the brand name in ("Discover Bouge near you" / "Discover Sortir near
you"), which conflates app-name with domain noun. The description
should say what the app does, not repeat the brand.

Switches to static "Discover events near you" so the description
remains stable across deployments while the title and short_name still
flex per VITE_APP_NAME.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cleanup pass caught by review after the main rename landed. None of
these were live code paths — all were doc-comments, example configs,
or build-script labels.

- nginx.conf.example: path-mode example URLs `/activities/` → `/events/`,
  alias `dist-activities` → `dist-events`, the "Sortir / activities
  standalone" parenthetical dropped, and the subdomain example
  `sortir.<domain>` → `events.<domain>`.
- package.json: `dev:all` concurrently process label `sortir` → `events`
  and `build:demo` `VITE_BASE_PATH=/sortir/` → `/events/`. The build
  script call already used `npm run build:events`; this just aligns the
  path prefix and the process tag.
- src/lib/router-helpers.ts: the standalones-list comment for
  `installLenientAuthGuard` updated `activities` → `events`.
- src/modules/market/composables/useMarket.ts: the VITE_APP_NAME
  example in the comment switched from "Sortir" to "Bouge" — matching
  the deployment direction in vite.events.config.ts.
- vite.events.config.ts: VITE_BASE_PATH doc-comment examples switched
  from `/sortir/` and `sortir.ariege.io` to `/events/` and
  `bouge.ariege.io`; the cfaun branding example now says "Bouge".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
In the standalone events app:

- Add `APP_LABEL` next to `APP_NAME` in `events-app/app.ts`. It reads
  as `Events` on unbranded builds and `Events (Bouge)` (etc.) when
  `VITE_APP_NAME` is set to anything other than "Events"
  (case-insensitive). The four console messages (Starting / initialized
  / started / Failed to start) all use APP_LABEL, so unbranded dev
  doesn't show the redundant `Events (Events)`. `acceptTokenFromUrl`
  keeps the raw `APP_NAME` — it's a cross-subdomain token namespace
  identifier, not display copy.

- `vite.events.config.ts` doc-comment: collapse the redundant
  "cfaun sets X; future deployments can override (e.g. X)" into the
  shorter "cfaun overrides to 'Bouge' via NixOS. Defaults to 'Events'."
  The override mechanism is the same, and the example was duplicating
  the value pointlessly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
User did the noun rename in fr.ts and es.ts; this commits it plus the
gender-agreement fixes needed because événement (m) and evento (m) take
different agreements than activité (f) and actividad (f).

French (fr.ts):
- "Aucune activité trouvée" → "Aucun événement trouvé"
- "vos activités préférées" → "vos événements préférés"
- "d'une activité ... pour la sauvegarder" → "d'un événement ... pour
  le sauvegarder"

Spanish (es.ts):
- "tus actividades favoritas" → "tus eventos favoritos"
- "cualquier actividad ... para guardarla" → "cualquier evento ... para
  guardarlo"

Strings already covered in earlier commits (title, createNew, noEvents,
the settings.loginPrompt full-replace, etc.) untouched here.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three sortir-era references missed in the prior cleanup commits, plus
one stale "activities" doc-comment:

- Line 6 (VITE_APP_NAME comment): cfaun ships the events app as "Sortir"
  → "Bouge". Native-French feedback retired the Sortir branding.
- Line 23 (VITE_LNBITS_NOSTR_TRANSPORT_PUBKEY comment): "activities
  ticket scanner" → "events ticket scanner".
- Line 44 (section header): "Activities / Sortir Configuration" →
  "Events App Configuration".
- Line 93 (VITE_HUB_EVENTS_URL example): https://sortir.example.comhttps://events.example.com (the comment is the subdomain-mode
  example; using the generic app name is cleaner than baking in any
  specific deployment's brand).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
padreug deleted branch refactor/events-module-rename 2026-06-09 18:18:27 +00:00
Sign in to join this conversation.
No description provided.