# kirmisaki/framefilm architecture

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

## Overview

FrameFilm combines ESP32 display firmware, companion photo-transfer tools, and Film-hub cloud management. The main device workflow is converting an image to Film, sending it over BLE or WiFi, storing and displaying it on the frame; Film-hub adds device registration, albums, templates, scheduled streams, and AI-assisted content. Firmware internals are sampled unevenly, so links from BLE command handling to file/OTA services are shown where calls are visible; other documented but unsampled capabilities are represented without speculative implementation links.

Main entry points: [`server/backend/app/main.py`](https://github.com/kirmisaki/framefilm/blob/main/server/backend/app/main.py) (Film-hub API), [`firmware/frame_film/components/film_service/src/service_ble.c`](https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_ble.c) (BLE service), [`tools/wechart/miniprogram/app.js`](https://github.com/kirmisaki/framefilm/blob/main/tools/wechart/miniprogram/app.js) (WeChat mini-program), [`tools/ForFilm/js/main.js`](https://github.com/kirmisaki/framefilm/blob/main/tools/ForFilm/js/main.js) (ForFilm interface)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_device["Device firmware"]
  node_firmware_entry["Firmware startup<br/>[main.c]"]
  node_sys["System services<br/>[sys_init.c]"]
  node_ble["BLE service<br/>[service_ble.c]"]
  node_gatts["GATT transport"]
  node_files["Film file service<br/>[service_file.c]"]
  node_film["Film playback<br/>[service_film.c]"]
  node_ota["Firmware updates<br/>[service_ota.c]"]
  node_wifi["WiFi delivery<br/>[service_wifi.c]"]
  node_params["Device settings<br/>[service_param.c]"]
  node_hal["Hardware abstraction"]
  node_epaper["E-paper display<br/>[hal_epd_368.c]"]
  node_sd["SD storage<br/>[hal_sd.c]"]
end

subgraph group_hub["Film-hub backend"]
  node_backend["Film-hub API<br/>[main.py]"]
  node_auth["Authentication<br/>[auth.py]"]
  node_api_routes["Hub API domains"]
  node_database[("Hub database<br/>[db.py]")]
  node_models["Domain records"]
  node_templates["Built-in templates"]
  node_ai["AI integration<br/>[ai_client.py]"]
end

subgraph group_webtools["Web companion"]
  node_forfilm["ForFilm interface<br/>[main.js]"]
  node_convert["Film conversion<br/>[convert.js]"]
end

subgraph group_miniprogram["WeChat companion"]
  node_miniapp["WeChat mini-program<br/>[app.js]"]
  node_ble_utils["Phone BLE utilities<br/>[ble-utils.js]"]
  node_film_utils["Film utilities<br/>[film-utils.js]"]
end

node_owner(("FrameFilm owner"))
node_cloud_user(("Hub administrator"))
node_browser_user(("Browser user"))
node_phone_user(("Phone user"))
node_frame["FrameFilm device"]
node_hub_service["Film-hub service"]

node_owner -->|"converts photos"| node_forfilm
node_forfilm -.->|"uses conversion"| node_convert
node_forfilm -->|"transfers by BLE"| node_frame
node_owner -->|"creates and sends"| node_miniapp
node_miniapp -->|"imports"| node_ble_utils
node_miniapp -->|"uses Film helpers"| node_film_utils
node_miniapp -->|"transfers by BLE"| node_frame
node_frame -->|"runs firmware"| node_firmware_entry
node_firmware_entry -->|"initializes"| node_sys
node_sys -.->|"starts services"| node_ble
node_ble -->|"initializes transport"| node_gatts
node_ble -->|"saves transfers"| node_files
node_ble -->|"starts updates"| node_ota
node_wifi -->|"downloads Film"| node_files
node_files -.->|"uses storage"| node_sd
node_film -.->|"renders on"| node_epaper
node_hal -->|"provides display"| node_epaper
node_hal -->|"provides storage"| node_sd
node_cloud_user -->|"manages content"| node_backend
node_backend -->|"mounts routes"| node_auth
node_backend -->|"mounts routes"| node_api_routes
node_auth -->|"gets database session"| node_database
node_database -->|"loads models"| node_models
node_backend -->|"seeds templates"| node_templates
node_api_routes -->|"provides device and content APIs"| node_hub_service
node_hub_service -->|"pushes content by WiFi"| node_wifi
node_backend -->|"supports AI features"| node_ai
node_hub_service -->|"registers and serves device"| node_frame
node_browser_user -->|"administers hub"| node_backend

click node_firmware_entry "https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/main/main.c"
click node_sys "https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_sys/src/sys_init.c"
click node_ble "https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_ble.c"
click node_gatts "https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_ble_gatts.c"
click node_files "https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_file.c"
click node_film "https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_film.c"
click node_ota "https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_ota.c"
click node_wifi "https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_wifi.c"
click node_params "https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_param.c"
click node_hal "https://github.com/kirmisaki/framefilm/tree/main/firmware/frame_film/components/film_hal"
click node_epaper "https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_hal/src/hal_epd_368.c"
click node_sd "https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_hal/src/hal_sd.c"
click node_backend "https://github.com/kirmisaki/framefilm/blob/main/server/backend/app/main.py"
click node_auth "https://github.com/kirmisaki/framefilm/blob/main/server/backend/app/api/auth.py"
click node_api_routes "https://github.com/kirmisaki/framefilm/tree/main/server/backend/app/api"
click node_database "https://github.com/kirmisaki/framefilm/blob/main/server/backend/app/db.py"
click node_models "https://github.com/kirmisaki/framefilm/tree/main/server/backend/app/models"
click node_templates "https://github.com/kirmisaki/framefilm/blob/main/server/backend/app/services/builtin_templates.py"
click node_ai "https://github.com/kirmisaki/framefilm/blob/main/server/backend/app/services/ai_client.py"
click node_forfilm "https://github.com/kirmisaki/framefilm/blob/main/tools/ForFilm/js/main.js"
click node_convert "https://github.com/kirmisaki/framefilm/blob/main/tools/ForFilm/js/convert.js"
click node_miniapp "https://github.com/kirmisaki/framefilm/blob/main/tools/wechart/miniprogram/app.js"
click node_ble_utils "https://github.com/kirmisaki/framefilm/blob/main/tools/wechart/miniprogram/utils/ble-utils.js"
click node_film_utils "https://github.com/kirmisaki/framefilm/blob/main/tools/wechart/miniprogram/utils/film-utils.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_firmware_entry,node_sys,node_ble,node_gatts,node_files,node_film,node_ota,node_wifi,node_params,node_hal,node_epaper,node_sd,node_browser_user,node_phone_user toneBlue
class node_backend,node_auth,node_api_routes,node_database,node_models,node_templates,node_ai toneAmber
class node_forfilm,node_convert toneMint
class node_miniapp,node_ble_utils,node_film_utils toneRose
class node_owner,node_cloud_user,node_frame,node_hub_service toneIndigo
```

## Components

### Device firmware

- [Firmware startup](https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/main/main.c): `firmware/frame_film/main/main.c`
- [System services](https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_sys/src/sys_init.c): `firmware/frame_film/components/film_sys/src/sys_init.c`
- [BLE service](https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_ble.c): `firmware/frame_film/components/film_service/src/service_ble.c`
- [GATT transport](https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_ble_gatts.c): `firmware/frame_film/components/film_service/src/service_ble_gatts.c`
- [Film file service](https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_file.c): `firmware/frame_film/components/film_service/src/service_file.c`
- [Film playback](https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_film.c): `firmware/frame_film/components/film_service/src/service_film.c`
- [Firmware updates](https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_ota.c): `firmware/frame_film/components/film_service/src/service_ota.c`
- [WiFi delivery](https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_wifi.c): `firmware/frame_film/components/film_service/src/service_wifi.c`
- [Device settings](https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_service/src/service_param.c): `firmware/frame_film/components/film_service/src/service_param.c`
- [Hardware abstraction](https://github.com/kirmisaki/framefilm/tree/main/firmware/frame_film/components/film_hal): `firmware/frame_film/components/film_hal`
- [E-paper display](https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_hal/src/hal_epd_368.c): `firmware/frame_film/components/film_hal/src/hal_epd_368.c`
- [SD storage](https://github.com/kirmisaki/framefilm/blob/main/firmware/frame_film/components/film_hal/src/hal_sd.c): `firmware/frame_film/components/film_hal/src/hal_sd.c`

### Film-hub backend

- [Film-hub API](https://github.com/kirmisaki/framefilm/blob/main/server/backend/app/main.py): `server/backend/app/main.py`
- [Authentication](https://github.com/kirmisaki/framefilm/blob/main/server/backend/app/api/auth.py): `server/backend/app/api/auth.py`
- [Hub API domains](https://github.com/kirmisaki/framefilm/tree/main/server/backend/app/api): `server/backend/app/api`
- [Hub database](https://github.com/kirmisaki/framefilm/blob/main/server/backend/app/db.py): `server/backend/app/db.py`
- [Domain records](https://github.com/kirmisaki/framefilm/tree/main/server/backend/app/models): `server/backend/app/models`
- [Built-in templates](https://github.com/kirmisaki/framefilm/blob/main/server/backend/app/services/builtin_templates.py): `server/backend/app/services/builtin_templates.py`
- [AI integration](https://github.com/kirmisaki/framefilm/blob/main/server/backend/app/services/ai_client.py): `server/backend/app/services/ai_client.py`

### Web companion

- [ForFilm interface](https://github.com/kirmisaki/framefilm/blob/main/tools/ForFilm/js/main.js): `tools/ForFilm/js/main.js`
- [Film conversion](https://github.com/kirmisaki/framefilm/blob/main/tools/ForFilm/js/convert.js): `tools/ForFilm/js/convert.js`

### WeChat companion

- [WeChat mini-program](https://github.com/kirmisaki/framefilm/blob/main/tools/wechart/miniprogram/app.js): `tools/wechart/miniprogram/app.js`
- [Phone BLE utilities](https://github.com/kirmisaki/framefilm/blob/main/tools/wechart/miniprogram/utils/ble-utils.js): `tools/wechart/miniprogram/utils/ble-utils.js`
- [Film utilities](https://github.com/kirmisaki/framefilm/blob/main/tools/wechart/miniprogram/utils/film-utils.js): `tools/wechart/miniprogram/utils/film-utils.js`

### Other components

- **FrameFilm owner**
- **Hub administrator**
- **Browser user**
- **Phone user**
- **FrameFilm device**
- **Film-hub service**

## Connections

- FrameFilm owner → ForFilm interface: converts photos (evidence: `README.md`)
- ForFilm interface → Film conversion: uses conversion
- ForFilm interface → FrameFilm device: transfers by BLE (evidence: `README.md`)
- FrameFilm owner → WeChat mini-program: creates and sends (evidence: `README.md`)
- WeChat mini-program → Phone BLE utilities: imports (evidence: `tools/wechart/miniprogram/app.js`)
- WeChat mini-program → Film utilities: uses Film helpers
- WeChat mini-program → FrameFilm device: transfers by BLE (evidence: `README.md`)
- FrameFilm device → Firmware startup: runs firmware (evidence: `README.md`)
- Firmware startup → System services: initializes (evidence: `firmware/frame_film/main/main.c`)
- System services → BLE service: starts services
- BLE service → GATT transport: initializes transport (evidence: `firmware/frame_film/components/film_service/src/service_ble.c`)
- BLE service → Film file service: saves transfers (evidence: `firmware/frame_film/components/film_service/src/service_ble.c`)
- BLE service → Firmware updates: starts updates (evidence: `firmware/frame_film/components/film_service/src/service_ble.c`)
- WiFi delivery → Film file service: downloads Film (evidence: `firmware/frame_film/components/film_service/src/service_wifi.c`)
- Film file service → SD storage: uses storage
- Film playback → E-paper display: renders on
- Hardware abstraction → E-paper display: provides display (evidence: `README.md`)
- Hardware abstraction → SD storage: provides storage (evidence: `README.md`)
- Hub administrator → Film-hub API: manages content (evidence: `README.md`)
- Film-hub API → Authentication: mounts routes (evidence: `server/backend/app/main.py`)
- Film-hub API → Hub API domains: mounts routes (evidence: `server/backend/app/main.py`)
- Authentication → Hub database: gets database session (evidence: `server/backend/app/api/auth.py`)
- Hub database → Domain records: loads models (evidence: `server/backend/app/db.py`)
- Film-hub API → Built-in templates: seeds templates (evidence: `server/backend/app/main.py`)
- Hub API domains → Film-hub service: provides device and content APIs (evidence: `README.md`)
- Film-hub service → WiFi delivery: pushes content by WiFi (evidence: `README.md`)
- Film-hub API → AI integration: supports AI features (evidence: `README.md`)
- Film-hub service → FrameFilm device: registers and serves device (evidence: `README.md`)
- Browser user → Film-hub API: administers hub (evidence: `README.md`)
