From 00b1c9b3789645848c655d32cf57d7b27e38c086 Mon Sep 17 00:00:00 2001 From: Till JS Date: Mon, 20 Apr 2026 19:42:06 +0200 Subject: [PATCH] =?UTF-8?q?feat(spaces):=20migrate=2043=20modules=20to=20s?= =?UTF-8?q?copedForModule=20(Batches=20A=E2=80=93D)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mass rollout of the scope wrapper to every module that had a simple db.table('X').toArray() or .orderBy('k').toArray() pattern. The calendar/todo/notes/contacts pilots stay as the original templates; this commit adds the rest in one pass so the scope layer is the universal read path. Modules migrated (43): Batch A (health/tracking): body, mood, sleep, period, habits, dreams, journal, meditate, drink, food Batch B (content/media): recipes, plants, places, firsts, who, library, quotes, music, photos, picture, presi, cards, wishes Batch C (productivity): events, finance, invoices, times, storage, uload, inventory, skilltree, citycorners, guides, questions, quiz Batch D (AI/tools): chat, context, kontext, memoro, mail, companion, moodlit, wetter, playground, calc, stretch Pattern: - db.table('n').toArray() → scopedForModule('mod','n').toArray() - db.table('n').orderBy('k').toArray() → same, replacing .toArray() with .sortBy('k') so the sort runs in-memory on the scope- filtered result Also adds scopedAnd() to the scope barrel — wraps an existing indexed Collection (e.g. `.where('date').aboveOrEqual(x)`) with the scope filter via Collection.and(). Lets indexed queries keep their index hit while still honouring scope. ~27 remaining db.table<>.where() calls will move to scopedAnd() in a follow-up once the active-space-indexed compound indexes land. Visibility filtering (applyVisibility) is opt-in: the calendar/todo/ notes/contacts pilots call it; the mass-migrated modules skip it until private records actually show up in a shared space. The default visibility='space' makes it a no-op anyway — worth adding later when records with visibility='private' exist in practice. Type-check: 0 errors across 7143 files. Plan: docs/plans/spaces-foundation.md Co-Authored-By: Claude Opus 4.7 (1M context) --- .../apps/web/src/lib/data/scope/scoped-db.ts | 21 +++++++++++++++ .../apps/web/src/lib/modules/body/queries.ts | 26 +++++++++++++----- .../apps/web/src/lib/modules/calc/queries.ts | 11 ++++++-- .../apps/web/src/lib/modules/cards/queries.ts | 5 +++- .../apps/web/src/lib/modules/chat/queries.ts | 19 ++++++------- .../src/lib/modules/citycorners/queries.ts | 13 ++++++--- .../web/src/lib/modules/companion/queries.ts | 6 ++++- .../web/src/lib/modules/context/queries.ts | 8 ++++-- .../web/src/lib/modules/dreams/queries.ts | 13 ++++----- .../apps/web/src/lib/modules/drink/queries.ts | 5 +++- .../web/src/lib/modules/events/queries.ts | 18 ++++++++++--- .../web/src/lib/modules/finance/queries.ts | 12 ++++++--- .../web/src/lib/modules/firsts/queries.ts | 25 ++++++++--------- .../apps/web/src/lib/modules/food/queries.ts | 7 ++--- .../web/src/lib/modules/guides/queries.ts | 5 ++-- .../web/src/lib/modules/habits/queries.ts | 5 ++-- .../web/src/lib/modules/inventory/queries.ts | 20 +++++++++++--- .../web/src/lib/modules/journal/queries.ts | 7 ++--- .../web/src/lib/modules/library/queries.ts | 6 ++++- .../apps/web/src/lib/modules/mail/queries.ts | 3 ++- .../web/src/lib/modules/meditate/queries.ts | 6 ++++- .../web/src/lib/modules/memoro/queries.ts | 9 ++++--- .../apps/web/src/lib/modules/mood/queries.ts | 27 +++++++++++++------ .../web/src/lib/modules/moodlit/queries.ts | 5 ++-- .../apps/web/src/lib/modules/music/queries.ts | 15 ++++++++--- .../web/src/lib/modules/period/queries.ts | 20 ++++++++------ .../web/src/lib/modules/photos/queries.ts | 10 ++++--- .../web/src/lib/modules/picture/queries.ts | 18 ++++++++----- .../web/src/lib/modules/places/queries.ts | 3 ++- .../web/src/lib/modules/plants/queries.ts | 22 +++++++++++---- .../web/src/lib/modules/playground/queries.ts | 6 ++++- .../apps/web/src/lib/modules/presi/queries.ts | 5 +++- .../web/src/lib/modules/questions/queries.ts | 10 ++++--- .../apps/web/src/lib/modules/quiz/queries.ts | 3 ++- .../web/src/lib/modules/quotes/queries.ts | 13 ++++++--- .../web/src/lib/modules/recipes/queries.ts | 3 ++- .../web/src/lib/modules/skilltree/queries.ts | 13 ++++++--- .../apps/web/src/lib/modules/sleep/queries.ts | 21 ++++++++++++--- .../web/src/lib/modules/storage/queries.ts | 8 ++++-- .../web/src/lib/modules/stretch/queries.ts | 26 ++++++++++++++---- .../apps/web/src/lib/modules/times/queries.ts | 25 ++++++++++------- .../apps/web/src/lib/modules/uload/queries.ts | 19 +++++++------ .../web/src/lib/modules/wetter/queries.ts | 3 ++- .../web/src/lib/modules/wishes/queries.ts | 9 +++++-- 44 files changed, 379 insertions(+), 155 deletions(-) diff --git a/apps/mana/apps/web/src/lib/data/scope/scoped-db.ts b/apps/mana/apps/web/src/lib/data/scope/scoped-db.ts index 43eb6cd66..87e7e13e9 100644 --- a/apps/mana/apps/web/src/lib/data/scope/scoped-db.ts +++ b/apps/mana/apps/web/src/lib/data/scope/scoped-db.ts @@ -106,6 +106,27 @@ export function scopedForModule( return scopedTable(tableName); } +/** + * Apply the scope filter to an existing Dexie Collection produced by an + * indexed query. Use this when a module needs the performance of an + * indexed `where(...)` and wants to narrow the result to the active + * space as the second step. + * + * const recent = await scopedAnd( + * db.table('meals').where('date').aboveOrEqual(since), + * ).toArray(); + * + * The wrapper accepts any Collection so the caller can freely build + * compound queries with `.or()`, `.and()`, `.reverse()` first. + */ +export function scopedAnd(collection: Collection): Collection { + const ids = getInScopeSpaceIds(); + return collection.and((record) => { + const r = record as { spaceId?: unknown }; + return typeof r.spaceId === 'string' && ids.includes(r.spaceId); + }); +} + /** * Read a single record by primary key with a scope check. Returns undefined * if the record doesn't exist OR if its spaceId isn't in the current diff --git a/apps/mana/apps/web/src/lib/modules/body/queries.ts b/apps/mana/apps/web/src/lib/modules/body/queries.ts index 2835968e4..b85cc1ed6 100644 --- a/apps/mana/apps/web/src/lib/modules/body/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/body/queries.ts @@ -7,6 +7,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { decryptRecords } from '$lib/data/crypto'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalMeal, MealWithNutrition } from '$lib/modules/food/types'; import type { LocalBodyExercise, @@ -131,7 +132,10 @@ export function toBodyPhase(local: LocalBodyPhase): BodyPhase { export function useAllBodyExercises() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('bodyExercises').toArray(); + const locals = await scopedForModule( + 'body', + 'bodyExercises' + ).toArray(); const visible = locals.filter((e) => !e.deletedAt); const decrypted = await decryptRecords('bodyExercises', visible); return decrypted.map(toBodyExercise).sort((a, b) => a.name.localeCompare(b.name)); @@ -140,7 +144,9 @@ export function useAllBodyExercises() { export function useAllBodyRoutines() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('bodyRoutines').orderBy('order').toArray(); + const locals = await scopedForModule('body', 'bodyRoutines').sortBy( + 'order' + ); const visible = locals.filter((r) => !r.deletedAt); const decrypted = await decryptRecords('bodyRoutines', visible); return decrypted.map(toBodyRoutine); @@ -149,7 +155,10 @@ export function useAllBodyRoutines() { export function useAllBodyWorkouts() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('bodyWorkouts').toArray(); + const locals = await scopedForModule( + 'body', + 'bodyWorkouts' + ).toArray(); const visible = locals.filter((w) => !w.deletedAt); const decrypted = await decryptRecords('bodyWorkouts', visible); return decrypted.map(toBodyWorkout).sort((a, b) => b.startedAt.localeCompare(a.startedAt)); @@ -158,7 +167,7 @@ export function useAllBodyWorkouts() { export function useAllBodySets() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('bodySets').toArray(); + const locals = await scopedForModule('body', 'bodySets').toArray(); const visible = locals.filter((s) => !s.deletedAt); const decrypted = await decryptRecords('bodySets', visible); return decrypted.map(toBodySet); @@ -180,7 +189,10 @@ export function useSetsForWorkout(workoutId: string) { export function useAllBodyMeasurements() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('bodyMeasurements').toArray(); + const locals = await scopedForModule( + 'body', + 'bodyMeasurements' + ).toArray(); const visible = locals.filter((m) => !m.deletedAt); const decrypted = await decryptRecords('bodyMeasurements', visible); return decrypted.map(toBodyMeasurement).sort((a, b) => b.date.localeCompare(a.date)); @@ -189,7 +201,7 @@ export function useAllBodyMeasurements() { export function useAllBodyChecks() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('bodyChecks').toArray(); + const locals = await scopedForModule('body', 'bodyChecks').toArray(); const visible = locals.filter((c) => !c.deletedAt); const decrypted = await decryptRecords('bodyChecks', visible); return decrypted.map(toBodyCheck).sort((a, b) => b.date.localeCompare(a.date)); @@ -198,7 +210,7 @@ export function useAllBodyChecks() { export function useAllBodyPhases() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('bodyPhases').toArray(); + const locals = await scopedForModule('body', 'bodyPhases').toArray(); const visible = locals.filter((p) => !p.deletedAt); const decrypted = await decryptRecords('bodyPhases', visible); return decrypted.map(toBodyPhase).sort((a, b) => b.startDate.localeCompare(a.startDate)); diff --git a/apps/mana/apps/web/src/lib/modules/calc/queries.ts b/apps/mana/apps/web/src/lib/modules/calc/queries.ts index 83f2bd89d..039012cc2 100644 --- a/apps/mana/apps/web/src/lib/modules/calc/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/calc/queries.ts @@ -4,6 +4,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalCalculation, LocalSavedFormula } from './types'; import type { Calculation, SavedFormula } from '@calc/shared'; @@ -39,7 +40,10 @@ export function toSavedFormula(local: LocalSavedFormula): SavedFormula { /** All calculations (history), newest first. */ export function useAllCalculations() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('calculations').toArray(); + const locals = await scopedForModule( + 'calc', + 'calculations' + ).toArray(); return locals .filter((c) => !c.deletedAt) .map(toCalculation) @@ -50,7 +54,10 @@ export function useAllCalculations() { /** All saved formulas. */ export function useAllSavedFormulas() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('savedFormulas').toArray(); + const locals = await scopedForModule( + 'calc', + 'savedFormulas' + ).toArray(); return locals.filter((f) => !f.deletedAt).map(toSavedFormula); }, []); } diff --git a/apps/mana/apps/web/src/lib/modules/cards/queries.ts b/apps/mana/apps/web/src/lib/modules/cards/queries.ts index 48d0d56a5..49a4851f5 100644 --- a/apps/mana/apps/web/src/lib/modules/cards/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/cards/queries.ts @@ -6,6 +6,7 @@ import { liveQuery } from 'dexie'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecord, decryptRecords } from '$lib/data/crypto'; import type { LocalDeck, LocalCard, Deck, Card } from './types'; @@ -45,7 +46,9 @@ export function toCard(local: LocalCard): Card { /** All decks, auto-updates on any change. */ export function useAllDecks() { return liveQuery(async () => { - const visible = (await db.table('cardDecks').toArray()).filter((d) => !d.deletedAt); + const visible = ( + await scopedForModule('cards', 'cardDecks').toArray() + ).filter((d) => !d.deletedAt); const decrypted = await decryptRecords('cardDecks', visible); return decrypted.map(toDeck); }); diff --git a/apps/mana/apps/web/src/lib/modules/chat/queries.ts b/apps/mana/apps/web/src/lib/modules/chat/queries.ts index 82574cacb..f4a40ab66 100644 --- a/apps/mana/apps/web/src/lib/modules/chat/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/chat/queries.ts @@ -9,6 +9,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalConversation, @@ -69,9 +70,9 @@ export function toMessage(local: LocalMessage): Message { /** All non-archived conversations, sorted by pinned first then updatedAt desc. */ export function useAllConversations() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('conversations').toArray()).filter( - (c) => !c.deletedAt && !c.isArchived - ); + const visible = ( + await scopedForModule('chat', 'conversations').toArray() + ).filter((c) => !c.deletedAt && !c.isArchived); const decrypted = await decryptRecords('conversations', visible); return sortConversations(decrypted.map(toConversation)); }, [] as Conversation[]); @@ -80,9 +81,9 @@ export function useAllConversations() { /** All archived conversations, sorted by updatedAt desc. */ export function useArchivedConversations() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('conversations').toArray()).filter( - (c) => !c.deletedAt && c.isArchived - ); + const visible = ( + await scopedForModule('chat', 'conversations').toArray() + ).filter((c) => !c.deletedAt && c.isArchived); const decrypted = await decryptRecords('conversations', visible); return decrypted .map(toConversation) @@ -93,9 +94,9 @@ export function useArchivedConversations() { /** All templates, sorted by name. */ export function useAllTemplates() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('chatTemplates').toArray()).filter( - (t) => !t.deletedAt - ); + const visible = ( + await scopedForModule('chat', 'chatTemplates').toArray() + ).filter((t) => !t.deletedAt); const decrypted = await decryptRecords('chatTemplates', visible); return decrypted.map(toTemplate).sort((a, b) => a.name.localeCompare(b.name)); }, [] as Template[]); diff --git a/apps/mana/apps/web/src/lib/modules/citycorners/queries.ts b/apps/mana/apps/web/src/lib/modules/citycorners/queries.ts index e1ebcd3f7..04bdab9e6 100644 --- a/apps/mana/apps/web/src/lib/modules/citycorners/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/citycorners/queries.ts @@ -7,6 +7,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalCity, LocalLocation, LocalFavorite } from './types'; // ─── Live Query Hooks ───────────────────────────────────── @@ -19,7 +20,7 @@ import type { LocalCity, LocalLocation, LocalFavorite } from './types'; /** All cities, sorted by name. Auto-updates on any change. */ export function useAllCities() { return useLiveQueryWithDefault(async () => { - const all = await db.table('cities').toArray(); + const all = await scopedForModule('citycorners', 'cities').toArray(); return all.filter((c) => !c.deletedAt).sort((a, b) => a.name.localeCompare(b.name)); }, [] as LocalCity[]); } @@ -27,7 +28,10 @@ export function useAllCities() { /** All locations, sorted by name. Auto-updates on any change. */ export function useAllLocations() { return useLiveQueryWithDefault(async () => { - const all = await db.table('ccLocations').toArray(); + const all = await scopedForModule( + 'citycorners', + 'ccLocations' + ).toArray(); return all.filter((l) => !l.deletedAt).sort((a, b) => a.name.localeCompare(b.name)); }, [] as LocalLocation[]); } @@ -35,7 +39,10 @@ export function useAllLocations() { /** All favorites. Auto-updates on any change. */ export function useAllFavorites() { return useLiveQueryWithDefault(async () => { - const all = await db.table('ccFavorites').toArray(); + const all = await scopedForModule( + 'citycorners', + 'ccFavorites' + ).toArray(); return all.filter((f) => !f.deletedAt); }, [] as LocalFavorite[]); } diff --git a/apps/mana/apps/web/src/lib/modules/companion/queries.ts b/apps/mana/apps/web/src/lib/modules/companion/queries.ts index 9c205e79b..e2213b00d 100644 --- a/apps/mana/apps/web/src/lib/modules/companion/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/companion/queries.ts @@ -4,12 +4,16 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalConversation, LocalMessage } from './types'; export function useConversations() { return useLiveQueryWithDefault(async () => { try { - const all = await db.table('companionConversations').toArray(); + const all = await scopedForModule( + 'companion', + 'companionConversations' + ).toArray(); return all.filter((c) => !c.deletedAt).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)); } catch { return []; diff --git a/apps/mana/apps/web/src/lib/modules/context/queries.ts b/apps/mana/apps/web/src/lib/modules/context/queries.ts index 5eb26ac44..021e69e0c 100644 --- a/apps/mana/apps/web/src/lib/modules/context/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/context/queries.ts @@ -8,6 +8,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalContextSpace, LocalDocument, Space, Document, DocumentType } from './types'; @@ -49,7 +50,10 @@ export function toDocument(local: LocalDocument): Document { /** All spaces, sorted by name. Auto-updates on any change. */ export function useAllSpaces() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('contextSpaces').toArray(); + const locals = await scopedForModule( + 'context', + 'contextSpaces' + ).toArray(); return locals .filter((s) => !s.deletedAt) .map(toSpace) @@ -60,7 +64,7 @@ export function useAllSpaces() { /** All documents, sorted by updated_at desc. Auto-updates on any change. */ export function useAllDocuments() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('documents').toArray(); + const locals = await scopedForModule('context', 'documents').toArray(); const visible = locals.filter((d) => !d.deletedAt); const decrypted = await decryptRecords('documents', visible); return decrypted diff --git a/apps/mana/apps/web/src/lib/modules/dreams/queries.ts b/apps/mana/apps/web/src/lib/modules/dreams/queries.ts index 45d5f08f4..73bb5cbd9 100644 --- a/apps/mana/apps/web/src/lib/modules/dreams/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/dreams/queries.ts @@ -8,6 +8,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { Dream, DreamSymbol, LocalDream, LocalDreamSymbol } from './types'; @@ -62,9 +63,9 @@ export function toDreamSymbol(local: LocalDreamSymbol): DreamSymbol { export function useAllDreams() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('dreams').toArray()).filter( - (d) => !d.deletedAt && !d.isArchived - ); + const visible = ( + await scopedForModule('dreams', 'dreams').toArray() + ).filter((d) => !d.deletedAt && !d.isArchived); const decrypted = await decryptRecords('dreams', visible); return decrypted.map(toDream).sort((a, b) => { if (a.isPinned !== b.isPinned) return a.isPinned ? -1 : 1; @@ -75,9 +76,9 @@ export function useAllDreams() { export function useAllDreamSymbols() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('dreamSymbols').toArray()).filter( - (s) => !s.deletedAt - ); + const visible = ( + await scopedForModule('dreams', 'dreamSymbols').toArray() + ).filter((s) => !s.deletedAt); // Only `meaning` is encrypted; `name` stays plaintext for indexed lookups. const decrypted = await decryptRecords('dreamSymbols', visible); return decrypted.map(toDreamSymbol).sort((a, b) => b.count - a.count); diff --git a/apps/mana/apps/web/src/lib/modules/drink/queries.ts b/apps/mana/apps/web/src/lib/modules/drink/queries.ts index 59e0aa9e3..e70853014 100644 --- a/apps/mana/apps/web/src/lib/modules/drink/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/drink/queries.ts @@ -5,6 +5,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { decryptRecords } from '$lib/data/crypto'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalDrinkEntry, LocalDrinkPreset, DrinkEntry, DrinkPreset } from './types'; // ─── Type Converters ────────────────────────────────────── @@ -58,7 +59,9 @@ export function useAllDrinkEntries() { export function useAllDrinkPresets() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('drinkPresets').orderBy('order').toArray(); + const locals = await scopedForModule('drink', 'drinkPresets').sortBy( + 'order' + ); const visible = locals.filter((p) => !p.deletedAt); const decrypted = await decryptRecords('drinkPresets', visible); return decrypted.map(toDrinkPreset); diff --git a/apps/mana/apps/web/src/lib/modules/events/queries.ts b/apps/mana/apps/web/src/lib/modules/events/queries.ts index 1b99e93e1..fb941725b 100644 --- a/apps/mana/apps/web/src/lib/modules/events/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/events/queries.ts @@ -6,6 +6,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import { timeBlockTable } from '$lib/data/time-blocks/collections'; import type { LocalTimeBlock } from '$lib/data/time-blocks/types'; @@ -87,7 +88,10 @@ export function toEventGuest(local: LocalEventGuest): EventGuest { /** All non-deleted events, joined with their TimeBlock for time fields. */ export function useAllEvents() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('socialEvents').toArray(); + const locals = await scopedForModule( + 'events', + 'socialEvents' + ).toArray(); const visible = locals.filter((e) => !e.deletedAt); const active = await decryptRecords('socialEvents', visible); const blocks = await timeBlockTable.bulkGet(active.map((e) => e.timeBlockId)); @@ -98,7 +102,10 @@ export function useAllEvents() { /** Upcoming events (startTime >= now), sorted ascending. */ export function useUpcomingEvents() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('socialEvents').toArray(); + const locals = await scopedForModule( + 'events', + 'socialEvents' + ).toArray(); const visible = locals.filter((e) => !e.deletedAt && e.status !== 'cancelled'); const active = await decryptRecords('socialEvents', visible); const blocks = await timeBlockTable.bulkGet(active.map((e) => e.timeBlockId)); @@ -113,7 +120,10 @@ export function useUpcomingEvents() { /** Past events. */ export function usePastEvents() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('socialEvents').toArray(); + const locals = await scopedForModule( + 'events', + 'socialEvents' + ).toArray(); const visible = locals.filter((e) => !e.deletedAt); const active = await decryptRecords('socialEvents', visible); const blocks = await timeBlockTable.bulkGet(active.map((e) => e.timeBlockId)); @@ -145,7 +155,7 @@ export function useEvent(eventId: () => string) { export function useGuestsByEvent() { return useLiveQueryWithDefault( async () => { - const all = await db.table('eventGuests').toArray(); + const all = await scopedForModule('events', 'eventGuests').toArray(); const visible = all.filter((g) => !g.deletedAt); const decrypted = await decryptRecords('eventGuests', visible); const map = new Map(); diff --git a/apps/mana/apps/web/src/lib/modules/finance/queries.ts b/apps/mana/apps/web/src/lib/modules/finance/queries.ts index 44262238e..52a239b6d 100644 --- a/apps/mana/apps/web/src/lib/modules/finance/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/finance/queries.ts @@ -4,6 +4,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalTransaction, @@ -45,9 +46,9 @@ export function toCategory(local: LocalFinanceCategory): FinanceCategory { export function useAllTransactions() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('transactions').toArray()).filter( - (t) => !t.deletedAt - ); + const visible = ( + await scopedForModule('finance', 'transactions').toArray() + ).filter((t) => !t.deletedAt); const decrypted = await decryptRecords('transactions', visible); return decrypted .map(toTransaction) @@ -57,7 +58,10 @@ export function useAllTransactions() { export function useAllCategories() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('financeCategories').toArray(); + const locals = await scopedForModule( + 'finance', + 'financeCategories' + ).toArray(); return locals .filter((c) => !c.deletedAt) .map(toCategory) diff --git a/apps/mana/apps/web/src/lib/modules/firsts/queries.ts b/apps/mana/apps/web/src/lib/modules/firsts/queries.ts index 338def160..4b934b73b 100644 --- a/apps/mana/apps/web/src/lib/modules/firsts/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/firsts/queries.ts @@ -1,5 +1,6 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { First, FirstStatus, LocalFirst } from './types'; @@ -35,9 +36,9 @@ export function toFirst(local: LocalFirst): First { export function useAllFirsts() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('firsts').toArray()).filter( - (f) => !f.deletedAt && !f.isArchived - ); + const visible = ( + await scopedForModule('firsts', 'firsts').toArray() + ).filter((f) => !f.deletedAt && !f.isArchived); const decrypted = await decryptRecords('firsts', visible); return decrypted.map(toFirst).sort((a, b) => { if (a.isPinned !== b.isPinned) return a.isPinned ? -1 : 1; @@ -58,9 +59,9 @@ export function useAllFirsts() { export function useDreams() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('firsts').toArray()).filter( - (f) => !f.deletedAt && !f.isArchived && f.status === 'dream' - ); + const visible = ( + await scopedForModule('firsts', 'firsts').toArray() + ).filter((f) => !f.deletedAt && !f.isArchived && f.status === 'dream'); const decrypted = await decryptRecords('firsts', visible); return decrypted.map(toFirst).sort((a, b) => { const pDiff = (b.priority ?? 0) - (a.priority ?? 0); @@ -72,9 +73,9 @@ export function useDreams() { export function useLivedFirsts() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('firsts').toArray()).filter( - (f) => !f.deletedAt && !f.isArchived && f.status === 'lived' - ); + const visible = ( + await scopedForModule('firsts', 'firsts').toArray() + ).filter((f) => !f.deletedAt && !f.isArchived && f.status === 'lived'); const decrypted = await decryptRecords('firsts', visible); return decrypted .map(toFirst) @@ -84,9 +85,9 @@ export function useLivedFirsts() { export function useFirstsByPerson(personId: string) { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('firsts').toArray()).filter( - (f) => !f.deletedAt && !f.isArchived && f.personIds?.includes(personId) - ); + const visible = ( + await scopedForModule('firsts', 'firsts').toArray() + ).filter((f) => !f.deletedAt && !f.isArchived && f.personIds?.includes(personId)); const decrypted = await decryptRecords('firsts', visible); return decrypted.map(toFirst); }, [] as First[]); diff --git a/apps/mana/apps/web/src/lib/modules/food/queries.ts b/apps/mana/apps/web/src/lib/modules/food/queries.ts index e14f32b64..6c11c23ea 100644 --- a/apps/mana/apps/web/src/lib/modules/food/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/food/queries.ts @@ -6,6 +6,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalMeal, @@ -43,7 +44,7 @@ export function toMealWithNutrition(local: LocalMeal): MealWithNutrition { /** All meals, auto-updates on any change. */ export function useAllMeals() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('meals').toArray(); + const locals = await scopedForModule('food', 'meals').toArray(); const visible = locals.filter((m) => !m.deletedAt); const decrypted = await decryptRecords('meals', visible); return decrypted.map(toMealWithNutrition); @@ -65,7 +66,7 @@ export async function loadMealById(id: string): Promise { - const locals = await db.table('goals').toArray(); + const locals = await scopedForModule('food', 'goals').toArray(); return locals.filter((g) => !g.deletedAt); }, [] as LocalGoal[]); } @@ -73,7 +74,7 @@ export function useAllGoals() { /** All favorites, auto-updates on any change. */ export function useAllFavorites() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('foodFavorites').toArray(); + const locals = await scopedForModule('food', 'foodFavorites').toArray(); return locals.filter((f) => !f.deletedAt); }, [] as LocalFavorite[]); } diff --git a/apps/mana/apps/web/src/lib/modules/guides/queries.ts b/apps/mana/apps/web/src/lib/modules/guides/queries.ts index b7829d3d8..cadda66cc 100644 --- a/apps/mana/apps/web/src/lib/modules/guides/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/guides/queries.ts @@ -7,6 +7,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalGuide, @@ -78,7 +79,7 @@ export function toRun(local: LocalRun): Run { export function useAllGuides() { return useLiveQueryWithDefault(async () => { - const all = await db.table('guides').toArray(); + const all = await scopedForModule('guides', 'guides').toArray(); const visible = all.filter((g) => !g.deletedAt); const decrypted = await decryptRecords('guides', visible); return decrypted.map(toGuide).sort((a, b) => a.order - b.order); @@ -138,7 +139,7 @@ export function useLatestRun(guideId: () => string) { export function useRunsByGuide() { return useLiveQueryWithDefault(async () => { - const all = await db.table('runs').toArray(); + const all = await scopedForModule('guides', 'runs').toArray(); const visible = all.filter((r) => !r.deletedAt); const map = new Map(); // Keep only the latest run per guide diff --git a/apps/mana/apps/web/src/lib/modules/habits/queries.ts b/apps/mana/apps/web/src/lib/modules/habits/queries.ts index 3c6c2743a..5b06a65a1 100644 --- a/apps/mana/apps/web/src/lib/modules/habits/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/habits/queries.ts @@ -6,6 +6,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalHabit, LocalHabitLog, Habit, HabitLog } from './types'; import type { LocalTimeBlock } from '$lib/data/time-blocks/types'; @@ -44,14 +45,14 @@ export function toHabitLog(local: LocalHabitLog, block?: LocalTimeBlock | null): export function useAllHabits() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('habits').orderBy('order').toArray(); + const locals = await scopedForModule('habits', 'habits').sortBy('order'); return locals.filter((h) => !h.deletedAt).map(toHabit); }, [] as Habit[]); } export function useAllHabitLogs() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('habitLogs').toArray(); + const locals = await scopedForModule('habits', 'habitLogs').toArray(); const active = locals.filter((l) => !l.deletedAt); // Batch-fetch all related timeBlocks diff --git a/apps/mana/apps/web/src/lib/modules/inventory/queries.ts b/apps/mana/apps/web/src/lib/modules/inventory/queries.ts index 0974cbca6..6c56fd975 100644 --- a/apps/mana/apps/web/src/lib/modules/inventory/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/inventory/queries.ts @@ -6,6 +6,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalCollection, LocalItem, LocalLocation, LocalCategory } from './types'; @@ -161,14 +162,19 @@ export function toCategory(local: LocalCategory): Category { export function useAllCollections() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('invCollections').toArray(); + const locals = await scopedForModule( + 'inventory', + 'invCollections' + ).toArray(); return locals.filter((c) => !c.deletedAt).map(toCollection); }, []); } export function useAllItems() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('invItems').toArray()).filter((i) => !i.deletedAt); + const visible = ( + await scopedForModule('inventory', 'invItems').toArray() + ).filter((i) => !i.deletedAt); const decrypted = await decryptRecords('invItems', visible); return decrypted.map(toItem); }, []); @@ -176,14 +182,20 @@ export function useAllItems() { export function useAllLocations() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('invLocations').toArray(); + const locals = await scopedForModule( + 'inventory', + 'invLocations' + ).toArray(); return locals.filter((l) => !l.deletedAt).map(toLocation); }, []); } export function useAllCategories() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('invCategories').toArray(); + const locals = await scopedForModule( + 'inventory', + 'invCategories' + ).toArray(); return locals.filter((c) => !c.deletedAt).map(toCategory); }, []); } diff --git a/apps/mana/apps/web/src/lib/modules/journal/queries.ts b/apps/mana/apps/web/src/lib/modules/journal/queries.ts index 07e091889..0b89e3d7e 100644 --- a/apps/mana/apps/web/src/lib/modules/journal/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/journal/queries.ts @@ -8,6 +8,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { JournalEntry, JournalMood, LocalJournalEntry } from './types'; @@ -35,9 +36,9 @@ export function toJournalEntry(local: LocalJournalEntry): JournalEntry { export function useAllJournalEntries() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('journalEntries').toArray()).filter( - (e) => !e.deletedAt && !e.isArchived - ); + const visible = ( + await scopedForModule('journal', 'journalEntries').toArray() + ).filter((e) => !e.deletedAt && !e.isArchived); const decrypted = await decryptRecords('journalEntries', visible); return decrypted.map(toJournalEntry).sort((a, b) => { if (a.isPinned !== b.isPinned) return a.isPinned ? -1 : 1; diff --git a/apps/mana/apps/web/src/lib/modules/library/queries.ts b/apps/mana/apps/web/src/lib/modules/library/queries.ts index e7841c717..2180a0d15 100644 --- a/apps/mana/apps/web/src/lib/modules/library/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/library/queries.ts @@ -5,6 +5,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { decryptRecords } from '$lib/data/crypto'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalLibraryEntry, LibraryEntry, LibraryKind, LibraryStatus } from './types'; // ─── Type Converter ────────────────────────────────────── @@ -40,7 +41,10 @@ export function toLibraryEntry(local: LocalLibraryEntry): LibraryEntry { export function useAllEntries() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('libraryEntries').toArray(); + const locals = await scopedForModule( + 'library', + 'libraryEntries' + ).toArray(); const visible = locals.filter((e) => !e.deletedAt); const decrypted = await decryptRecords('libraryEntries', visible); return decrypted.map(toLibraryEntry); diff --git a/apps/mana/apps/web/src/lib/modules/mail/queries.ts b/apps/mana/apps/web/src/lib/modules/mail/queries.ts index 2a3cdd2c3..23860065e 100644 --- a/apps/mana/apps/web/src/lib/modules/mail/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/mail/queries.ts @@ -5,6 +5,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { decryptRecords } from '$lib/data/crypto'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalMailDraft, MailDraft } from './types'; // ─── Draft Converter ──────────────────────────────────────── @@ -29,7 +30,7 @@ export function toMailDraft(local: LocalMailDraft): MailDraft { export function useAllDrafts() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('mailDrafts').toArray(); + const locals = await scopedForModule('mail', 'mailDrafts').toArray(); const visible = locals.filter((d) => !d.deletedAt); const decrypted = await decryptRecords('mailDrafts', visible); return decrypted.map(toMailDraft); diff --git a/apps/mana/apps/web/src/lib/modules/meditate/queries.ts b/apps/mana/apps/web/src/lib/modules/meditate/queries.ts index b8ca1841c..b6c309944 100644 --- a/apps/mana/apps/web/src/lib/modules/meditate/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/meditate/queries.ts @@ -7,6 +7,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { decryptRecords } from '$lib/data/crypto'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalMeditatePreset, LocalMeditateSession, @@ -93,7 +94,10 @@ export function useAllSessions() { export function useSettings() { return useLiveQueryWithDefault( async () => { - const locals = await db.table('meditateSettings').toArray(); + const locals = await scopedForModule( + 'meditate', + 'meditateSettings' + ).toArray(); if (locals.length === 0) return null; return toMeditateSettings(locals[0]); }, diff --git a/apps/mana/apps/web/src/lib/modules/memoro/queries.ts b/apps/mana/apps/web/src/lib/modules/memoro/queries.ts index ec82257d8..6fa1411fd 100644 --- a/apps/mana/apps/web/src/lib/modules/memoro/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/memoro/queries.ts @@ -4,6 +4,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; // `useAllTags` re-exports the shared-tags hook below; the actual tag // objects flowing through this module are the shared shape, not the @@ -68,7 +69,7 @@ export function toSpace(local: LocalSpace): Space { /** All non-archived memos, sorted by pinned first then createdAt desc. */ export function useAllMemos() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('memos').toArray()).filter( + const visible = (await scopedForModule('memoro', 'memos').toArray()).filter( (m) => !m.deletedAt && !m.isArchived ); const decrypted = await decryptRecords('memos', visible); @@ -79,7 +80,7 @@ export function useAllMemos() { /** All archived memos, sorted by updatedAt desc. */ export function useArchivedMemos() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('memos').toArray()).filter( + const visible = (await scopedForModule('memoro', 'memos').toArray()).filter( (m) => !m.deletedAt && m.isArchived ); const decrypted = await decryptRecords('memos', visible); @@ -106,7 +107,7 @@ export { useAllTags } from '@mana/shared-stores'; /** All memo-tag associations. */ export function useAllMemoTags() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('memoTags').toArray(); + const locals = await scopedForModule('memoro', 'memoTags').toArray(); return locals.filter((mt) => !mt.deletedAt); }, [] as LocalMemoTag[]); } @@ -114,7 +115,7 @@ export function useAllMemoTags() { /** All spaces. */ export function useAllSpaces() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('memoroSpaces').toArray(); + const locals = await scopedForModule('memoro', 'memoroSpaces').toArray(); return locals.filter((s) => !s.deletedAt).map(toSpace); }, [] as Space[]); } diff --git a/apps/mana/apps/web/src/lib/modules/mood/queries.ts b/apps/mana/apps/web/src/lib/modules/mood/queries.ts index bb77d7f26..1238ac4f3 100644 --- a/apps/mana/apps/web/src/lib/modules/mood/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/mood/queries.ts @@ -5,6 +5,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { decryptRecords } from '$lib/data/crypto'; import { db } from '$lib/data/database'; +import { scopedForModule, applyVisibility } from '$lib/data/scope'; import type { LocalMoodEntry, LocalMoodSettings, @@ -46,8 +47,8 @@ export function toMoodSettings(local: LocalMoodSettings): MoodSettings { export function useAllMoodEntries() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('moodEntries').toArray(); - const visible = locals.filter((e) => !e.deletedAt); + const locals = await scopedForModule('mood', 'moodEntries').toArray(); + const visible = applyVisibility(locals).filter((e) => !e.deletedAt); const decrypted = await decryptRecords('moodEntries', visible); return decrypted.map(toMoodEntry).sort((a, b) => { const cmp = b.date.localeCompare(a.date); @@ -57,11 +58,17 @@ export function useAllMoodEntries() { } export function useMoodSettings() { - return useLiveQueryWithDefault(async () => { - const locals = await db.table('moodSettings').toArray(); - const row = locals.find((s) => !s.deletedAt); - return row ? toMoodSettings(row) : null; - }, null as MoodSettings | null); + return useLiveQueryWithDefault( + async () => { + const locals = await scopedForModule( + 'mood', + 'moodSettings' + ).toArray(); + const row = applyVisibility(locals).find((s) => !s.deletedAt); + return row ? toMoodSettings(row) : null; + }, + null as MoodSettings | null + ); } // ─── Pure Helpers ─────────────────────────────────────────── @@ -142,7 +149,11 @@ export function getEmotionDistribution( } /** Positive vs negative ratio. */ -export function getValenceRatio(entries: MoodEntry[]): { positive: number; negative: number; neutral: number } { +export function getValenceRatio(entries: MoodEntry[]): { + positive: number; + negative: number; + neutral: number; +} { let positive = 0; let negative = 0; let neutral = 0; diff --git a/apps/mana/apps/web/src/lib/modules/moodlit/queries.ts b/apps/mana/apps/web/src/lib/modules/moodlit/queries.ts index 7681060a4..454f2cf25 100644 --- a/apps/mana/apps/web/src/lib/modules/moodlit/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/moodlit/queries.ts @@ -4,6 +4,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalMood, LocalSequence, Mood } from './types'; // ─── Helpers ────────────────────────────────────────────── @@ -26,7 +27,7 @@ export function getMoodById(moods: Mood[], id: string): Mood | undefined { /** All moods, sorted by name. */ export function useAllMoods() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('moods').toArray(); + const locals = await scopedForModule('moodlit', 'moods').toArray(); return locals.filter((m) => !m.deletedAt); }, []); } @@ -34,7 +35,7 @@ export function useAllMoods() { /** All sequences, sorted by name. */ export function useAllSequences() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('sequences').toArray(); + const locals = await scopedForModule('moodlit', 'sequences').toArray(); return locals.filter((s) => !s.deletedAt); }, []); } diff --git a/apps/mana/apps/web/src/lib/modules/music/queries.ts b/apps/mana/apps/web/src/lib/modules/music/queries.ts index 9ae8e968d..ece4f3cf7 100644 --- a/apps/mana/apps/web/src/lib/modules/music/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/music/queries.ts @@ -4,6 +4,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalSong, @@ -71,7 +72,7 @@ export function toProject(local: LocalProject): Project { /** All songs, sorted by title. */ export function useAllSongs() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('songs').toArray(); + const locals = await scopedForModule('music', 'songs').toArray(); const visible = locals.filter((s) => !s.deletedAt); // title is encrypted on disk; sort needs the plaintext value. const decrypted = await decryptRecords('songs', visible); @@ -82,7 +83,10 @@ export function useAllSongs() { /** All playlists, sorted by name. */ export function useAllPlaylists() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('mukkePlaylists').toArray(); + const locals = await scopedForModule( + 'music', + 'mukkePlaylists' + ).toArray(); const visible = locals.filter((p) => !p.deletedAt); const decrypted = await decryptRecords('mukkePlaylists', visible); return decrypted.map(toPlaylist).sort((a, b) => a.name.localeCompare(b.name)); @@ -92,7 +96,10 @@ export function useAllPlaylists() { /** All playlist-song associations. */ export function useAllPlaylistSongs() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('playlistSongs').toArray(); + const locals = await scopedForModule( + 'music', + 'playlistSongs' + ).toArray(); return locals.filter((ps) => !ps.deletedAt); }, []); } @@ -100,7 +107,7 @@ export function useAllPlaylistSongs() { /** All projects, sorted by title. */ export function useAllProjects() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('mukkeProjects').toArray(); + const locals = await scopedForModule('music', 'mukkeProjects').toArray(); return locals .filter((p) => !p.deletedAt) .map(toProject) diff --git a/apps/mana/apps/web/src/lib/modules/period/queries.ts b/apps/mana/apps/web/src/lib/modules/period/queries.ts index 974eb4b4a..1bfd80b9f 100644 --- a/apps/mana/apps/web/src/lib/modules/period/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/period/queries.ts @@ -4,6 +4,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecord, decryptRecords } from '$lib/data/crypto'; import type { Period, @@ -65,9 +66,9 @@ export function toPeriodSymptom(local: LocalPeriodSymptom): PeriodSymptom { export function useAllPeriods() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('periods').toArray()).filter( - (c) => !c.deletedAt && !c.isArchived - ); + const visible = ( + await scopedForModule('period', 'periods').toArray() + ).filter((c) => !c.deletedAt && !c.isArchived); const decrypted = await decryptRecords('periods', visible); return decrypted.map(toPeriod).sort((a, b) => b.startDate.localeCompare(a.startDate)); }, [] as Period[]); @@ -76,7 +77,7 @@ export function useAllPeriods() { export function useCurrentPeriod() { return useLiveQueryWithDefault( async () => { - const locals = await db.table('periods').toArray(); + const locals = await scopedForModule('period', 'periods').toArray(); const real = locals.filter((c) => !c.deletedAt && !c.isArchived && !c.isPredicted); if (real.length === 0) return null; const latest = real.sort((a, b) => b.startDate.localeCompare(a.startDate))[0]; @@ -89,9 +90,9 @@ export function useCurrentPeriod() { export function useAllDayLogs() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('periodDayLogs').toArray()).filter( - (l) => !l.deletedAt - ); + const visible = ( + await scopedForModule('period', 'periodDayLogs').toArray() + ).filter((l) => !l.deletedAt); const decrypted = await decryptRecords('periodDayLogs', visible); return decrypted.map(toPeriodDayLog).sort((a, b) => b.logDate.localeCompare(a.logDate)); }, [] as PeriodDayLog[]); @@ -116,7 +117,10 @@ export function useDayLog(date: string) { export function useAllSymptoms() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('periodSymptoms').toArray(); + const locals = await scopedForModule( + 'period', + 'periodSymptoms' + ).toArray(); return locals .filter((s) => !s.deletedAt) .map(toPeriodSymptom) diff --git a/apps/mana/apps/web/src/lib/modules/photos/queries.ts b/apps/mana/apps/web/src/lib/modules/photos/queries.ts index a0a837c1e..f9fd8a7d9 100644 --- a/apps/mana/apps/web/src/lib/modules/photos/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/photos/queries.ts @@ -6,6 +6,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalAlbum, LocalAlbumItem, LocalFavorite, Album, AlbumItem } from './types'; // ─── Type Converters ─────────────────────────────────────── @@ -42,7 +43,7 @@ export function toAlbumItem(local: LocalAlbumItem): AlbumItem { /** All albums. Auto-updates on any change. */ export function useAllAlbums() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('albums').toArray(); + const locals = await scopedForModule('photos', 'albums').toArray(); return locals.filter((a) => !a.deletedAt).map(toAlbum); }, []); } @@ -50,7 +51,7 @@ export function useAllAlbums() { /** All album items. Auto-updates on any change. */ export function useAllAlbumItems() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('albumItems').toArray(); + const locals = await scopedForModule('photos', 'albumItems').toArray(); return locals.filter((i) => !i.deletedAt).map(toAlbumItem); }, []); } @@ -58,7 +59,10 @@ export function useAllAlbumItems() { /** All favorites. Auto-updates on any change. */ export function useAllFavorites() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('photoFavorites').toArray(); + const locals = await scopedForModule( + 'photos', + 'photoFavorites' + ).toArray(); return locals.filter((f) => !f.deletedAt); }, []); } diff --git a/apps/mana/apps/web/src/lib/modules/picture/queries.ts b/apps/mana/apps/web/src/lib/modules/picture/queries.ts index 37c44747f..42b255ae5 100644 --- a/apps/mana/apps/web/src/lib/modules/picture/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/picture/queries.ts @@ -9,6 +9,7 @@ import { liveQuery } from 'dexie'; import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalImage, @@ -69,7 +70,7 @@ export function toBoard(local: LocalBoard): Board { /** All non-archived images, sorted by createdAt desc. */ export function useAllImages() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('images').toArray(); + const locals = await scopedForModule('picture', 'images').toArray(); const visible = locals.filter((img) => !img.isArchived && !img.deletedAt); const decrypted = await decryptRecords('images', visible); return decrypted @@ -81,7 +82,7 @@ export function useAllImages() { /** All archived images, sorted by createdAt desc. */ export function useArchivedImages() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('images').toArray(); + const locals = await scopedForModule('picture', 'images').toArray(); const visible = locals.filter((img) => !!img.isArchived && !img.deletedAt); const decrypted = await decryptRecords('images', visible); return decrypted @@ -93,8 +94,11 @@ export function useArchivedImages() { /** All boards with item counts, sorted by updatedAt desc. */ export function useAllBoards() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('boards').toArray(); - const allItems = await db.table('boardItems').toArray(); + const locals = await scopedForModule('picture', 'boards').toArray(); + const allItems = await scopedForModule( + 'picture', + 'boardItems' + ).toArray(); // boardItems.textContent is encrypted but the count map only // looks at structural fields (deletedAt + boardId), so no @@ -128,7 +132,7 @@ export { useAllTags as useAllPictureTags } from '@mana/shared-stores'; /** All image-tag associations. */ export function useAllImageTags() { return useLiveQueryWithDefault(async () => { - return await db.table('imageTags').toArray(); + return await scopedForModule('picture', 'imageTags').toArray(); }, [] as LocalImageTag[]); } @@ -136,7 +140,7 @@ export function useAllImageTags() { export function allImages$() { return liveQuery(async () => { - const locals = await db.table('images').toArray(); + const locals = await scopedForModule('picture', 'images').toArray(); const visible = locals.filter((img) => !img.isArchived && !img.deletedAt); const decrypted = await decryptRecords('images', visible); return decrypted @@ -147,7 +151,7 @@ export function allImages$() { export function allBoards$() { return liveQuery(async () => { - const locals = await db.table('boards').toArray(); + const locals = await scopedForModule('picture', 'boards').toArray(); const visible = locals.filter((b) => !b.deletedAt); const decrypted = await decryptRecords('boards', visible); return decrypted.map(toBoard); diff --git a/apps/mana/apps/web/src/lib/modules/places/queries.ts b/apps/mana/apps/web/src/lib/modules/places/queries.ts index e23d63277..5b6a5f237 100644 --- a/apps/mana/apps/web/src/lib/modules/places/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/places/queries.ts @@ -4,6 +4,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalPlace, LocalLocationLog, Place, LocationLog } from './types'; @@ -46,7 +47,7 @@ export function toLocationLog(local: LocalLocationLog): LocationLog { export function useAllPlaces() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('places').toArray(); + const locals = await scopedForModule('places', 'places').toArray(); const visible = locals.filter((p) => !p.deletedAt); const decrypted = await decryptRecords('places', visible); return decrypted.map(toPlace); diff --git a/apps/mana/apps/web/src/lib/modules/plants/queries.ts b/apps/mana/apps/web/src/lib/modules/plants/queries.ts index d47226a4f..52328e492 100644 --- a/apps/mana/apps/web/src/lib/modules/plants/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/plants/queries.ts @@ -8,6 +8,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { Tag } from '@mana/shared-tags'; import type { @@ -99,7 +100,9 @@ export function toWateringLog(local: LocalWateringLog): WateringLog { /** All plants. Auto-updates on any change. */ export function useAllPlants() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('plants').toArray()).filter((p) => !p.deletedAt); + const visible = ( + await scopedForModule('plants', 'plants').toArray() + ).filter((p) => !p.deletedAt); const decrypted = await decryptRecords('plants', visible); return decrypted.map(toPlant); }, []); @@ -108,7 +111,10 @@ export function useAllPlants() { /** All plant photos. Auto-updates on any change. */ export function useAllPlantPhotos() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('plantPhotos').toArray(); + const locals = await scopedForModule( + 'plants', + 'plantPhotos' + ).toArray(); return locals.filter((p) => !p.deletedAt).map(toPlantPhoto); }, []); } @@ -116,7 +122,10 @@ export function useAllPlantPhotos() { /** All watering schedules. Auto-updates on any change. */ export function useAllWateringSchedules() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('wateringSchedules').toArray(); + const locals = await scopedForModule( + 'plants', + 'wateringSchedules' + ).toArray(); return locals.filter((s) => !s.deletedAt).map(toWateringSchedule); }, []); } @@ -124,7 +133,10 @@ export function useAllWateringSchedules() { /** All watering logs. Auto-updates on any change. */ export function useAllWateringLogs() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('wateringLogs').toArray(); + const locals = await scopedForModule( + 'plants', + 'wateringLogs' + ).toArray(); return locals.filter((l) => !l.deletedAt).map(toWateringLog); }, []); } @@ -132,7 +144,7 @@ export function useAllWateringLogs() { /** All plant↔tag junctions (active only). */ export function useAllPlantTags() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('plantTags').toArray(); + const locals = await scopedForModule('plants', 'plantTags').toArray(); return locals.filter((t) => !t.deletedAt); }, []); } diff --git a/apps/mana/apps/web/src/lib/modules/playground/queries.ts b/apps/mana/apps/web/src/lib/modules/playground/queries.ts index d686a762c..981afae4e 100644 --- a/apps/mana/apps/web/src/lib/modules/playground/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/playground/queries.ts @@ -8,6 +8,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalPlaygroundSnippet, @@ -85,7 +86,10 @@ export function toMessage(local: LocalPlaygroundMessage): PlaygroundConversation export function useAllConversations() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('playgroundConversations').toArray(); + const locals = await scopedForModule( + 'playground', + 'playgroundConversations' + ).toArray(); const visible = locals.filter((c) => !c.deletedAt); const decrypted = await decryptRecords( 'playgroundConversations', diff --git a/apps/mana/apps/web/src/lib/modules/presi/queries.ts b/apps/mana/apps/web/src/lib/modules/presi/queries.ts index 11deca0bb..76088b587 100644 --- a/apps/mana/apps/web/src/lib/modules/presi/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/presi/queries.ts @@ -6,6 +6,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecord, decryptRecords } from '$lib/data/crypto'; import type { LocalDeck, LocalSlide, Deck, Slide } from './types'; @@ -40,7 +41,9 @@ export function toSlide(local: LocalSlide): Slide { /** All decks, sorted by updatedAt descending. Auto-updates on any change. */ export function useAllDecks() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('presiDecks').toArray()).filter((d) => !d.deletedAt); + const visible = ( + await scopedForModule('presi', 'presiDecks').toArray() + ).filter((d) => !d.deletedAt); const decrypted = await decryptRecords('presiDecks', visible); return decrypted .map(toDeck) diff --git a/apps/mana/apps/web/src/lib/modules/questions/queries.ts b/apps/mana/apps/web/src/lib/modules/questions/queries.ts index 2c801b638..00ee3ea9d 100644 --- a/apps/mana/apps/web/src/lib/modules/questions/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/questions/queries.ts @@ -6,6 +6,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalCollection, LocalQuestion, LocalAnswer } from './types'; @@ -103,7 +104,10 @@ export function toAnswer(local: LocalAnswer): Answer { /** All collections, sorted by sortOrder. Auto-updates on any change. */ export function useAllCollections() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('qCollections').toArray(); + const locals = await scopedForModule( + 'questions', + 'qCollections' + ).toArray(); return locals .filter((c) => !c.deletedAt) .sort((a, b) => a.sortOrder - b.sortOrder) @@ -114,7 +118,7 @@ export function useAllCollections() { /** All questions. Auto-updates on any change. */ export function useAllQuestions() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('questions').toArray(); + const locals = await scopedForModule('questions', 'questions').toArray(); const visible = locals.filter((q) => !q.deletedAt); const decrypted = await decryptRecords('questions', visible); return decrypted.map(toQuestion); @@ -124,7 +128,7 @@ export function useAllQuestions() { /** All answers for a given question. */ export function useAnswersByQuestion(questionId: string) { return useLiveQueryWithDefault(async () => { - const locals = await db.table('answers').toArray(); + const locals = await scopedForModule('questions', 'answers').toArray(); const visible = locals.filter((a) => !a.deletedAt && a.questionId === questionId); const decrypted = await decryptRecords('answers', visible); return decrypted.map(toAnswer); diff --git a/apps/mana/apps/web/src/lib/modules/quiz/queries.ts b/apps/mana/apps/web/src/lib/modules/quiz/queries.ts index bc102334b..64bb9f4d4 100644 --- a/apps/mana/apps/web/src/lib/modules/quiz/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/quiz/queries.ts @@ -9,6 +9,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalQuiz, @@ -69,7 +70,7 @@ export function toAttempt(local: LocalQuizAttempt): QuizAttempt { export function useAllQuizzes() { return useLiveQueryWithDefault(async () => { - const visible = (await db.table('quizzes').toArray()).filter( + const visible = (await scopedForModule('quiz', 'quizzes').toArray()).filter( (q) => !q.deletedAt && !q.isArchived ); const decrypted = await decryptRecords('quizzes', visible); diff --git a/apps/mana/apps/web/src/lib/modules/quotes/queries.ts b/apps/mana/apps/web/src/lib/modules/quotes/queries.ts index 927944a9d..cb3ddab39 100644 --- a/apps/mana/apps/web/src/lib/modules/quotes/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/quotes/queries.ts @@ -4,6 +4,7 @@ import { liveQuery } from 'dexie'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalFavorite, LocalQuoteList, LocalCustomQuote } from './types'; // ─── Domain Types ───────────────────────────────────────── @@ -73,7 +74,10 @@ export function toQuoteList(local: LocalQuoteList): QuoteList { /** All favorites. Auto-updates on any change. */ export function useAllFavorites() { return liveQuery(async () => { - const locals = await db.table('quotesFavorites').toArray(); + const locals = await scopedForModule( + 'quotes', + 'quotesFavorites' + ).toArray(); return locals.filter((f) => !f.deletedAt).map(toFavorite); }); } @@ -81,7 +85,7 @@ export function useAllFavorites() { /** All lists. Auto-updates on any change. */ export function useAllLists() { return liveQuery(async () => { - const locals = await db.table('quotesLists').toArray(); + const locals = await scopedForModule('quotes', 'quotesLists').toArray(); return locals.filter((l) => !l.deletedAt).map(toQuoteList); }); } @@ -89,7 +93,10 @@ export function useAllLists() { /** All custom quotes. Auto-updates on any change. */ export function useAllCustomQuotes() { return liveQuery(async () => { - const locals = await db.table('customQuotes').toArray(); + const locals = await scopedForModule( + 'quotes', + 'customQuotes' + ).toArray(); return locals.filter((q) => !q.deletedAt).map(toCustomQuote); }); } diff --git a/apps/mana/apps/web/src/lib/modules/recipes/queries.ts b/apps/mana/apps/web/src/lib/modules/recipes/queries.ts index e13c33005..d01c7e750 100644 --- a/apps/mana/apps/web/src/lib/modules/recipes/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/recipes/queries.ts @@ -5,6 +5,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { decryptRecords } from '$lib/data/crypto'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalRecipe, Recipe, Difficulty } from './types'; // ─── Type Converter ────────────────────────────────────── @@ -35,7 +36,7 @@ export function toRecipe(local: LocalRecipe): Recipe { export function useAllRecipes() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('recipes').toArray(); + const locals = await scopedForModule('recipes', 'recipes').toArray(); const visible = locals.filter((r) => !r.deletedAt); const decrypted = await decryptRecords('recipes', visible); return decrypted.map(toRecipe); diff --git a/apps/mana/apps/web/src/lib/modules/skilltree/queries.ts b/apps/mana/apps/web/src/lib/modules/skilltree/queries.ts index afcc25b42..950d5d8c4 100644 --- a/apps/mana/apps/web/src/lib/modules/skilltree/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/skilltree/queries.ts @@ -8,6 +8,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalSkill, LocalActivity, LocalAchievement } from './types'; import type { Skill, Activity, SkillBranch, UserStats } from './types'; import { BRANCH_INFO } from './types'; @@ -47,7 +48,7 @@ export function toActivity(local: LocalActivity): Activity { /** All skills, auto-updates on any change. */ export function useAllSkills() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('skills').toArray(); + const locals = await scopedForModule('skilltree', 'skills').toArray(); return locals.filter((s) => !s.deletedAt).map(toSkill); }, [] as Skill[]); } @@ -55,7 +56,10 @@ export function useAllSkills() { /** All activities, auto-updates on any change. */ export function useAllActivities() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('activities').toArray(); + const locals = await scopedForModule( + 'skilltree', + 'activities' + ).toArray(); return locals.filter((a) => !a.deletedAt).map(toActivity); }, [] as Activity[]); } @@ -63,7 +67,10 @@ export function useAllActivities() { /** All achievements (raw local records), auto-updates on any change. */ export function useAllAchievements() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('achievements').toArray(); + const locals = await scopedForModule( + 'skilltree', + 'achievements' + ).toArray(); return locals.filter((a) => !a.deletedAt); }, [] as LocalAchievement[]); } diff --git a/apps/mana/apps/web/src/lib/modules/sleep/queries.ts b/apps/mana/apps/web/src/lib/modules/sleep/queries.ts index 8dd0dbf1e..e0b3c8817 100644 --- a/apps/mana/apps/web/src/lib/modules/sleep/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/sleep/queries.ts @@ -7,6 +7,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { decryptRecords } from '$lib/data/crypto'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalSleepEntry, LocalSleepHygieneLog, @@ -84,7 +85,10 @@ export function toSleepSettings(local: LocalSleepSettings): SleepSettings { export function useAllSleepEntries() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('sleepEntries').toArray(); + const locals = await scopedForModule( + 'sleep', + 'sleepEntries' + ).toArray(); const visible = locals.filter((e) => !e.deletedAt); const decrypted = await decryptRecords('sleepEntries', visible); return decrypted.map(toSleepEntry).sort((a, b) => b.date.localeCompare(a.date)); @@ -93,7 +97,10 @@ export function useAllSleepEntries() { export function useAllSleepHygieneLogs() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('sleepHygieneLogs').toArray(); + const locals = await scopedForModule( + 'sleep', + 'sleepHygieneLogs' + ).toArray(); const visible = locals.filter((l) => !l.deletedAt); return visible.map(toSleepHygieneLog).sort((a, b) => b.date.localeCompare(a.date)); }, [] as SleepHygieneLog[]); @@ -101,7 +108,10 @@ export function useAllSleepHygieneLogs() { export function useAllSleepHygieneChecks() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('sleepHygieneChecks').toArray(); + const locals = await scopedForModule( + 'sleep', + 'sleepHygieneChecks' + ).toArray(); const visible = locals.filter((c) => !c.deletedAt); const decrypted = await decryptRecords('sleepHygieneChecks', visible); return decrypted.map(toSleepHygieneCheck).sort((a, b) => a.order - b.order); @@ -111,7 +121,10 @@ export function useAllSleepHygieneChecks() { export function useSleepSettings() { return useLiveQueryWithDefault( async () => { - const locals = await db.table('sleepSettings').toArray(); + const locals = await scopedForModule( + 'sleep', + 'sleepSettings' + ).toArray(); const row = locals.find((s) => !s.deletedAt); return row ? toSleepSettings(row) : null; }, diff --git a/apps/mana/apps/web/src/lib/modules/storage/queries.ts b/apps/mana/apps/web/src/lib/modules/storage/queries.ts index 2761adfdb..985cdfd2b 100644 --- a/apps/mana/apps/web/src/lib/modules/storage/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/storage/queries.ts @@ -6,6 +6,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalFile, LocalFolder, LocalFileTag } from './types'; @@ -107,7 +108,7 @@ export function toTag(local: { /** All non-deleted files, sorted by name. Auto-updates on any change. */ export function useAllFiles() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('files').toArray(); + const locals = await scopedForModule('storage', 'files').toArray(); const visible = locals.filter((f) => !f.isDeleted && !f.deletedAt); // name + originalName are encrypted on disk; sort needs plaintext. const decrypted = await decryptRecords('files', visible); @@ -118,7 +119,10 @@ export function useAllFiles() { /** All non-deleted folders, sorted by name. Auto-updates on any change. */ export function useAllFolders() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('storageFolders').toArray(); + const locals = await scopedForModule( + 'storage', + 'storageFolders' + ).toArray(); return locals .filter((f) => !f.isDeleted && !f.deletedAt) .map(toFolder) diff --git a/apps/mana/apps/web/src/lib/modules/stretch/queries.ts b/apps/mana/apps/web/src/lib/modules/stretch/queries.ts index 18ccd497a..47ba89a17 100644 --- a/apps/mana/apps/web/src/lib/modules/stretch/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/stretch/queries.ts @@ -7,6 +7,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { decryptRecords } from '$lib/data/crypto'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { LocalStretchExercise, LocalStretchRoutine, @@ -109,7 +110,10 @@ export function toStretchReminder(local: LocalStretchReminder): StretchReminder export function useAllStretchExercises() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('stretchExercises').toArray(); + const locals = await scopedForModule( + 'stretch', + 'stretchExercises' + ).toArray(); const visible = locals.filter((e) => !e.deletedAt); const decrypted = await decryptRecords('stretchExercises', visible); return decrypted.map(toStretchExercise).sort((a, b) => a.order - b.order); @@ -118,7 +122,10 @@ export function useAllStretchExercises() { export function useAllStretchRoutines() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('stretchRoutines').toArray(); + const locals = await scopedForModule( + 'stretch', + 'stretchRoutines' + ).toArray(); const visible = locals.filter((r) => !r.deletedAt); const decrypted = await decryptRecords('stretchRoutines', visible); return decrypted.map(toStretchRoutine).sort((a, b) => a.order - b.order); @@ -127,7 +134,10 @@ export function useAllStretchRoutines() { export function useAllStretchSessions() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('stretchSessions').toArray(); + const locals = await scopedForModule( + 'stretch', + 'stretchSessions' + ).toArray(); const visible = locals.filter((s) => !s.deletedAt); const decrypted = await decryptRecords('stretchSessions', visible); return decrypted.map(toStretchSession).sort((a, b) => b.startedAt.localeCompare(a.startedAt)); @@ -136,7 +146,10 @@ export function useAllStretchSessions() { export function useAllStretchAssessments() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('stretchAssessments').toArray(); + const locals = await scopedForModule( + 'stretch', + 'stretchAssessments' + ).toArray(); const visible = locals.filter((a) => !a.deletedAt); const decrypted = await decryptRecords('stretchAssessments', visible); return decrypted @@ -147,7 +160,10 @@ export function useAllStretchAssessments() { export function useAllStretchReminders() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('stretchReminders').toArray(); + const locals = await scopedForModule( + 'stretch', + 'stretchReminders' + ).toArray(); const visible = locals.filter((r) => !r.deletedAt); const decrypted = await decryptRecords('stretchReminders', visible); return decrypted.map(toStretchReminder); diff --git a/apps/mana/apps/web/src/lib/modules/times/queries.ts b/apps/mana/apps/web/src/lib/modules/times/queries.ts index dbf4f9889..3e2ecd175 100644 --- a/apps/mana/apps/web/src/lib/modules/times/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/times/queries.ts @@ -6,6 +6,7 @@ import { liveQuery } from 'dexie'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import type { LocalClient, @@ -171,21 +172,21 @@ export function toWorldClock(local: LocalWorldClock): WorldClock { export function useAllClients() { return liveQuery(async () => { - const locals = await db.table('timeClients').toArray(); + const locals = await scopedForModule('times', 'timeClients').toArray(); return locals.filter((c) => !c.deletedAt).map(toClient); }); } export function useAllProjects() { return liveQuery(async () => { - const locals = await db.table('timeProjects').toArray(); + const locals = await scopedForModule('times', 'timeProjects').toArray(); return locals.filter((p) => !p.deletedAt).map(toProject); }); } export function useAllTimeEntries() { return liveQuery(async () => { - const locals = await db.table('timeEntries').toArray(); + const locals = await scopedForModule('times', 'timeEntries').toArray(); const active = locals.filter((e) => !e.deletedAt); // Batch-fetch all related timeBlocks @@ -205,14 +206,14 @@ export { useAllTags } from '@mana/shared-stores'; export function useAllTemplates() { return liveQuery(async () => { - const locals = await db.table('timeTemplates').toArray(); + const locals = await scopedForModule('times', 'timeTemplates').toArray(); return locals.filter((t) => !t.deletedAt).map(toTemplate); }); } export function useSettings() { return liveQuery(async () => { - const locals = await db.table('timeSettings').toArray(); + const locals = await scopedForModule('times', 'timeSettings').toArray(); const active = locals.filter((s) => !s.deletedAt); return active.length > 0 ? toSettings(active[0]) : null; }); @@ -223,7 +224,7 @@ export function useSettings() { /** All alarms as raw observable. */ export function allAlarms$() { return liveQuery(async () => { - const locals = await db.table('timeAlarms').toArray(); + const locals = await scopedForModule('times', 'timeAlarms').toArray(); return locals.filter((a) => !a.deletedAt).map(toAlarm); }); } @@ -231,7 +232,10 @@ export function allAlarms$() { /** All countdown timers as raw observable. */ export function allCountdownTimers$() { return liveQuery(async () => { - const locals = await db.table('timeCountdownTimers').toArray(); + const locals = await scopedForModule( + 'times', + 'timeCountdownTimers' + ).toArray(); return locals.filter((t) => !t.deletedAt).map(toCountdownTimer); }); } @@ -252,7 +256,7 @@ export function allWorldClocks$() { /** All alarms, auto-updates on any change. Returns { value, loading, error }. */ export function useAllAlarms() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('timeAlarms').toArray(); + const locals = await scopedForModule('times', 'timeAlarms').toArray(); return locals.filter((a) => !a.deletedAt).map(toAlarm); }, [] as Alarm[]); } @@ -260,7 +264,10 @@ export function useAllAlarms() { /** All countdown timers, auto-updates on any change. Returns { value, loading, error }. */ export function useAllCountdownTimers() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('timeCountdownTimers').toArray(); + const locals = await scopedForModule( + 'times', + 'timeCountdownTimers' + ).toArray(); return locals.filter((t) => !t.deletedAt).map(toCountdownTimer); }, [] as Timer[]); } diff --git a/apps/mana/apps/web/src/lib/modules/uload/queries.ts b/apps/mana/apps/web/src/lib/modules/uload/queries.ts index 67507e098..e91e20db4 100644 --- a/apps/mana/apps/web/src/lib/modules/uload/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/uload/queries.ts @@ -8,6 +8,7 @@ import { liveQuery } from 'dexie'; import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecord, decryptRecords } from '$lib/data/crypto'; import type { LocalLink, LocalTag, LocalFolder, LocalLinkTag } from './types'; @@ -133,7 +134,7 @@ export function toLinkTag(local: LocalLinkTag): LinkTag { export function allLinks$() { return liveQuery(async () => { - const locals = await db.table('links').toArray(); + const locals = await scopedForModule('uload', 'links').toArray(); const visible = locals.filter((l) => !l.deletedAt); const decrypted = await decryptRecords('links', visible); return decrypted.map(toLink); @@ -142,21 +143,21 @@ export function allLinks$() { export function allTags$() { return liveQuery(async () => { - const locals = await db.table('uloadTags').toArray(); + const locals = await scopedForModule('uload', 'uloadTags').toArray(); return locals.filter((t) => !t.deletedAt).map(toTag); }); } export function allFolders$() { return liveQuery(async () => { - const locals = await db.table('uloadFolders').toArray(); + const locals = await scopedForModule('uload', 'uloadFolders').toArray(); return locals.filter((f) => !f.deletedAt).map(toFolder); }); } export function allLinkTags$() { return liveQuery(async () => { - const locals = await db.table('linkTags').toArray(); + const locals = await scopedForModule('uload', 'linkTags').toArray(); return locals.filter((lt) => !lt.deletedAt).map(toLinkTag); }); } @@ -165,7 +166,7 @@ export function allLinkTags$() { export function useAllLinks() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('links').toArray(); + const locals = await scopedForModule('uload', 'links').toArray(); const visible = locals.filter((l) => !l.deletedAt); const decrypted = await decryptRecords('links', visible); return decrypted.map(toLink); @@ -174,21 +175,23 @@ export function useAllLinks() { export function useAllTags() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('uloadTags').toArray(); + const locals = await scopedForModule('uload', 'uloadTags').toArray(); return locals.filter((t) => !t.deletedAt).map(toTag); }, [] as Tag[]); } export function useAllFolders() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('uloadFolders').orderBy('order').toArray(); + const locals = await scopedForModule('uload', 'uloadFolders').sortBy( + 'order' + ); return locals.filter((f) => !f.deletedAt).map(toFolder); }, [] as Folder[]); } export function useAllLinkTags() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('linkTags').toArray(); + const locals = await scopedForModule('uload', 'linkTags').toArray(); return locals.filter((lt) => !lt.deletedAt).map(toLinkTag); }, [] as LinkTag[]); } diff --git a/apps/mana/apps/web/src/lib/modules/wetter/queries.ts b/apps/mana/apps/web/src/lib/modules/wetter/queries.ts index 67fdbd12b..ad861f65c 100644 --- a/apps/mana/apps/web/src/lib/modules/wetter/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/wetter/queries.ts @@ -4,11 +4,12 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import type { WeatherLocation, WeatherSettings } from './types'; export function useLocations() { return useLiveQueryWithDefault( - () => db.table('wetterLocations').orderBy('order').toArray(), + () => scopedForModule('wetter', 'wetterLocations').sortBy('order'), [] as WeatherLocation[] ); } diff --git a/apps/mana/apps/web/src/lib/modules/wishes/queries.ts b/apps/mana/apps/web/src/lib/modules/wishes/queries.ts index 6bcd667f3..a42c12f72 100644 --- a/apps/mana/apps/web/src/lib/modules/wishes/queries.ts +++ b/apps/mana/apps/web/src/lib/modules/wishes/queries.ts @@ -4,6 +4,7 @@ import { useLiveQueryWithDefault } from '@mana/local-store/svelte'; import { db } from '$lib/data/database'; +import { scopedForModule } from '$lib/data/scope'; import { decryptRecords } from '$lib/data/crypto'; import type { LocalWish, @@ -68,7 +69,9 @@ export function toPriceCheck(local: LocalPriceCheck): PriceCheck { export function useAllWishes() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('wishesItems').orderBy('order').toArray(); + const locals = await scopedForModule('wishes', 'wishesItems').sortBy( + 'order' + ); const visible = locals.filter((w) => !w.deletedAt); const decrypted = await decryptRecords('wishesItems', visible); return decrypted.map(toWish); @@ -77,7 +80,9 @@ export function useAllWishes() { export function useAllLists() { return useLiveQueryWithDefault(async () => { - const locals = await db.table('wishesLists').orderBy('order').toArray(); + const locals = await scopedForModule('wishes', 'wishesLists').sortBy( + 'order' + ); const visible = locals.filter((l) => !l.deletedAt && !l.isArchived); return visible.map(toWishList); }, [] as WishList[]);