# amittras-pal/silent-memoirs architecture

> Architecture diagram of the GitHub repository amittras-pal/silent-memoirs, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/amittras-pal/silent-memoirs
- Repository: https://github.com/amittras-pal/silent-memoirs

## Overview

Silent Memoirs is a browser-based, encrypted journal backed by Google Drive. The main workflow connects a Google account, unlocks or sets up a vault, then lets the user write entries and browse or view saved entries; the app also provides an emotion-record book and PDF export. The graph follows explicit routing and sampled calls. Several feature modules are represented from the tree, but their internal wiring is not inferred where source was not sampled.

Main entry points: [`app/src/components/ProtectedLayout.tsx`](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/components/ProtectedLayout.tsx) (Protected layout), [`app/src/contexts/AppContext.tsx`](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/contexts/AppContext.tsx) (App state), [`app/src/workers/exportPdf.worker.ts`](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/workers/exportPdf.worker.ts) (PDF export worker), [`app/src/lib/sync.ts`](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/sync.ts) (Journal sync)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_access["Access and vault"]
  node_app["App routes<br/>[App.tsx]"]
  node_auth["Google login<br/>[AuthWall.tsx]"]
  node_session["Session refresh<br/>[SessionManager.tsx]"]
  node_vaultwall["Vault setup<br/>[VaultSetupWall.tsx]"]
  node_protected["Protected layout"]
end

subgraph group_journal["Journal workflow"]
  node_editor["Entry editor<br/>[index.tsx]"]
  node_editorui["Editor UI<br/>[Editor.tsx]"]
  node_entries["Entry browser<br/>[index.tsx]"]
  node_viewer["Entry viewer<br/>[index.tsx]"]
  node_past["Past entries<br/>[useLastEntry.ts]"]
end

subgraph group_features["Journal features"]
  node_emotion["Emotion book<br/>[index.tsx]"]
  node_emotionhook["Emotion records<br/>[useEmotionBook.ts]"]
  node_settings["Settings<br/>[index.tsx]"]
  node_exportworker["PDF export worker"]
  node_renderer["PDF renderer<br/>[pdfRenderer.ts]"]
end

subgraph group_runtime["Sync and export"]
  node_context["App state<br/>[AppContext.tsx]"]
  node_vault["Vault manager<br/>[vault.ts]"]
  node_storage["Drive storage<br/>[storage.ts]"]
  node_sync["Journal sync<br/>[sync.ts]"]
  node_media["Media helpers<br/>[media.ts]"]
  node_staged[("Staged media<br/>[stagedMedia.ts]")]
  node_crypto["Encryption<br/>[crypto.ts]"]
end

node_user(("User"))
node_google[("Google Drive")]

node_user -->|"connects account"| node_auth
node_auth -->|"OAuth token"| node_google
node_auth -->|"sets storage"| node_context
node_context -->|"creates provider"| node_storage
node_storage -->|"reads and writes"| node_google
node_storage -->|"refreshes token"| node_session
node_app -->|"routes login"| node_auth
node_app -->|"routes unlock"| node_vaultwall
node_vaultwall -->|"sets vault"| node_context
node_context -->|"creates engine"| node_sync
node_context -->|"holds manager"| node_vault
node_app -->|"guards pages"| node_protected
node_protected -->|"routes editor"| node_editor
node_protected -->|"routes entries"| node_entries
node_protected -->|"routes viewer"| node_viewer
node_protected -->|"routes settings"| node_settings
node_protected -->|"routes emotion book"| node_emotion
node_editor -->|"uses editor"| node_editorui
node_editor -->|"syncs entries"| node_sync
node_entries -->|"browses entries"| node_sync
node_viewer -->|"loads entry"| node_sync
node_past -->|"loads history"| node_sync
node_emotion -->|"uses records"| node_emotionhook
node_emotionhook -->|"reads app state"| node_context
node_emotionhook -->|"persists records"| node_storage
node_exportworker -->|"downloads files"| node_google
node_exportworker -->|"renders PDF"| node_renderer
node_exportworker -->|"extracts media"| node_media
node_exportworker -->|"reads pending media"| node_staged
node_exportworker -->|"decrypts content"| node_crypto

