# sapinsapin/sapinsapin-web architecture

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

- Interactive diagram: https://gitdiagram.com/sapinsapin/sapinsapin-web
- Repository: https://github.com/sapinsapin/sapinsapin-web

## Overview

sapinsapin.ai is a public React landing page for an initiative building Philippine-language AI resources. Visitors explore the project, synced dataset and model figures, map, and speech demo; they can also ask the site-wide Sappy assistant or recover from a mistyped URL. Hub figures are synchronized into source data before deployment, while the speech demo and assistant use runtime services. The README describes the site as static, but the sampled client code and source index also show an assistant Worker integration. Unsampled Worker internals are not expanded here.

Main entry points: [`src/App.jsx`](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/App.jsx) (Homepage), [`src/NotFound.jsx`](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/NotFound.jsx) (404 recovery), [`src/components/SpeechConsole.jsx`](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/components/SpeechConsole.jsx) (Speech console), [`src/components/ChatWidget.jsx`](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/components/ChatWidget.jsx) (Chat widget)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_presentation["Site experience"]
  node_homepage["Homepage<br/>[App.jsx]"]
  node_notfound["404 recovery<br/>[NotFound.jsx]"]
  node_map["Philippines map<br/>[PhilippinesMap.jsx]"]
  node_mapdata["Map geometry"]
  node_theme["Theme state<br/>[theme.js]"]
  node_signal["URL waveform<br/>[SignalTrace.jsx]"]
end

subgraph group_catalog["Project information"]
  node_catalogview["Catalog display<br/>[catalog.js]"]
  node_hubdata["Hub snapshot<br/>[hubSnapshot.js]"]
  node_modelnotes["Model descriptions<br/>[modelNotes.js]"]
end

subgraph group_speech["Speech demo"]
  node_spaceconfig["Demo manifest<br/>[spaceManifest.js]"]
  node_speechconsole["Speech console<br/>[SpeechConsole.jsx]"]
  node_audio["Audio processing<br/>[audio.js]"]
  node_spaceclient["Space client<br/>[spaceClient.js]"]
end

subgraph group_assistant["Sappy assistant"]
  node_chatwidget["Chat widget<br/>[ChatWidget.jsx]"]
  node_sappyclient["Sappy client<br/>[sappyClient.js]"]
  node_worker["Sappy Worker<br/>[index.js]"]
  node_knowledge[("Project knowledge")]
  node_modelservice["Model service"]
end

node_visitor(("Visitor"))
node_gradio["Halohalo Space"]

node_visitor -->|"visits"| node_homepage
node_visitor -->|"opens bad URL"| node_notfound
node_homepage -->|"renders"| node_catalogview
node_homepage -->|"renders"| node_map
node_homepage -->|"renders"| node_speechconsole
node_homepage -->|"renders"| node_chatwidget
node_homepage -->|"uses descriptions"| node_modelnotes
node_homepage -->|"uses theme"| node_theme
node_notfound -->|"renders trace"| node_signal
node_notfound -->|"uses theme"| node_theme
node_notfound -->|"renders"| node_chatwidget
node_map -->|"reads geometry"| node_mapdata
node_map -->|"reads figures"| node_catalogview
node_catalogview -->|"merges snapshot"| node_hubdata
node_speechconsole -->|"loads choices"| node_spaceconfig
node_speechconsole -->|"processes audio"| node_audio
node_speechconsole -->|"requests speech tasks"| node_spaceclient
node_spaceclient -->|"calls Space"| node_gradio
node_chatwidget -->|"sends questions"| node_sappyclient
node_chatwidget -->|"records voice"| node_audio
node_sappyclient -->|"calls assistant"| node_worker
node_sappyclient -->|"uses voice tasks"| node_spaceclient
node_worker -.->|"retrieves project facts"| node_knowledge
node_worker -.->|"generates answers"| node_modelservice

