diff --git a/apps/mobile/src/demoData.ts b/apps/mobile/src/demoData.ts index 31270846..50ba2ef8 100644 --- a/apps/mobile/src/demoData.ts +++ b/apps/mobile/src/demoData.ts @@ -1,4 +1,5 @@ import { projectMobileNotes, type MobileNote, type MobileNoteSource } from './mobileNoteProjection' +import { createFixtureMobileVaultRepository } from './mobileVaultRepository' export type { MobileNote } from './mobileNoteProjection' @@ -67,6 +68,8 @@ const noteContent: MobileNoteSource[] = [ export const notes: MobileNote[] = projectMobileNotes(noteContent) +export const demoVaultRepository = createFixtureMobileVaultRepository(noteContent) + export const sidebarSections = [ { title: 'Library', diff --git a/apps/mobile/src/mobileVaultRepository.test.ts b/apps/mobile/src/mobileVaultRepository.test.ts new file mode 100644 index 00000000..ce67dc90 --- /dev/null +++ b/apps/mobile/src/mobileVaultRepository.test.ts @@ -0,0 +1,46 @@ +import { describe, expect, it } from 'vitest' +import { createFixtureMobileVaultRepository } from './mobileVaultRepository' +import type { MobileNoteSource } from './mobileNoteProjection' + +const sources: MobileNoteSource[] = [ + createSource('workflow', 'Workflow Orchestration Essay'), + createSource('release', 'v2026-05-02'), +] + +describe('mobile vault repository', () => { + it('lists projected notes in vault order', async () => { + const repository = createFixtureMobileVaultRepository(sources) + const notes = await repository.listNotes() + + expect(notes.map((note) => note.id)).toEqual(['workflow', 'release']) + expect(notes[0].title).toBe('Workflow Orchestration Essay') + }) + + it('reads a projected note by id', async () => { + const repository = createFixtureMobileVaultRepository(sources) + + await expect(repository.readNote('release')).resolves.toMatchObject({ + id: 'release', + title: 'v2026-05-02', + }) + }) + + it('returns null for missing notes', async () => { + const repository = createFixtureMobileVaultRepository(sources) + + await expect(repository.readNote('missing')).resolves.toBeNull() + }) +}) + +function createSource(id: string, title: string): MobileNoteSource { + return { + id, + type: 'Essay', + icon: 'pen-nib', + date: 'May 13, 2026', + modified: '6h ago', + filename: `${id}.md`, + tags: ['Tolaria MVP'], + content: `---\ntitle: ${title}\n---\n\n# ${title}\n\nBody text for ${title}.`, + } +} diff --git a/apps/mobile/src/mobileVaultRepository.ts b/apps/mobile/src/mobileVaultRepository.ts new file mode 100644 index 00000000..18fb394c --- /dev/null +++ b/apps/mobile/src/mobileVaultRepository.ts @@ -0,0 +1,15 @@ +import { projectMobileNotes, type MobileNote, type MobileNoteSource } from './mobileNoteProjection' + +export type MobileVaultRepository = { + listNotes: () => Promise + readNote: (id: string) => Promise +} + +export function createFixtureMobileVaultRepository(sources: MobileNoteSource[]): MobileVaultRepository { + const notes = projectMobileNotes(sources) + + return { + listNotes: () => Promise.resolve(notes), + readNote: (id) => Promise.resolve(notes.find((note) => note.id === id) ?? null), + } +} diff --git a/docs/MOBILE_PROGRESS.md b/docs/MOBILE_PROGRESS.md index 71d74c4d..f8a3bfff 100644 --- a/docs/MOBILE_PROGRESS.md +++ b/docs/MOBILE_PROGRESS.md @@ -8,7 +8,7 @@ This file is the resumable working log for Tolaria mobile. The strategy and road - Branch: `codex/mobile` - Active phase: Phase 2 - Mobile Shell -- Active slice: Separate mobile note projection from fixtures +- Active slice: Define mobile vault repository boundary - Push policy: commit locally; do not push unless explicitly requested - Validation target: iPad/iOS simulator first @@ -36,6 +36,7 @@ This file is the resumable working log for Tolaria mobile. The strategy and road - Pinned Expo runtime dependencies to the versions expected by Expo 55 after the initial generated versions failed iOS bundle export (`react-native@0.83.6`, `react@19.2.0`, matching safe-area/svg versions). - Extracted compact phone navigation into a pure tested state machine so future swipe gestures can dispatch explicit events instead of mutating panels ad hoc. - Extracted mobile note projection into a pure module that turns raw vault-like note records into the list/editor shape used by the mobile shell. +- Added a minimal mobile vault repository contract plus fixture implementation so app-local vault storage and git sync can plug in behind `listNotes` / `readNote` later. ## Next Action @@ -90,6 +91,10 @@ Continue Phase 2 with the next mobile shell slice: - `pnpm --filter @tolaria/mobile typecheck` passed after note projection extraction. - CodeScene after note projection extraction: `apps/mobile/src/mobileNoteProjection.ts` and `apps/mobile/src/mobileNoteProjection.test.ts` scored `10`; `apps/mobile/src/demoData.ts` returned no scorable code and no findings. - `pnpm --filter @tolaria/mobile exec expo export --platform ios --output-dir /tmp/tolaria-mobile-export` passed after note projection extraction. +- `pnpm --filter @tolaria/mobile test` passed after mobile vault repository extraction: 4 files / 11 tests. +- `pnpm --filter @tolaria/mobile typecheck` passed after mobile vault repository extraction. +- CodeScene after mobile vault repository extraction: `apps/mobile/src/mobileVaultRepository.ts` and `apps/mobile/src/mobileVaultRepository.test.ts` scored `10`; `apps/mobile/src/demoData.ts` still returned no scorable code and no findings. +- `pnpm --filter @tolaria/mobile exec expo export --platform ios --output-dir /tmp/tolaria-mobile-export` passed after mobile vault repository extraction. ## Risks / Watch Items