Skip to main content

Multi-Frontend Architecture

Channel Abstraction

The MessageChannel abstraction in src/channels.py provides a unified interface for sending messages regardless of which frontend a participant is using.

Implementations

  • TelegramChannel -- wraps python-telegram-bot's messaging API
  • WebSocketChannel -- sends JSON messages over WebSocket connections

Abstract Types

TypeDescription
ButtonRepresents a button with label, callback_data, url, and web_app_url fields
KeyboardContains rows of Button objects for inline keyboard layouts
SentMessageWraps channel-specific message IDs as a string for uniform handling

Shared Survey Logic

Pure survey logic lives in src/survey_logic.py with no Telegram dependency. This module is shared by both frontends:

  • src/handlers/survey.py -- Telegram survey handler
  • src/api_webapp.py -- WebSocket survey handler

Both call the same functions for question rendering, response validation, session progression, and branching logic.

PWA Frontend

The PWA lives in the pwa/ directory and is built with:

  • React + TypeScript for the UI
  • Tailwind CSS 4 for styling
  • Vite as the build tool

It connects to the backend via WebSocket through src/api_webapp.py. The production build output (pwa/dist/) is served as static files by the FastAPI server.

Adding a New Frontend

To add a new frontend (e.g., a native mobile app, a different messaging platform):

  1. Implement the MessageChannel interface in src/channels.py
  2. Wire up message handling for your transport (HTTP, WebSocket, SDK, etc.)
  3. Reuse the functions in src/survey_logic.py for survey delivery and response handling

No changes to the core survey engine or database layer should be necessary.