mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 22:21:10 +02:00
feat(analytics): add event tracking to 7 core module stores
Add analytics events to todo, calendar, contacts, chat, cards, and photos module stores. All mutations (create, update, delete, complete, favorite, archive) now fire the corresponding typed event helpers with automatic module context. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bfe11d91ed
commit
8ece7d31b8
9 changed files with 35 additions and 1 deletions
|
|
@ -9,6 +9,7 @@
|
|||
import { db } from '$lib/data/database';
|
||||
import type { LocalEvent, CalendarEvent } from '../types';
|
||||
import { toCalendarEvent } from '../queries';
|
||||
import { CalendarEvents } from '@manacore/shared-utils/analytics';
|
||||
|
||||
let error = $state<string | null>(null);
|
||||
let draftEvent = $state<CalendarEvent | null>(null);
|
||||
|
|
@ -54,6 +55,7 @@ export const eventsStore = {
|
|||
};
|
||||
|
||||
await db.table<LocalEvent>('events').add(newLocal);
|
||||
CalendarEvents.eventCreated(!!input.recurrenceRule);
|
||||
return { success: true, data: toCalendarEvent(newLocal) };
|
||||
} catch (e) {
|
||||
error = e instanceof Error ? e.message : 'Failed to create event';
|
||||
|
|
@ -96,6 +98,7 @@ export const eventsStore = {
|
|||
await db.table('events').update(id, localData);
|
||||
const updated = await db.table<LocalEvent>('events').get(id);
|
||||
if (updated) {
|
||||
CalendarEvents.eventUpdated();
|
||||
return { success: true, data: toCalendarEvent(updated) };
|
||||
}
|
||||
return { success: false, error: 'Event not found' };
|
||||
|
|
@ -115,6 +118,7 @@ export const eventsStore = {
|
|||
deletedAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
});
|
||||
CalendarEvents.eventDeleted();
|
||||
return { success: true };
|
||||
} catch (e) {
|
||||
error = e instanceof Error ? e.message : 'Failed to delete event';
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
* This store only handles writes to IndexedDB via the unified database.
|
||||
*/
|
||||
|
||||
import { CardsEvents } from '@manacore/shared-utils/analytics';
|
||||
import { cardTable, cardDeckTable } from '../collections';
|
||||
import { toCard } from '../queries';
|
||||
import type { LocalCard, Card, CreateCardInput, UpdateCardInput } from '../types';
|
||||
|
|
@ -40,6 +41,7 @@ export const cardStore = {
|
|||
});
|
||||
}
|
||||
|
||||
CardsEvents.cardCreated();
|
||||
return toCard(newLocal);
|
||||
} catch (err: any) {
|
||||
error = err.message || 'Failed to create card';
|
||||
|
|
@ -72,6 +74,7 @@ export const cardStore = {
|
|||
try {
|
||||
const now = new Date().toISOString();
|
||||
await cardTable.update(id, { deletedAt: now, updatedAt: now });
|
||||
CardsEvents.cardDeleted();
|
||||
|
||||
// Update deck card count
|
||||
if (deckId) {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
* This store only handles writes to IndexedDB via the unified database.
|
||||
*/
|
||||
|
||||
import { CardsEvents } from '@manacore/shared-utils/analytics';
|
||||
import { cardDeckTable, cardTable } from '../collections';
|
||||
import { toDeck } from '../queries';
|
||||
import type { LocalDeck } from '../types';
|
||||
|
|
@ -30,6 +31,7 @@ export const deckStore = {
|
|||
};
|
||||
|
||||
await cardDeckTable.add(newLocal);
|
||||
CardsEvents.deckCreated();
|
||||
return toDeck(newLocal);
|
||||
} catch (err: any) {
|
||||
error = err.message || 'Failed to create deck';
|
||||
|
|
@ -69,6 +71,7 @@ export const deckStore = {
|
|||
|
||||
// Soft-delete the deck
|
||||
await cardDeckTable.update(id, { deletedAt: now, updatedAt: now });
|
||||
CardsEvents.deckDeleted();
|
||||
} catch (err: any) {
|
||||
error = err.message || 'Failed to delete deck';
|
||||
console.error('Delete deck error:', err);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
import { conversationTable, messageTable } from '../collections';
|
||||
import { toConversation } from '../queries';
|
||||
import { createArchiveOps } from '@manacore/shared-stores';
|
||||
import { ChatEvents } from '@manacore/shared-utils/analytics';
|
||||
import type { LocalConversation } from '../types';
|
||||
|
||||
/** Archive/soft-delete ops for conversations. */
|
||||
|
|
@ -37,6 +38,7 @@ export const conversationsStore = {
|
|||
isPinned: false,
|
||||
};
|
||||
await conversationTable.add(newLocal);
|
||||
ChatEvents.conversationCreated();
|
||||
return toConversation(newLocal);
|
||||
},
|
||||
|
||||
|
|
@ -85,5 +87,6 @@ export const conversationsStore = {
|
|||
for (const msg of msgs) {
|
||||
await messageTable.update(msg.id, { deletedAt: now, updatedAt: now });
|
||||
}
|
||||
ChatEvents.conversationDeleted();
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { messageTable, conversationTable } from '../collections';
|
||||
import { toMessage } from '../queries';
|
||||
import { ChatEvents } from '@manacore/shared-utils/analytics';
|
||||
import type { LocalMessage } from '../types';
|
||||
|
||||
export const messagesStore = {
|
||||
|
|
@ -23,6 +24,7 @@ export const messagesStore = {
|
|||
await conversationTable.update(conversationId, {
|
||||
updatedAt: new Date().toISOString(),
|
||||
});
|
||||
ChatEvents.messageSent();
|
||||
return toMessage(newLocal);
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
import { contactTable } from '../collections';
|
||||
import { toContact } from '../queries';
|
||||
import { createArchiveOps } from '@manacore/shared-stores';
|
||||
import { ContactsEvents } from '@manacore/shared-utils/analytics';
|
||||
import type { LocalContact, Contact } from '../types';
|
||||
|
||||
/** Archive/soft-delete ops for contacts. */
|
||||
|
|
@ -42,6 +43,7 @@ export const contactsStore = {
|
|||
};
|
||||
|
||||
await contactTable.add(newLocal);
|
||||
ContactsEvents.contactCreated();
|
||||
return toContact(newLocal);
|
||||
},
|
||||
|
||||
|
|
@ -75,6 +77,7 @@ export const contactsStore = {
|
|||
...updateData,
|
||||
updatedAt: new Date().toISOString(),
|
||||
});
|
||||
ContactsEvents.contactUpdated();
|
||||
},
|
||||
|
||||
async deleteContact(id: string) {
|
||||
|
|
@ -82,6 +85,7 @@ export const contactsStore = {
|
|||
deletedAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
});
|
||||
ContactsEvents.contactDeleted();
|
||||
},
|
||||
|
||||
async toggleFavorite(id: string) {
|
||||
|
|
@ -92,6 +96,7 @@ export const contactsStore = {
|
|||
isFavorite: !local.isFavorite,
|
||||
updatedAt: new Date().toISOString(),
|
||||
});
|
||||
ContactsEvents.contactFavorited();
|
||||
},
|
||||
|
||||
async updateTagIds(id: string, tagIds: string[]) {
|
||||
|
|
@ -101,5 +106,8 @@ export const contactsStore = {
|
|||
});
|
||||
},
|
||||
|
||||
toggleArchive: (id: string) => contactArchive.toggleArchive(id),
|
||||
toggleArchive: async (id: string) => {
|
||||
await contactArchive.toggleArchive(id);
|
||||
ContactsEvents.contactArchived();
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
* This store handles mutations (create, update, delete, add/remove items).
|
||||
*/
|
||||
|
||||
import { PhotosEvents } from '@manacore/shared-utils/analytics';
|
||||
import { db } from '$lib/data/database';
|
||||
import type { LocalAlbum, LocalAlbumItem, Album } from '../types';
|
||||
import { toAlbum } from '../queries';
|
||||
|
|
@ -25,6 +26,7 @@ export const albumMutations = {
|
|||
updatedAt: now,
|
||||
};
|
||||
await db.table('albums').add(newLocal);
|
||||
PhotosEvents.albumCreated();
|
||||
return toAlbum(newLocal);
|
||||
} catch (e) {
|
||||
console.error('Failed to create album:', e);
|
||||
|
|
@ -59,6 +61,7 @@ export const albumMutations = {
|
|||
await db.table('albumItems').update(item.id, { deletedAt: now, updatedAt: now });
|
||||
}
|
||||
await db.table('albums').update(id, { deletedAt: now, updatedAt: now });
|
||||
PhotosEvents.albumDeleted();
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.error('Failed to delete album:', e);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
* Favorites are local-first via Dexie.
|
||||
*/
|
||||
|
||||
import { PhotosEvents } from '@manacore/shared-utils/analytics';
|
||||
import { db } from '$lib/data/database';
|
||||
import type { LocalFavorite, Photo, PhotoFilters, PhotoStats } from '../types';
|
||||
|
||||
|
|
@ -156,6 +157,7 @@ export const photoStore = {
|
|||
|
||||
// Update server-fetched photos in-memory for immediate UI feedback
|
||||
const isFav = !fav;
|
||||
PhotosEvents.photoFavorited(isFav);
|
||||
photos = photos.map((p) => (p.id === mediaId ? { ...p, isFavorited: isFav } : p));
|
||||
if (selectedPhoto?.id === mediaId) {
|
||||
selectedPhoto = { ...selectedPhoto, isFavorited: isFav };
|
||||
|
|
@ -179,6 +181,7 @@ export const photoStore = {
|
|||
|
||||
photos = photos.filter((p) => p.id !== mediaId);
|
||||
if (selectedPhoto?.id === mediaId) selectedPhoto = null;
|
||||
PhotosEvents.photoDeleted();
|
||||
return true;
|
||||
} catch (e) {
|
||||
error = e instanceof Error ? e.message : 'Failed to delete photo';
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
import { taskTable } from '../collections';
|
||||
import { toTask } from '../queries';
|
||||
import type { LocalTask, TaskPriority, Subtask } from '../types';
|
||||
import { TodoEvents } from '@manacore/shared-utils/analytics';
|
||||
|
||||
export const tasksStore = {
|
||||
async createTask(data: {
|
||||
|
|
@ -42,6 +43,7 @@ export const tasksStore = {
|
|||
}
|
||||
|
||||
await taskTable.add(newLocal);
|
||||
TodoEvents.taskCreated(!!data.dueDate);
|
||||
return toTask(newLocal);
|
||||
},
|
||||
|
||||
|
|
@ -67,6 +69,7 @@ export const tasksStore = {
|
|||
...data,
|
||||
updatedAt: new Date().toISOString(),
|
||||
});
|
||||
TodoEvents.taskEdited();
|
||||
},
|
||||
|
||||
async deleteTask(id: string) {
|
||||
|
|
@ -74,6 +77,7 @@ export const tasksStore = {
|
|||
deletedAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
});
|
||||
TodoEvents.taskDeleted();
|
||||
},
|
||||
|
||||
async completeTask(id: string) {
|
||||
|
|
@ -82,6 +86,7 @@ export const tasksStore = {
|
|||
completedAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
});
|
||||
TodoEvents.taskCompleted();
|
||||
},
|
||||
|
||||
async uncompleteTask(id: string) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue