Banban Architecture Diagrams

Rendered Mermaid viewer for the architecture docs. Requires internet access for the Mermaid CDN when opened as a local file.

01 System Overview

Public edge, mini-program, backend, database, MQTT, device, and external providers.

Runtime Architecture

flowchart LR
  subgraph WeChat["WeChat Ecosystem"]
    Mini["banban-mini\nTaro WeChat mini-program"]
    WxLogin["WeChat login / phone APIs"]
    WxMP["WeChat Official Account\nnotifications and bind"]
  end

  subgraph Edge["Public Edge"]
    Domain["banban.api.talkingq.com"]
    Nginx["Nginx / TLS"]
  end

  subgraph Backend["talkingq-url FastAPI backend"]
    Main["main.py\nFastAPI app + lifespan"]
    AuthMW["banban auth middleware"]
    BanbanRouter["banban routers\nchildren, devices, binding, chat,\nlocation, alarms, firmware, roles,\nwechat-mp"]
    MqttSvc["TalkingQMQTTService"]
    Scheduler["TaskScheduler\ncleanup and periodic tasks"]
    StaticAssets["/assets static files"]
  end

  subgraph Data["Stateful Services"]
    MySQL["MySQL\nshared banban schema"]
    COS["Tencent COS\nmessage audio files"]
    MQTT["MQTT broker"]
  end

  subgraph DeviceSide["Device Side"]
    Device["TalkingQ device"]
    NFC["NFC card"]
  end

  subgraph External["External Providers"]
    MapSvc["Map / reverse geocoding provider"]
    SMS["SMS provider"]
  end

  Mini -->|HTTPS /banban/*| Domain --> Nginx --> Main
  Main --> AuthMW --> BanbanRouter
  Main --> StaticAssets
  Main --> Scheduler
  Main --> MqttSvc
  BanbanRouter --> MySQL
  MqttSvc --> MQTT
  Device -->|device/{id}/event,response| MQTT
  MQTT -->|subscribed messages| MqttSvc
  MqttSvc --> MySQL
  Device --> NFC
  BanbanRouter --> COS
  MqttSvc --> COS
  BanbanRouter --> WxLogin
  BanbanRouter --> WxMP
  BanbanRouter --> SMS
  MqttSvc --> MapSvc
        
Source: talkingq-url/main.py, banban-mini/src/services/*, database/talkingq_shared_schema.sql

02 Device Bootstrap

How IMEI mappings become active Banban device identities.

Bootstrap Flow

sequenceDiagram
  autonumber
  participant Factory as Factory Excel / import CSV
  participant Mapping as device_imei_mapping
  participant Device as TalkingQ device
  participant MQTT as MQTT broker
  participant Handler as TalkingQMQTTService
  participant Init as device_identity_initializer
  participant Auth as device_auth

  Factory->>Mapping: Insert imei, device_id, serial_number, status=pending
  Device->>MQTT: Publish device/{imei}/event msg_id=012
  MQTT->>Handler: Deliver identity init event
  Handler->>Init: initialize_by_imei(imei)
  Init->>Mapping: SELECT mapping by imei
  alt mapping missing or incomplete
    Init-->>Handler: DeviceIdentityInitializationError
    Handler-->>MQTT: device/{imei}/event_resp status=failed
  else mapping found
    Init->>Auth: SELECT device_auth by device_id
    alt no auth row
      Init->>Auth: INSERT device_id, serial_number, is_active=1
    else auth row exists and serial matches
      Init->>Auth: UPDATE is_active=1
    else serial mismatch
      Init-->>Handler: device_auth serial_number conflict
      Handler-->>MQTT: device/{imei}/event_resp status=failed
    end
    Init->>Mapping: UPDATE status=activated, activated_at=now
    Handler-->>MQTT: device/{imei}/event_resp with device_id and device_sn
    MQTT-->>Device: Receive assigned identity
  end
        

Data Model

erDiagram
  device_imei_mapping {
    int id PK
    varchar imei UK
    varchar device_id UK
    varchar serial_number
    varchar status
    datetime activated_at
    datetime created_at
    datetime updated_at
  }

  device_auth {
    int id PK
    varchar device_id UK
    varchar serial_number
    varchar batch_id
    tinyint is_active
    datetime created_at
    datetime updated_at
  }

  device_imei_mapping ||--o| device_auth : activates
        
Source: talkingq-url/services/device_identity_initializer.py, talkingq-url/handlers/mqtt_handler.py

03 Binding Flow

How a parent binds an authenticated device to a child through NFC confirmation.

Device Binding

sequenceDiagram
  autonumber
  participant Parent as Parent in mini-program
  participant Mini as banban-mini bind page
  participant API as /banban/bind APIs
  participant Binding as BindingService
  participant DAO as BindingDAO
  participant Auth as device_auth
  participant MQTT as TalkingQMQTTService
  participant Device as TalkingQ device
  participant Card as cards
  participant Bindings as device_bindings
  participant History as device_bind_history

  Parent->>Mini: Scan QR or open bind URL
  Mini->>API: start_bind(device_id, serial_number, child_id)
  API->>Binding: start_bind(user_id, device_id, serial_number, child_id)
  Binding->>Auth: get_device_auth(device_id)
  alt device missing, inactive, or serial mismatch
    Binding-->>API: BindingError
    API-->>Mini: 4xx error
  else device is bindable
    Binding->>DAO: ensure no active device binding
    Binding->>DAO: create device_bind_session
    Binding->>MQTT: send_bind_nfc_command(msg_id=006)
    MQTT-->>Device: device/{device_id}/command
    API-->>Mini: bind_token, expires_at
  end

  Device->>MQTT: NFC response / card UUID
  MQTT->>Binding: finalize_nfc_bind(device_id, card_uuid)
  Binding->>DAO: load latest pending bind session
  Binding->>Card: activate_card(card_uuid, device_id)
  Binding->>Bindings: create active binding
  Binding->>History: write bind audit history
  Binding->>DAO: mark session completed
        

Related Tables

erDiagram
  parents ||--o{ children : owns
  parents ||--o{ device_bindings : owns
  children ||--o{ device_bindings : current_child
  device_auth ||--o{ device_bindings : device
  device_auth ||--o{ device_bind_sessions : pending_bind
  device_auth ||--o{ cards : card_owner_device
  device_bindings ||--o{ device_bind_history : audit
        
Source: banban-mini/src/pages/bind/index.tsx, talkingq-url/banban/service/binding.py

04 Voice And IM Flow

Parent voice upload, IM persistence, COS audio, and device delivery.

Parent Voice Message To Device

sequenceDiagram
  autonumber
  participant Parent as Parent
  participant Mini as Chat detail page
  participant API as /banban chat APIs
  participant Audio as Upload / audio handling
  participant COS as Tencent COS
  participant IM as IM service / DAO
  participant DB as im_conversations + im_messages
  participant Pending as device_pending_voice_messages
  participant MQTT as MQTT broker
  participant Device as TalkingQ device

  Parent->>Mini: Long press "press to leave message"
  Mini->>Mini: Taro.getRecorderManager records mp3/aac
  Mini->>API: upload voice file + metadata
  API->>Audio: validate and store audio
  Audio->>COS: upload message audio
  COS-->>Audio: media_file_key / public URL
  API->>IM: create parent voice IM message
  IM->>DB: upsert conversation and insert message
  IM->>Pending: create pending voice delivery row
  API-->>Mini: message item with media URL

  Device->>MQTT: device/{device_id}/event msg_id=005 NFC listen
  MQTT->>API: MQTT handler receives event
  API->>Pending: find pending voice for card/device
  API-->>MQTT: device/{device_id}/event_resp with audio URL(s)
  MQTT-->>Device: Play pending audio
  API->>Pending: mark delivered / increment delivery count
        

Device / Child Voice Into IM

flowchart TD
  Device["Device short press / voice upload\nmsg_id=011 or compatibility path"]
  MQTT["TalkingQMQTTService"]
  Upload["Audio upload / archive service"]
  Resolve["Resolve bound owner and child\nfrom device_bindings"]
  IM["IM service"]
  Tables["im_conversations\nim_messages"]
  Mini["banban-mini chat list/detail"]

  Device --> MQTT --> Upload --> Resolve --> IM --> Tables
  Tables -->|GET chat APIs| Mini
        

Audio Domain

flowchart LR
  Message["im_messages.media_file_key"]
  Presenter["present_message_item / chat service"]
  URL["mediaUrl returned to mini-program"]
  Player["Taro InnerAudioContext"]
  COS["COS downloadFile legal domain"]

  Message --> Presenter --> URL --> Player
  URL --> COS
        
Source: banban-mini/src/pages/chat/detail/index.tsx, talkingq-url/banban/service/im.py

05 Location Flow

Device-sourced current location and trajectory shown in the mini-program.

Device-Sourced Location

sequenceDiagram
  autonumber
  participant Device as TalkingQ device
  participant MQTT as MQTT broker
  participant Handler as TalkingQMQTTService
  participant Location as Location service
  participant Current as child_location_current
  participant History as child_location_history
  participant Mini as banban-mini location page
  participant API as /banban/devices/{device_id}/location

  Device->>MQTT: msg_id=000 with latitude/longitude or GPS response
  MQTT->>Handler: deliver device event/response
  Handler->>Location: report_mqtt_device_location(...)
  Location->>Location: resolve active child binding
  Location->>Current: upsert latest location
  Location->>History: insert location history point
  Handler-->>MQTT: success event_resp

  Mini->>API: GET current location
  API->>Current: read current row for bound child/device
  API-->>Mini: current location, accuracy, battery, address fields

  Mini->>API: GET trajectory
  API->>History: read recent/today points
  API-->>Mini: trajectory points
        

Data Model

erDiagram
  device_auth ||--o{ child_location_current : device
  children ||--o{ child_location_current : child
  device_auth ||--o{ child_location_history : device
  children ||--o{ child_location_history : child
  device_bindings ||--o{ child_location_current : active_binding_source
        
Source: banban-mini/src/pages/location/index.tsx, talkingq-url/banban/service/location.py

06 Alarm And Notification Flow

Device alarm persistence and user-visible notifications.

Device Alarm To User Notification

sequenceDiagram
  autonumber
  participant Device as TalkingQ device
  participant MQTT as MQTT broker
  participant Handler as TalkingQMQTTService
  participant Alarm as Alarm service
  participant Location as Location snapshot
  participant DB as device_alarm_events
  participant Banner as system banner polling
  participant Mini as banban-mini
  participant WxMP as WeChat Official Account
  participant SMS as SMS provider

  Device->>MQTT: alarm event msg_id=010
  MQTT->>Handler: deliver alarm payload
  Handler->>Alarm: create alarm event
  Alarm->>Location: attach current location snapshot if available
  Alarm->>DB: insert device_alarm_events
  Alarm->>WxMP: schedule/send template notification if bound
  Alarm->>SMS: send SMS if phone notification is enabled
  Banner->>DB: poll latest/new alarm
  Mini->>Banner: show banner / alarm history on device home
  Handler-->>MQTT: alarm event_resp
        

Supporting Notification Bind

flowchart TD
  Mini["banban-mini management page"]
  Phone["WeChat phone authorization"]
  WxBind["WeChat MP bind start/status"]
  Backend["talkingq-url wechat-mp routers/services"]
  Parent["parents / parent_wechat_* tables"]
  Notify["wechat_mp_notification_service"]

  Mini --> Phone --> Backend --> Parent
  Mini --> WxBind --> Backend --> Parent
  Parent --> Notify
        

Key Tables

erDiagram
  device_auth ||--o{ device_alarm_events : reports
  children ||--o{ device_alarm_events : alarm_owner
  parents ||--o{ parent_wechat_accounts : mp_account
  parents ||--o{ parent_wechat_identities : wx_identity
  parents ||--o{ wechat_mp_bind_states : bind_state
        
Source: banban-mini/src/services/system-banner.ts, talkingq-url/banban/service/wechat_mp_notification.py

07 Deployment

Public API host, reverse proxy, backend process, database, MQTT, COS, and certificate renewal.

Public Deployment Shape

flowchart TD
  User["WeChat mini-program user"]
  Domain["banban.api.talkingq.com"]
  Nginx["Nginx container\nTLS + reverse proxy + static verify files"]
  FastAPI["talkingq-url FastAPI process\n/home/ubuntu/banban-backend"]
  MySQL["1Panel MySQL container\nMySQL 8.x"]
  MQTT["Configured MQTT broker"]
  COS["Tencent COS"]
  Certbot["certbot container\nLet's Encrypt renewals"]

  User -->|HTTPS| Domain --> Nginx --> FastAPI
  FastAPI --> MySQL
  FastAPI --> MQTT
  FastAPI --> COS
  Certbot --> Nginx
        

Startup Responsibilities

sequenceDiagram
  autonumber
  participant Proc as FastAPI process
  participant Init as init_db
  participant Scheduler as TaskScheduler
  participant MQTT as TalkingQMQTTService
  participant Roles as role_manager
  participant Firmware as firmware_scanner

  Proc->>Init: initialize and migrate database tables
  Proc->>Scheduler: start periodic tasks
  Proc->>MQTT: connect to configured broker
  Proc->>Roles: initialize role definitions
  Proc->>Firmware: scan firmware files
  Proc-->>Proc: serve API routes and assets
        
Source: talkingq-url/docker-compose.yml, talkingq-url/nginx.conf, talkingq-url/main.py

If diagrams do not render, open this file with network access enabled or render the Markdown files in a Mermaid-capable viewer such as GitHub, GitLab, VS Code with Mermaid support, or Mermaid Live Editor.