# faysal1000/fake-news-annotation-tool architecture

> Architecture diagram of the GitHub repository faysal1000/fake-news-annotation-tool, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/faysal1000/fake-news-annotation-tool
- Repository: https://github.com/faysal1000/fake-news-annotation-tool

## Overview

1. **Repository split**
   - The repo contains two deployable systems: the main **desktop annotator** in `annotator/` and a separate **Telegram bot service** in `bot-server/`.
   - The desktop app is the primary product; the bot is an auxiliary distribution/input pipeline for routing news items to annotators.

2. **Desktop app boundary**
   - `annotator/main.py` is the launch entry point; it adds `src/` to the path and starts the GUI.
   - `annotator/build.py` packages the app into standalone binaries with PyInstaller for Windows, macOS, and Linux.
   - This makes the desktop client self-contained and usable without Python knowledge.

3. **Core runtime architecture**
   - The app is organized as a local, stateful GUI application with a **UI layer**, **mode layer**, **data layer**, **media layer**, and **analysis utilities**.
   - `ui/main_window.py` acts as the orchestrator and wires the other modules together.
   - `bootstrap.py`, `app_paths.py`, and `constants.py` provide startup checks, filesystem resolution, and shared configuration.

4. **Primary user workflows**
   - The app centers on three modes: **Annotate**, **Review**, and **Re-label**.
   - `modes/mode_controller.py` switches between these views.
   - `annotate_mode.py` handles record creation and validation, `review_mode.py` handles browsing/edit/delete of saved records, and `relabel_mode.py` supports blind relabeling for agreement testing.

5. **Local data persistence**
   - All annotation data is stored locally, not in a central database.
   - `data/csv_manager.py` manages the dataset CSV schema, reads/writes records, and handles migrations.
   - `data/config_manager.py` stores per-user local settings.
   - `data/stats_engine.py` computes local counts and summary metrics used by the UI and dashboard.

6. **Media handling**
   - Media is stored alongside the dataset, typically in local `images/` and `videos/` folders next to the executable.
   - `media/media_manager.py` is responsible for attaching, previewing, saving, and scaling media assets.
   - Dataset rows keep relative media paths so the CSV remains portable when folders are moved together.

7. **Duplicate detection and auditing**
   - Duplicate checking is a distinct subsystem under `duplicates/duplicate_engine.py`.
   - It appears to run background auditing and supports an inline duplicate badge plus a dedicated comparison popup in `ui/duplicate_popup.py`.
   - The app also maintains a persistent `non_duplicates.json` list so manually reviewed pairs are not repeatedly flagged.

8. **Analysis and dataset operations**
   - `analysis/aggregator.py` combines datasets from multiple annotators and generates derived samples, especially for inter-rater reliability workflows.
   - `analysis/kappa.py` implements Cohen/Fleiss Kappa calculations for agreement testing.
   - `analysis/text_similarity.py` provides text normalization and similarity checks used by duplicate or overlap analysis.
   - These utilities are surfaced through the UI’s scripts and stats dialogs rather than through a separate backend.

9. **Statistics and dashboards**
   - `ui/stats_popup.py` provides an interactive statistics dashboard driven by the data layer.
   - The dashboard is not just read-only reporting; it can dynamically recompute category distributions and multi-modal counts from the local dataset.
   - This creates a tight flow from CSV data → stats engine → interactive modal.

10. **Cross-cutting UI support**
   - `ui/build_ui.py`, `ui/dialogs.py`, `ui/widgets.py`, `ui/filter_panel.py`, and `ui/scripts_popup.py` provide layout, reusable controls, confirmation dialogs, filtering, and action launchers.
   - `shortcuts/keyboard.py` binds hotkeys for fast annotation work.
   - These modules support the main mode screens rather than acting as standalone features.

11. **Sync and update boundaries**
   - `sync/global_sync.py` uploads lightweight team metrics to a GitHub Gist for shared progress visibility.
   - `updater/update_manager.py` checks for releases and can trigger updates asynchronously.
   - Both are optional cloud-facing concerns layered on top of an otherwise offline-first desktop app.

12. **Telegram bot service**
   - `bot-server/telegram_bot.py` is a separate runtime for receiving or polling Telegram messages and routing news links to annotators.
   - `bot-server/api/index.py` and `vercel.json` indicate a serverless webhook deployment option on Vercel, while `setup_webhook.py` configures Telegram webhook registration.
   - This service feeds assignment/input into the annotation workflow but does not share the desktop app’s local storage directly.