click node_app "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/App.tsx"
click node_auth "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/components/AuthWall.tsx"
click node_session "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/components/SessionManager.tsx"
click node_vaultwall "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/components/VaultSetupWall.tsx"
click node_protected "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/components/ProtectedLayout.tsx"
click node_context "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/contexts/AppContext.tsx"
click node_vault "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/vault.ts"
click node_storage "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/storage.ts"
click node_sync "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/sync.ts"
click node_editor "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/editor/index.tsx"
click node_editorui "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/components/Editor.tsx"
click node_entries "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/entries/index.tsx"
click node_viewer "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/viewer/index.tsx"
click node_past "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/editor/useLastEntry.ts"
click node_emotion "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/emotionbook/index.tsx"
click node_emotionhook "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/emotionbook/useEmotionBook.ts"
click node_settings "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/settings/index.tsx"
click node_exportworker "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/workers/exportPdf.worker.ts"
click node_renderer "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/export/pdfRenderer.ts"
click node_media "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/media.ts"
click node_staged "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/stagedMedia.ts"
click node_crypto "https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/crypto.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_auth,node_session,node_vaultwall,node_protected,node_user toneBlue
class node_editor,node_editorui,node_entries,node_viewer,node_past,node_google toneAmber
class node_emotion,node_emotionhook,node_settings,node_exportworker,node_renderer toneMint
class node_context,node_vault,node_storage,node_sync,node_media,node_staged,node_crypto toneRose
```

## Components

### Access and vault

- [App routes](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/App.tsx): `app/src/App.tsx`
- [Google login](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/components/AuthWall.tsx): `app/src/components/AuthWall.tsx`
- [Session refresh](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/components/SessionManager.tsx): `app/src/components/SessionManager.tsx`
- [Vault setup](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/components/VaultSetupWall.tsx): `app/src/components/VaultSetupWall.tsx`
- [Protected layout](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/components/ProtectedLayout.tsx): `app/src/components/ProtectedLayout.tsx`

### Journal workflow

- [Entry editor](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/editor/index.tsx): `app/src/modules/editor/index.tsx`
- [Editor UI](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/components/Editor.tsx): `app/src/components/Editor.tsx`
- [Entry browser](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/entries/index.tsx): `app/src/modules/entries/index.tsx`
- [Entry viewer](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/viewer/index.tsx): `app/src/modules/viewer/index.tsx`
- [Past entries](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/editor/useLastEntry.ts): `app/src/modules/editor/useLastEntry.ts`

### Journal features

- [Emotion book](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/emotionbook/index.tsx): `app/src/modules/emotionbook/index.tsx`
- [Emotion records](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/emotionbook/useEmotionBook.ts): `app/src/modules/emotionbook/useEmotionBook.ts`
- [Settings](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/modules/settings/index.tsx): `app/src/modules/settings/index.tsx`
- [PDF export worker](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/workers/exportPdf.worker.ts): `app/src/workers/exportPdf.worker.ts`
- [PDF renderer](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/export/pdfRenderer.ts): `app/src/lib/export/pdfRenderer.ts`

### Sync and export

- [App state](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/contexts/AppContext.tsx): `app/src/contexts/AppContext.tsx`
- [Vault manager](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/vault.ts): `app/src/lib/vault.ts`
- [Drive storage](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/storage.ts): `app/src/lib/storage.ts`
- [Journal sync](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/sync.ts): `app/src/lib/sync.ts`
- [Media helpers](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/media.ts): `app/src/lib/media.ts`
- [Staged media](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/stagedMedia.ts): `app/src/lib/stagedMedia.ts`
- [Encryption](https://github.com/amittras-pal/silent-memoirs/blob/main/app/src/lib/crypto.ts): `app/src/lib/crypto.ts`

### Other components

- **User**
- **Google Drive**

## Connections

- User → Google login: connects account
- Google login → Google Drive: OAuth token
- Google login → App state: sets storage
- App state → Drive storage: creates provider
- Drive storage → Google Drive: reads and writes
- Drive storage → Session refresh: refreshes token
- App routes → Google login: routes login
- App routes → Vault setup: routes unlock
- Vault setup → App state: sets vault
- App state → Journal sync: creates engine
- App state → Vault manager: holds manager
- App routes → Protected layout: guards pages
- Protected layout → Entry editor: routes editor
- Protected layout → Entry browser: routes entries
- Protected layout → Entry viewer: routes viewer
- Protected layout → Settings: routes settings
- Protected layout → Emotion book: routes emotion book
- Entry editor → Editor UI: uses editor
- Entry editor → Journal sync: syncs entries
- Entry browser → Journal sync: browses entries
- Entry viewer → Journal sync: loads entry
- Past entries → Journal sync: loads history
- Emotion book → Emotion records: uses records
- Emotion records → App state: reads app state
- Emotion records → Drive storage: persists records
- PDF export worker → Google Drive: downloads files
- PDF export worker → PDF renderer: renders PDF
- PDF export worker → Media helpers: extracts media
- PDF export worker → Staged media: reads pending media
- PDF export worker → Encryption: decrypts content