click node_homepage "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/App.jsx"
click node_notfound "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/NotFound.jsx"
click node_map "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/components/PhilippinesMap.jsx"
click node_mapdata "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/data/philippinesMapPaths.js"
click node_theme "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/lib/theme.js"
click node_signal "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/components/SignalTrace.jsx"
click node_catalogview "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/data/catalog.js"
click node_hubdata "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/data/hubSnapshot.js"
click node_modelnotes "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/data/modelNotes.js"
click node_spaceconfig "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/data/spaceManifest.js"
click node_speechconsole "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/components/SpeechConsole.jsx"
click node_audio "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/lib/audio.js"
click node_spaceclient "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/lib/spaceClient.js"
click node_chatwidget "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/components/ChatWidget.jsx"
click node_sappyclient "https://github.com/sapinsapin/sapinsapin-web/blob/main/src/lib/sappyClient.js"
click node_worker "https://github.com/sapinsapin/sapinsapin-web/blob/main/worker/src/index.js"

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_homepage,node_notfound,node_map,node_mapdata,node_theme,node_signal toneBlue
class node_catalogview,node_hubdata,node_modelnotes toneAmber
class node_spaceconfig,node_speechconsole,node_audio,node_spaceclient toneMint
class node_chatwidget,node_sappyclient,node_worker,node_knowledge,node_modelservice toneRose
class node_visitor,node_gradio toneIndigo
```

## Components

### Site experience

- [Homepage](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/App.jsx): `src/App.jsx`
- [404 recovery](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/NotFound.jsx): `src/NotFound.jsx`
- [Philippines map](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/components/PhilippinesMap.jsx): `src/components/PhilippinesMap.jsx`
- [Map geometry](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/data/philippinesMapPaths.js): `src/data/philippinesMapPaths.js`
- [Theme state](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/lib/theme.js): `src/lib/theme.js`
- [URL waveform](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/components/SignalTrace.jsx): `src/components/SignalTrace.jsx`

### Project information

- [Catalog display](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/data/catalog.js): `src/data/catalog.js`
- [Hub snapshot](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/data/hubSnapshot.js): `src/data/hubSnapshot.js`
- [Model descriptions](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/data/modelNotes.js): `src/data/modelNotes.js`

### Speech demo

- [Demo manifest](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/data/spaceManifest.js): `src/data/spaceManifest.js`
- [Speech console](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/components/SpeechConsole.jsx): `src/components/SpeechConsole.jsx`
- [Audio processing](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/lib/audio.js): `src/lib/audio.js`
- [Space client](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/lib/spaceClient.js): `src/lib/spaceClient.js`

### Sappy assistant

- [Chat widget](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/components/ChatWidget.jsx): `src/components/ChatWidget.jsx`
- [Sappy client](https://github.com/sapinsapin/sapinsapin-web/blob/main/src/lib/sappyClient.js): `src/lib/sappyClient.js`
- [Sappy Worker](https://github.com/sapinsapin/sapinsapin-web/blob/main/worker/src/index.js): `worker/src/index.js`
- **Project knowledge**
- **Model service**

### Other components

- **Visitor**
- **Halohalo Space**

## Connections

- Visitor → Homepage: visits (evidence: `README.md`)
- Visitor → 404 recovery: opens bad URL (evidence: `README.md`)
- Homepage → Catalog display: renders (evidence: `src/App.jsx`)
- Homepage → Philippines map: renders (evidence: `src/App.jsx`)
- Homepage → Speech console: renders (evidence: `src/App.jsx`)
- Homepage → Chat widget: renders (evidence: `src/App.jsx`)
- Homepage → Model descriptions: uses descriptions (evidence: `src/App.jsx`)
- Homepage → Theme state: uses theme (evidence: `src/App.jsx`)
- 404 recovery → URL waveform: renders trace (evidence: `src/NotFound.jsx`)
- 404 recovery → Theme state: uses theme (evidence: `src/NotFound.jsx`)
- 404 recovery → Chat widget: renders (evidence: `src/NotFound.jsx`)
- Philippines map → Map geometry: reads geometry (evidence: `src/components/PhilippinesMap.jsx`)
- Philippines map → Catalog display: reads figures (evidence: `src/components/PhilippinesMap.jsx`)
- Catalog display → Hub snapshot: merges snapshot (evidence: `src/data/catalog.js`)
- Speech console → Demo manifest: loads choices (evidence: `src/components/SpeechConsole.jsx`)
- Speech console → Audio processing: processes audio (evidence: `src/components/SpeechConsole.jsx`)
- Speech console → Space client: requests speech tasks (evidence: `src/components/SpeechConsole.jsx`)
- Space client → Halohalo Space: calls Space (evidence: `src/lib/spaceClient.js`)
- Chat widget → Sappy client: sends questions (evidence: `src/components/ChatWidget.jsx`)
- Chat widget → Audio processing: records voice (evidence: `src/components/ChatWidget.jsx`)
- Sappy client → Sappy Worker: calls assistant (evidence: `src/lib/sappyClient.js`)
- Sappy client → Space client: uses voice tasks (evidence: `src/lib/sappyClient.js`)
- Sappy Worker → Project knowledge: retrieves project facts
- Sappy Worker → Model service: generates answers