13. **Build and release pipeline**
   - `.github/workflows/build.yml` automates multi-platform builds and release creation from version tags.
   - The repo also uses a pre-push git hook to prevent mismatched version tags.
   - The overall delivery model is: source repo → CI build → standalone desktop release binaries + optional bot deployment.

Main entry points: [`annotator/src/ui/main_window.py`](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/ui/main_window.py) (Main window), [`annotator/src/modes/mode_controller.py`](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/modes/mode_controller.py) (Mode switch), [`annotator/src/duplicates/duplicate_engine.py`](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/duplicates/duplicate_engine.py) (Duplicate engine), [`annotator/src/ui/scripts_popup.py`](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/ui/scripts_popup.py) (Scripts panel)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_desktop["Desktop annotator"]
  node_main_launcher["Launcher<br/>desktop entrypoint<br/>[main.py]"]
  node_core_bootstrap["Bootstrap<br/>startup config<br/>[bootstrap.py]"]
  node_main_window["Main window<br/>ui orchestrator<br/>[main_window.py]"]
  node_mode_controller["Mode switch<br/>workflow router<br/>[mode_controller.py]"]
  node_annotate_mode["Annotate<br/>mode<br/>[annotate_mode.py]"]
  node_review_mode["Review<br/>mode<br/>[review_mode.py]"]
  node_relabel_mode["Re-label<br/>mode<br/>[relabel_mode.py]"]
  node_csv_manager[("CSV store<br/>local data<br/>[csv_manager.py]")]
  node_config_manager[("Config store<br/>local settings<br/>[config_manager.py]")]
  node_stats_engine["Stats engine<br/>metrics<br/>[stats_engine.py]"]
  node_media_manager["Media manager<br/>asset handling<br/>[media_manager.py]"]
  node_duplicate_engine["Duplicate engine<br/>audit logic"]
  node_text_similarity["Similarity<br/>analysis helper<br/>[text_similarity.py]"]
  node_aggregator["Aggregator<br/>dataset ops<br/>[aggregator.py]"]
  node_kappa["Kappa<br/>agreement metrics<br/>[kappa.py]"]
  node_stats_popup["Stats dashboard<br/>ui modal<br/>[stats_popup.py]"]
  node_scripts_popup["Scripts panel<br/>ui modal<br/>[scripts_popup.py]"]
  node_keyboard["Hotkeys<br/>shortcuts<br/>[keyboard.py]"]
  node_global_sync["Global sync<br/>cloud metrics<br/>[global_sync.py]"]
  node_update_manager["Updater<br/>release check<br/>[update_manager.py]"]
end

subgraph group_bot["Telegram bot"]
  node_telegram_bot["Telegram bot<br/>service runtime<br/>[telegram_bot.py]"]
  node_api_index["Webhook API<br/>serverless api<br/>[index.py]"]
  node_setup_webhook["Webhook setup<br/>deployment helper<br/>[setup_webhook.py]"]
end

subgraph group_delivery["Build and release"]
  node_build_packager["Packager<br/>desktop build<br/>[build.py]"]
  node_ci_build["CI build<br/>github workflow<br/>[build.yml]"]
end

node_main_launcher -->|"initializes"| node_core_bootstrap
node_main_launcher -->|"starts"| node_main_window
node_build_packager -->|"packages"| node_main_launcher
node_main_window -->|"routes"| node_mode_controller
node_mode_controller -->|"opens"| node_annotate_mode
node_mode_controller -->|"opens"| node_review_mode
node_mode_controller -->|"opens"| node_relabel_mode
node_annotate_mode -->|"writes"| node_csv_manager
node_review_mode -->|"reads/writes"| node_csv_manager
node_relabel_mode -->|"reads"| node_csv_manager
node_main_window -->|"uses"| node_media_manager
node_main_window -->|"queries"| node_stats_engine
node_stats_engine -->|"feeds"| node_stats_popup
node_main_window -->|"checks"| node_duplicate_engine
node_duplicate_engine -->|"uses"| node_text_similarity
node_duplicate_engine -->|"flags"| node_main_window
node_main_window -->|"launches"| node_scripts_popup
node_scripts_popup -->|"runs"| node_aggregator
node_scripts_popup -->|"runs"| node_kappa
node_main_window -->|"binds"| node_keyboard
node_main_window -->|"reports"| node_global_sync
node_main_window -->|"checks"| node_update_manager
node_telegram_bot -->|"deploys"| node_api_index
node_setup_webhook -->|"configures"| node_telegram_bot
node_ci_build -->|"builds"| node_build_packager
node_ci_build -->|"deploys"| node_telegram_bot

