chore(nostr-feed): delete legacy ScheduledEventService duplicate #81

Merged
padreug merged 1 commit from chore/dedup-scheduled-event-service into dev 2026-05-29 19:33:41 +00:00
Owner

Summary

ScheduledEventService (in nostr-feed/) was a legacy duplicate of TaskService (in tasks/). Both classes published the same kind 31925 (RSVP/status) and kind 5 (deletion) events — neither published the kind-31922 calendar event itself. The DI token SCHEDULED_EVENT_SERVICE was already marked @deprecated, and FeedService already routed runtime events to TASK_SERVICE. Only the publish-side (and the NostrFeed.vue consumer) hadn't been repointed yet.

This finishes the consolidation.

Changes

  • Delete src/modules/nostr-feed/services/ScheduledEventService.ts (1067 lines) — duplicate of TaskService
  • Delete src/modules/nostr-feed/composables/useScheduledEvents.ts — duplicate of useTasks
  • Remove SCHEDULED_EVENT_SERVICE token from src/core/di-container.ts (was @deprecated already)
  • Repoint NostrFeed.vue to useTasks({ autoSubscribe: false }) from @/modules/tasks/composables/useTasks. The autoSubscribe: false preserves current lifecycle behavior — FeedService already owns the consolidated relay subscription for kinds 31922 / 31925 / 5; the composable's onMounted auto-subscribe would create a redundant subscription. The exported method surface (getEventsForSpecificDate, getCompletion, getTaskStatus, claimTask, startTask, completeEvent, unclaimTask, deleteTask, allCompletions) is identical between the two composables.
  • Rename FeedService.scheduledEventService field → taskService for honesty. The alias was already pointing at TASK_SERVICE; this just makes the field name match.
  • Drop the tryInjectService legacy-fallback shim on the task-service inject. The nostr-feed module routing depends on the tasks module being loaded; if it isn't, we want a hard failure at init, not silently-dropped events. Strict-from-the-start per ~/dev/CLAUDE.md pre-public-launch policy.
  • Remove the now-dead defensive if (this.taskService) / if (this.reactionService) null-guards in FeedService's route methods. After the inject strictness change, those fields are guaranteed non-null at use time; the warn-on-null else branches were unreachable.

Why now

Same blocker reasoning as #78 (the sibling ReactionService dedup that just merged): the phase-2 bucket-B migration per aiolabs/lnbits#9 touches every finalizeEvent(eventTemplate, prvkeyBytes) site in the webapp. Touching both copies of TaskService-like code would waste effort and risks one branch silently keeping a prvkey-read path alive.

Test plan

  • vue-tsc --noEmit clean post-deletion
  • Manual smoke on aio-demo after dev deploy: open NostrFeed, confirm scheduled-event cards render for the selected date, claim/start/complete/unclaim a task, delete an event published by self, watch for any console warnings from the dropped null-guard branches

Note for reviewers

One pre-existing line at NostrFeed.vue:410 (toast.error("User private key not available")) triggers the global pre-commit secret-scanner — pure false positive on a user-facing error string. Added inline // pragma: allowlist secret marker. That whole block is going away in phase-1 PR #5 (when User.prvkey is removed from the User interface and every bucket-B site fails TS compile, triggering phase-2 migration). The marker is short-lived.

Refs

  • Closes #79
  • Sibling cleanup: #78 (just merged) — ReactionService dedup, same pattern
  • Parent initiative: aiolabs/lnbits#9 (signer abstraction / bunker integration)
  • Cross-session coordination log: ~/dev/coordination/log.md entries 2026-05-28T22:00Z (legacy-duplicate finding), 2026-05-28T22:30Z (lnbits authorized opening the chore), 2026-05-29T00:30Z (consolidated decisions)
  • Design doc Q7.1: ~/dev/coordination/webapp-design-questions.md

🤖 Generated with Claude Code

