From d8e67984b0f734955b64d7ee9b89cfcae79855b8 Mon Sep 17 00:00:00 2001 From: padreug Date: Sun, 16 Nov 2025 17:01:22 +0100 Subject: [PATCH] Fix real-time unclaim updates for task workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add deletion event handling to enable real-time UI updates when tasks are unclaimed. Previously, unclaiming a task required manual refresh to see the update. Changes: - Add handleDeletionEvent() to ScheduledEventService to process kind 5 deletion events - Update FeedService to route kind 31925 deletions to ScheduledEventService - Implement NIP-09 validation (only author can delete their own events) - Remove completions from reactive Map to trigger Vue reactivity Technical details: - Subscription to kind 5 events was already in place - Issue was lack of routing for kind 31925 (RSVP/completion) deletions - Now follows same pattern as reaction and post deletions - Deletion events properly update the _completions reactive Map - UI automatically reflects unclaimed state through Vue reactivity 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../nostr-feed/services/FeedService.ts | 11 +++++ .../services/ScheduledEventService.ts | 40 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/modules/nostr-feed/services/FeedService.ts b/src/modules/nostr-feed/services/FeedService.ts index 500f963..d46ab24 100644 --- a/src/modules/nostr-feed/services/FeedService.ts +++ b/src/modules/nostr-feed/services/FeedService.ts @@ -383,6 +383,17 @@ export class FeedService extends BaseService { return } + // Route to ScheduledEventService for completion/RSVP deletions (kind 31925) + if (deletedKind === '31925') { + console.log('🔀 FeedService: Routing kind 5 (deletion of kind 31925) to ScheduledEventService') + if (this.scheduledEventService) { + this.scheduledEventService.handleDeletionEvent(event) + } else { + console.warn('⚠️ FeedService: ScheduledEventService not available') + } + return + } + // Handle post deletions (kind 1) in FeedService if (deletedKind === '1' || !deletedKind) { // Extract event IDs to delete from 'e' tags diff --git a/src/modules/nostr-feed/services/ScheduledEventService.ts b/src/modules/nostr-feed/services/ScheduledEventService.ts index 7524b01..fc97fd1 100644 --- a/src/modules/nostr-feed/services/ScheduledEventService.ts +++ b/src/modules/nostr-feed/services/ScheduledEventService.ts @@ -213,6 +213,46 @@ export class ScheduledEventService extends BaseService { } } + /** + * Handle deletion event (kind 5) for completion events + * Made public so FeedService can route deletion events to this service + */ + public handleDeletionEvent(event: NostrEvent): void { + console.log('🗑️ ScheduledEventService: Received deletion event (kind 5)', event.id) + + try { + // Extract event IDs to delete from 'e' tags + const eventIdsToDelete = event.tags + ?.filter((tag: string[]) => tag[0] === 'e') + .map((tag: string[]) => tag[1]) || [] + + if (eventIdsToDelete.length === 0) { + console.warn('Deletion event missing e tags:', event.id) + return + } + + console.log('🔍 Looking for completions to delete:', eventIdsToDelete) + + // Find and remove completions that match the deleted event IDs + let deletedCount = 0 + for (const [completionKey, completion] of this._completions.entries()) { + // Only delete if: + // 1. The completion event ID matches one being deleted + // 2. The deletion request comes from the same author (NIP-09 validation) + if (eventIdsToDelete.includes(completion.id) && completion.pubkey === event.pubkey) { + this._completions.delete(completionKey) + console.log('✅ Deleted completion:', completionKey, 'event ID:', completion.id) + deletedCount++ + } + } + + console.log(`🗑️ Deleted ${deletedCount} completion(s) from deletion event`) + + } catch (error) { + console.error('Failed to handle deletion event:', error) + } + } + /** * Get all scheduled events */