click node_main_launcher "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/main.py"
click node_build_packager "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/build.py"
click node_core_bootstrap "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/bootstrap.py"
click node_main_window "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/ui/main_window.py"
click node_mode_controller "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/modes/mode_controller.py"
click node_annotate_mode "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/modes/annotate_mode.py"
click node_review_mode "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/modes/review_mode.py"
click node_relabel_mode "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/modes/relabel_mode.py"
click node_csv_manager "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/data/csv_manager.py"
click node_config_manager "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/data/config_manager.py"
click node_stats_engine "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/data/stats_engine.py"
click node_media_manager "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/media/media_manager.py"
click node_duplicate_engine "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/duplicates/duplicate_engine.py"
click node_text_similarity "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/analysis/text_similarity.py"
click node_aggregator "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/analysis/aggregator.py"
click node_kappa "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/analysis/kappa.py"
click node_stats_popup "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/ui/stats_popup.py"
click node_scripts_popup "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/ui/scripts_popup.py"
click node_keyboard "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/shortcuts/keyboard.py"
click node_global_sync "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/sync/global_sync.py"
click node_update_manager "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/updater/update_manager.py"
click node_telegram_bot "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/bot-server/telegram_bot.py"
click node_api_index "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/bot-server/api/index.py"
click node_setup_webhook "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/bot-server/setup_webhook.py"
click node_ci_build "https://github.com/faysal1000/fake-news-annotation-tool/blob/main/.github/workflows/build.yml"

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_main_launcher,node_core_bootstrap,node_main_window,node_mode_controller,node_annotate_mode,node_review_mode,node_relabel_mode,node_csv_manager,node_config_manager,node_stats_engine,node_media_manager,node_duplicate_engine,node_text_similarity,node_aggregator,node_kappa,node_stats_popup,node_scripts_popup,node_keyboard,node_global_sync,node_update_manager toneBlue
class node_telegram_bot,node_api_index,node_setup_webhook toneAmber
class node_build_packager,node_ci_build toneMint
```

## Components

### Desktop annotator

Local GUI application and its supporting subsystems.

- [Launcher](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/main.py): desktop entrypoint · Starts the desktop app and adds the source tree to the path. · `annotator/main.py`
- [Bootstrap](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/bootstrap.py): startup config · Performs startup checks and runtime initialization for the app. · `annotator/src/bootstrap.py`
- [Main window](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/ui/main_window.py): ui orchestrator · Coordinates the GUI and wires the major modules together. · `annotator/src/ui/main_window.py`
- [Mode switch](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/modes/mode_controller.py): workflow router · Switches between annotate, review, and relabel views. · `annotator/src/modes/mode_controller.py`
- [Annotate](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/modes/annotate_mode.py): mode · Creates and validates new annotation records. · `annotator/src/modes/annotate_mode.py`
- [Review](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/modes/review_mode.py): mode · Browses, edits, and deletes saved records. · `annotator/src/modes/review_mode.py`
- [Re-label](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/modes/relabel_mode.py): mode · Performs blind relabeling for agreement testing. · `annotator/src/modes/relabel_mode.py`
- [CSV store](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/data/csv_manager.py): local data · Reads, writes, and migrates the annotation dataset schema. · `annotator/src/data/csv_manager.py`
- [Config store](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/data/config_manager.py): local settings · Persists per-user application settings locally. · `annotator/src/data/config_manager.py`
- [Stats engine](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/data/stats_engine.py): metrics · Computes local counts and summary metrics for the UI. · `annotator/src/data/stats_engine.py`
- [Media manager](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/media/media_manager.py): asset handling · Attaches, previews, saves, and scales local media assets. · `annotator/src/media/media_manager.py`
- [Duplicate engine](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/duplicates/duplicate_engine.py): audit logic · Detects potential duplicates and supports manual review flows. · `annotator/src/duplicates/duplicate_engine.py`
- [Similarity](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/analysis/text_similarity.py): analysis helper · Normalizes text and computes similarity signals for overlap checks. · `annotator/src/analysis/text_similarity.py`
- [Aggregator](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/analysis/aggregator.py): dataset ops · Combines datasets and derives samples for reliability workflows. · `annotator/src/analysis/aggregator.py`
- [Kappa](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/analysis/kappa.py): agreement metrics · Implements Cohen and Fleiss kappa calculations. · `annotator/src/analysis/kappa.py`
- [Stats dashboard](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/ui/stats_popup.py): ui modal · Interactive statistics dashboard driven by local dataset metrics. · `annotator/src/ui/stats_popup.py`
- [Scripts panel](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/ui/scripts_popup.py): ui modal · Launches analysis and dataset operations from the GUI. · `annotator/src/ui/scripts_popup.py`
- [Hotkeys](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/shortcuts/keyboard.py): shortcuts · Keyboard bindings for fast annotation work. · `annotator/src/shortcuts/keyboard.py`
- [Global sync](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/sync/global_sync.py): cloud metrics · Uploads lightweight team progress metrics to a shared gist. · `annotator/src/sync/global_sync.py`
- [Updater](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/src/updater/update_manager.py): release check · Checks for releases and can trigger asynchronous updates. · `annotator/src/updater/update_manager.py`

### Telegram bot

Separate service for receiving or routing news items into the annotation workflow.

- [Telegram bot](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/bot-server/telegram_bot.py): service runtime · Receives or polls Telegram messages and routes news links. · `bot-server/telegram_bot.py`
- [Webhook API](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/bot-server/api/index.py): serverless api · Webhook entrypoint for the bot deployment. · `bot-server/api/index.py`
- [Webhook setup](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/bot-server/setup_webhook.py): deployment helper · Registers Telegram webhook configuration for the bot. · `bot-server/setup_webhook.py`

### Build and release

Packaging and CI pipeline for desktop releases and bot deployment.

- [Packager](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/annotator/build.py): desktop build · Creates standalone binaries for supported platforms. · `annotator/build.py`
- [CI build](https://github.com/faysal1000/fake-news-annotation-tool/blob/main/.github/workflows/build.yml): github workflow · Builds release artifacts from version tags and publishes releases. · `.github/workflows/build.yml`

## Connections

- Launcher → Bootstrap: initializes · Launcher hands off to startup checks and runtime setup.
- Launcher → Main window: starts · Launches the primary GUI shell.
- Packager → Launcher: packages · Bundles the desktop entrypoint into standalone binaries.
- Main window → Mode switch: routes · Main window delegates view switching to the mode controller.
- Mode switch → Annotate: opens · Activates annotation workflow.
- Mode switch → Review: opens · Activates review workflow.
- Mode switch → Re-label: opens · Activates blind relabel workflow.
- Annotate → CSV store: writes · Saves new records into the local dataset CSV.
- Review → CSV store: reads/writes · Loads and updates persisted records.
- Re-label → CSV store: reads · Uses saved records as the source for blind relabeling.
- Main window → Media manager: uses · Coordinates media attachment and preview flows.
- Main window → Stats engine: queries · Requests counts and summary metrics for the dashboard.
- Stats engine → Stats dashboard: feeds · Provides computed metrics to the interactive statistics UI.
- Main window → Duplicate engine: checks · Surfaces duplicate auditing in the main workflow.
- Duplicate engine → Similarity: uses · Relies on normalization and similarity scoring.
- Duplicate engine → Main window: flags · Pushes duplicate status back into the UI.
- Main window → Scripts panel: launches · Exposes analysis and dataset operations through action dialogs.
- Scripts panel → Aggregator: runs · Invokes dataset aggregation and derived sample generation.
- Scripts panel → Kappa: runs · Invokes agreement calculations for reliability workflows.
- Main window → Hotkeys: binds · Registers hotkeys for fast annotation actions.
- Main window → Global sync: reports · Sends lightweight progress metrics when enabled.
- Main window → Updater: checks · Integrates optional release checking and update flow.
- Telegram bot → Webhook API: deploys · Supports webhook-based serverless deployment.
- Webhook setup → Telegram bot: configures · Registers Telegram webhook settings for the bot service.
- CI build → Packager: builds · CI drives desktop packaging and release artifact creation.
- CI build → Telegram bot: deploys · Supports the bot service release/deployment path.
