# Wiring Frontend to the C# Backend This document explains how to connect the `Journal.App` frontend to the C# backend in this repository. ## Current Backend Reality In this repo today, the C# backend projects in `Journal.slnx` are: - `Journal.Core` - `Journal.Sidecar` - `Journal.SmokeTests` There is currently **no** `Journal.Api` project in the solution file, so the primary integration path is: - Frontend (Svelte/Tauri) -> Tauri bridge -> `Journal.Sidecar` (stdin/stdout JSON protocol) ## Command Protocol (C#) `Journal.Core.Entry.HandleCommandAsync` accepts a JSON command envelope and returns: - success: `{ "ok": true, "data": ... }` - failure: `{ "ok": false, "error": "..." }` Command model (`Journal.Core/Models/Command.cs`): ```json { "action": "entries.list", "correlationId": "optional-string", "id": "optional", "type": "optional", "tag": "optional", "payload": {} } ``` Useful actions for frontend wiring: - `entries.list` - `entries.load` - `entries.save` - `search.entries` - `vault.load_all` - `vault.save_current_month` - `db.status` - `db.hydrate_workspace` ## Recommended Integration (Sidecar Bridge) Use a small frontend client that sends commands through one bridge function. The bridge can be backed by: - a Tauri command that talks to a managed sidecar process, or - a local HTTP adapter (if you add one). ### 1. Define shared frontend command/response types Create `Journal.App/src/lib/backend/types.ts`: ```ts export type BackendCommand = { action: string; correlationId?: string; id?: string; type?: string; tag?: string; payload?: unknown; }; export type BackendOk = { ok: true; data: T }; export type BackendErr = { ok: false; error: string }; export type BackendResponse = BackendOk | BackendErr; ``` ### 2. Create one backend client entrypoint Create `Journal.App/src/lib/backend/client.ts`: ```ts import { invoke } from "@tauri-apps/api/core"; import type { BackendCommand, BackendResponse } from "./types"; export async function sendCommand(command: BackendCommand): Promise { const response = await invoke>("sidecar_command", { command }); if (!response.ok) { throw new Error(response.error || "Backend command failed"); } return response.data; } ``` This keeps all UI code backend-agnostic. ### 3. Build domain helpers (entries example) Create `Journal.App/src/lib/backend/entries.ts`: ```ts import { sendCommand } from "./client"; export async function listEntries(dataDirectory?: string) { return sendCommand({ action: "entries.list", payload: { dataDirectory } }); } export async function loadEntry(filePath: string) { return sendCommand<{ filePath: string; content: string; section?: string }>({ action: "entries.load", payload: { filePath } }); } export async function saveEntry(args: { filePath?: string; content: string; title?: string; section?: string; date?: string; }) { return sendCommand<{ filePath: string }>({ action: "entries.save", payload: args }); } ``` ### 4. Use client in UI state In page/component code: - on panel item click: call `loadEntry(filePath)` - on editor save button: call `saveEntry({ filePath, content })` - on app init: call `listEntries()` to populate list ## Tauri Bridge Notes Your frontend should not spawn/process-manage the sidecar directly. Keep that in the Tauri layer. Bridge responsibilities: - start and keep one sidecar process alive - write command JSON lines to sidecar stdin - read stdout lines and map responses by `correlationId` - return parsed response to frontend - restart sidecar if it crashes If you have not implemented this yet, create one Tauri command such as: - `sidecar_command(command)` and route all frontend calls through it. ## Vault/Auth Flow Recommended startup sequence: 1. Prompt for vault password in UI. 2. Call `vault.load_all` (or `db.hydrate_workspace`) once. 3. Backend stores session password (`DatabaseSessionService`) for subsequent commands. 4. Continue with `entries.list`, `entries.load`, etc. Do not store raw vault password in long-lived frontend state. ## Error Handling Pattern Always normalize backend errors in one place: - backend client throws `Error(message)` when `ok: false` - UI catches and displays your custom modal - include `correlationId` on commands for tracing/logging ## Optional HTTP Path (If You Add Journal.Api) If you later add `Journal.Api` with `POST /api/command`, keep the same command envelope and swap transport only: - replace `invoke("sidecar_command", ...)` with `fetch("/api/command", ...)` - keep `sendCommand` interface unchanged That lets UI code remain identical. ## Minimal Next Steps 1. Add `src/lib/backend/types.ts`, `client.ts`, `entries.ts`. 2. Wire `EditorPanel` save button to `entries.save`. 3. Wire `SidePanel` item load to `entries.load`. 4. Add vault unlock modal + `vault.load_all` on startup. 5. Keep all backend calls behind `sendCommand` only. ## Frontend Store Architecture (Current) Current frontend uses feature stores in `Journal.App/src/lib/stores/`: - `entries.ts` -> `entriesStore` - `fragments.ts` -> `fragmentsStore` - `todos.ts` -> `todoListsStore`, `todosStore` - `lists.ts` -> `listsStore` - `settings.ts` -> `settingsTags`, `settingsFragmentTypes` Current pattern is store-first for most feature CRUD and parsing (especially fragments and todos), with UI components invoking store helpers. ## State/CRUD Gaps Still Needed To fully standardize state management: 1. Move settings add/edit/remove logic into `settings.ts` helper functions (currently in route component code). 2. Add full CRUD helpers for `entries.ts` and `lists.ts` (update/remove/reorder, not only draft creation). 3. Make todo list metadata + todo items update atomically through a single store API wrapper. 4. Move calendar-created entries out of local component state into a dedicated calendar store. 5. Add persistence/hydration strategy between stores and backend (`entries.load/save`, `vault.load_all`, etc.). ## Recommended Rule - Keep all feature data mutations in store helper APIs. - Keep route/component files focused on view state and command orchestration. - Keep backend transport (`sendCommand`) separate from pure local store mutation helpers, then compose both in thin feature services.