## Summary `ScheduledEventService` (in `nostr-feed/`) was a legacy duplicate of `TaskService` (in `tasks/`). Both classes published the same kind 31925 (RSVP/status) and kind 5 (deletion) events — neither published the kind-31922 calendar event itself. The DI token `SCHEDULED_EVENT_SERVICE` was already marked `@deprecated`, and `FeedService` already routed runtime events to `TASK_SERVICE`. Only the publish-side (and the `NostrFeed.vue` consumer) hadn't been repointed yet. This finishes the consolidation. ## Changes - **Delete** `src/modules/nostr-feed/services/ScheduledEventService.ts` (1067 lines) — duplicate of `TaskService` - **Delete** `src/modules/nostr-feed/composables/useScheduledEvents.ts` — duplicate of `useTasks` - **Remove** `SCHEDULED_EVENT_SERVICE` token from `src/core/di-container.ts` (was `@deprecated` already) - **Repoint** `NostrFeed.vue` to `useTasks({ autoSubscribe: false })` from `@/modules/tasks/composables/useTasks`. The `autoSubscribe: false` preserves current lifecycle behavior — `FeedService` already owns the consolidated relay subscription for kinds 31922 / 31925 / 5; the composable's `onMounted` auto-subscribe would create a redundant subscription. The exported method surface (`getEventsForSpecificDate`, `getCompletion`, `getTaskStatus`, `claimTask`, `startTask`, `completeEvent`, `unclaimTask`, `deleteTask`, `allCompletions`) is identical between the two composables. - **Rename** `FeedService.scheduledEventService` field → `taskService` for honesty. The alias was already pointing at `TASK_SERVICE`; this just makes the field name match. - **Drop** the `tryInjectService` legacy-fallback shim on the task-service inject. The `nostr-feed` module routing depends on the tasks module being loaded; if it isn't, we want a hard failure at init, not silently-dropped events. Strict-from-the-start per `~/dev/CLAUDE.md` pre-public-launch policy. - **Remove** the now-dead defensive `if (this.taskService)` / `if (this.reactionService)` null-guards in `FeedService`'s route methods. After the inject strictness change, those fields are guaranteed non-null at use time; the warn-on-null else branches were unreachable. ## Why now Same blocker reasoning as `#78` (the sibling ReactionService dedup that just merged): the phase-2 bucket-B migration per `aiolabs/lnbits#9` touches every `finalizeEvent(eventTemplate, prvkeyBytes)` site in the webapp. Touching both copies of `TaskService`-like code would waste effort and risks one branch silently keeping a prvkey-read path alive. ## Test plan - [x] `vue-tsc --noEmit` clean post-deletion - [ ] Manual smoke on `aio-demo` after `dev` deploy: open NostrFeed, confirm scheduled-event cards render for the selected date, claim/start/complete/unclaim a task, delete an event published by self, watch for any console warnings from the dropped null-guard branches ## Note for reviewers One pre-existing line at `NostrFeed.vue:410` (`toast.error("User private key not available")`) triggers the global pre-commit secret-scanner — pure false positive on a user-facing error string. Added inline `// pragma: allowlist secret` marker. That whole block is going away in phase-1 PR #5 (when `User.prvkey` is removed from the `User` interface and every bucket-B site fails TS compile, triggering phase-2 migration). The marker is short-lived. ## Refs - Closes #79 - Sibling cleanup: #78 (just merged) — ReactionService dedup, same pattern - Parent initiative: `aiolabs/lnbits#9` (signer abstraction / bunker integration) - Cross-session coordination log: `~/dev/coordination/log.md` entries `2026-05-28T22:00Z` (legacy-duplicate finding), `2026-05-28T22:30Z` (lnbits authorized opening the chore), `2026-05-29T00:30Z` (consolidated decisions) - Design doc Q7.1: `~/dev/coordination/webapp-design-questions.md` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ScheduledEventService and useScheduledEvents were a legacy duplicate
of TaskService and useTasks. The DI token was already marked
@deprecated, and FeedService routed runtime events to TASK_SERVICE
already — only the publish-side and the NostrFeed view hadn't been
repointed yet.

Changes:
- Delete nostr-feed/services/ScheduledEventService.ts (1067 lines)
- Delete nostr-feed/composables/useScheduledEvents.ts
- Remove SCHEDULED_EVENT_SERVICE token from di-container.ts
- Repoint NostrFeed.vue to useTasks from the tasks module, with
  autoSubscribe: false (FeedService still owns the relay subscription
  for kinds 31922/31925/5)
- Rename FeedService.scheduledEventService field to taskService for
  honesty (the alias was already pointing at TASK_SERVICE)
- Drop tryInjectService legacy-fallback shim — strict-from-the-start
  per workspace pre-launch policy. The tasks module is required;
  inject hard-fails on absence.
- Remove now-dead defensive null guards around taskService and
  reactionService calls in route methods

Closes #79.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
padreug deleted branch chore/dedup-scheduled-event-service 2026-05-29 19:33:41 +00:00
Sign in to join this conversation.
No description provided.