# mosalah992/arcaneum architecture

> Architecture diagram of the GitHub repository mosalah992/arcaneum, 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/mosalah992/arcaneum
- Repository: https://github.com/mosalah992/arcaneum

## Overview

The Arcanaeum is a browser-based archive for Skyrim’s books, combining a searchable catalogue with live in-game holdings. Readers enter through the disc-and-passphrase screen, then browse or search the catalogue; the client fetches metadata, full-text matches, call-number lookups, and availability from separate API routes. The API uses D1 for catalogue/search and visit-count data, and Google Sheets for holdings. The README documents the gate middleware and FTS5 search; some route and middleware implementation details were not sampled, so uncertain internal links are omitted.

Main entry points: [`src/lib/api.ts`](https://github.com/mosalah992/arcaneum/blob/main/src/lib/api.ts) (API client), [`functions/api/_middleware.ts`](https://github.com/mosalah992/arcaneum/blob/main/functions/api/_middleware.ts) (Route guard), [`migrations/0001_create_tables.sql`](https://github.com/mosalah992/arcaneum/blob/main/migrations/0001_create_tables.sql) (D1 archive), [`src/screens/insert.ts`](https://github.com/mosalah992/arcaneum/blob/main/src/screens/insert.ts) (Disc entry)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Reader experience"]
  node_entry["Disc entry<br/>[insert.ts]"]
  node_frame["App frame<br/>[main.ts]"]
  node_router["Hash router<br/>[router.ts]"]
  node_catalogue["Catalogue<br/>[catalogue.ts]"]
  node_clientapi["API client<br/>[api.ts]"]
end

subgraph group_api["Archive API"]
  node_gate["Gate route<br/>[gate.ts]"]
  node_middleware["Route guard<br/>[_middleware.ts]"]
  node_tomes["Tome listing<br/>[index.ts]"]
  node_search["Full-text search<br/>[search.ts]"]
  node_resolve["Call lookup<br/>[&#91;callNumber&#93;.ts]"]
  node_availability["Holdings route<br/>[availability.ts]"]
  node_holdings["Holdings logic<br/>[availability.ts]"]
  node_register["Visit register<br/>[index.ts]"]
end

subgraph group_data["Archive data"]
  node_corpus["Book corpus<br/>[AR-I-001.md]"]
  node_d1[("D1 archive")]
end

subgraph group_integrations["External services"]
  node_sheets[("College register")]
  node_google["Google Sheets"]
end

node_reader(("Reader"))

node_reader -->|"starts at"| node_entry
node_entry -->|"checks gate"| node_clientapi
node_entry -->|"navigates"| node_router
node_frame -->|"mounts routes"| node_router
node_frame -->|"counts visits"| node_clientapi
node_router -->|"renders"| node_catalogue
node_catalogue -->|"requests data"| node_clientapi
node_clientapi -->|"checks or opens"| node_gate
node_clientapi -->|"lists tomes"| node_tomes
node_clientapi -->|"searches text"| node_search
node_clientapi -->|"resolves number"| node_resolve
node_clientapi -->|"fetches holdings"| node_availability
node_clientapi -->|"reads count"| node_register
node_middleware -.->|"exempts route"| node_gate
node_middleware -->|"guards routes"| node_tomes
node_middleware -->|"guards routes"| node_search
node_middleware -->|"guards routes"| node_resolve
node_middleware -->|"guards routes"| node_availability
node_tomes -->|"reads metadata"| node_d1
node_search -->|"searches corpus"| node_d1
node_resolve -->|"reads metadata"| node_d1
node_register -->|"reads count"| node_d1
node_availability -->|"loads holdings"| node_holdings
node_holdings -->|"reads register"| node_google
node_google -->|"accesses"| node_sheets
node_corpus -.->|"seeded as tomes"| node_d1

click node_entry "https://github.com/mosalah992/arcaneum/blob/main/src/screens/insert.ts"
click node_frame "https://github.com/mosalah992/arcaneum/blob/main/src/main.ts"
click node_router "https://github.com/mosalah992/arcaneum/blob/main/src/lib/router.ts"
click node_catalogue "https://github.com/mosalah992/arcaneum/blob/main/src/screens/catalogue.ts"
click node_clientapi "https://github.com/mosalah992/arcaneum/blob/main/src/lib/api.ts"
click node_gate "https://github.com/mosalah992/arcaneum/blob/main/functions/api/gate.ts"
click node_middleware "https://github.com/mosalah992/arcaneum/blob/main/functions/api/_middleware.ts"
click node_tomes "https://github.com/mosalah992/arcaneum/blob/main/functions/api/tomes/index.ts"
click node_search "https://github.com/mosalah992/arcaneum/blob/main/functions/api/search.ts"
click node_resolve "https://github.com/mosalah992/arcaneum/blob/main/functions/api/resolve/%5BcallNumber%5D.ts"
click node_availability "https://github.com/mosalah992/arcaneum/blob/main/functions/api/availability.ts"
click node_holdings "https://github.com/mosalah992/arcaneum/blob/main/functions/lib/availability.ts"
click node_register "https://github.com/mosalah992/arcaneum/blob/main/functions/api/register/index.ts"
click node_corpus "https://github.com/mosalah992/arcaneum/blob/main/content/library/AR-I-001.md"
click node_d1 "https://github.com/mosalah992/arcaneum/blob/main/migrations/0001_create_tables.sql"

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_entry,node_frame,node_router,node_catalogue,node_clientapi toneBlue
class node_gate,node_middleware,node_tomes,node_search,node_resolve,node_availability,node_holdings,node_register toneAmber
class node_corpus,node_d1 toneMint
class node_sheets,node_google toneRose
class node_reader toneIndigo
```

## Components

### Reader experience

- [Disc entry](https://github.com/mosalah992/arcaneum/blob/main/src/screens/insert.ts): `src/screens/insert.ts`
- [App frame](https://github.com/mosalah992/arcaneum/blob/main/src/main.ts): `src/main.ts`
- [Hash router](https://github.com/mosalah992/arcaneum/blob/main/src/lib/router.ts): `src/lib/router.ts`
- [Catalogue](https://github.com/mosalah992/arcaneum/blob/main/src/screens/catalogue.ts): `src/screens/catalogue.ts`
- [API client](https://github.com/mosalah992/arcaneum/blob/main/src/lib/api.ts): `src/lib/api.ts`

### Archive API

- [Gate route](https://github.com/mosalah992/arcaneum/blob/main/functions/api/gate.ts): `functions/api/gate.ts`
- [Route guard](https://github.com/mosalah992/arcaneum/blob/main/functions/api/_middleware.ts): `functions/api/_middleware.ts`
- [Tome listing](https://github.com/mosalah992/arcaneum/blob/main/functions/api/tomes/index.ts): `functions/api/tomes/index.ts`
- [Full-text search](https://github.com/mosalah992/arcaneum/blob/main/functions/api/search.ts): `functions/api/search.ts`
- [Call lookup](https://github.com/mosalah992/arcaneum/blob/main/functions/api/resolve/%5BcallNumber%5D.ts): `functions/api/resolve/[callNumber].ts`
- [Holdings route](https://github.com/mosalah992/arcaneum/blob/main/functions/api/availability.ts): `functions/api/availability.ts`
- [Holdings logic](https://github.com/mosalah992/arcaneum/blob/main/functions/lib/availability.ts): `functions/lib/availability.ts`
- [Visit register](https://github.com/mosalah992/arcaneum/blob/main/functions/api/register/index.ts): `functions/api/register/index.ts`

### Archive data

- [Book corpus](https://github.com/mosalah992/arcaneum/blob/main/content/library/AR-I-001.md): `content/library/AR-I-001.md`
- [D1 archive](https://github.com/mosalah992/arcaneum/blob/main/migrations/0001_create_tables.sql): `migrations/0001_create_tables.sql`

### External services

- **College register**
- **Google Sheets**

### Other components

- **Reader**

## Connections

- Reader → Disc entry: starts at
- Disc entry → API client: checks gate
- Disc entry → Hash router: navigates
- App frame → Hash router: mounts routes
- App frame → API client: counts visits
- Hash router → Catalogue: renders
- Catalogue → API client: requests data
- API client → Gate route: checks or opens
- API client → Tome listing: lists tomes
- API client → Full-text search: searches text
- API client → Call lookup: resolves number
- API client → Holdings route: fetches holdings
- API client → Visit register: reads count
- Route guard → Gate route: exempts route
- Route guard → Tome listing: guards routes
- Route guard → Full-text search: guards routes
- Route guard → Call lookup: guards routes
- Route guard → Holdings route: guards routes
- Tome listing → D1 archive: reads metadata
- Full-text search → D1 archive: searches corpus
- Call lookup → D1 archive: reads metadata
- Visit register → D1 archive: reads count
- Holdings route → Holdings logic: loads holdings
- Holdings logic → Google Sheets: reads register
- Google Sheets → College register: accesses
- Book corpus → D1 archive: seeded as tomes
