← Case study
Browse all guides

CITA Traffic Platform / Documentation

Architecture

Trace a response and check the boundaries between collection, database, and dashboard.

Thesis-source commands assume the Quickstart checkout and configuration. In each new terminal, run export COMPOSE_PROJECT_NAME=cita-docs-review before using Compose.

Jump to a section

Trace one response

  1. Schedule and fetch

    The feed catalog supplies per-feed intervals. The monotonic scheduler handles due feeds sequentially, with bounded retries and timeouts in the HTTP client.

  2. Archive the bytes

    SHA-256 identifies byte content. New gzip files are written through a temporary file, fsync, and an atomic rename. Database failure still leads to an attempted filesystem archive.

  3. Register the fetch

    A feed/hash pair reuses one snapshot; every fetch has its own observation. Duplicates skip parsing and preserve the snapshot’s earlier parse status.

  4. Parse and commit

    A feed-specific parser returns domain records and warnings. Detailed records, compatibility projections, warnings, and parsed status are persisted transactionally. Failure rolls back that group; the handler marks the snapshot failed while its archived bytes remain.

  5. Query and display

    PostgreSQL filters and aggregates before Polars/Streamlit render results. The dashboard never fetches CITA. Stopping it does not stop collection.

Inspect services and persistence

Runtime boundaries
ServiceResponsibilityState
collectorFetch, archive, parse, write PostgreSQLraw_feed_data at /app/data/raw
postgresDomain, compatibility, run/fetch metadatapostgres_data
dashboardQuery PostgreSQL; expose Streamlit port 8501No raw archive or source-feed access needed
Thesis source · health checks
docker compose ps
docker compose exec -T postgres pg_isready -U cita -d cita
docker compose exec -T collector python -m collector.healthcheck

Expected: PostgreSQL reports accepting connections. Collector health exits 0 for a recent successful or partial run, not complete feed coverage. The fixture helper does not create a collection-run row, so it alone cannot make this check pass.

Startup and query helpers initialize the schema. Although dashboard application queries read data, its current startup needs initialization privileges; a restricted read-only account is not a drop-in replacement.

Change the actual polling schedule

In your own source checkout, edit FeedConfig.interval_seconds in config/feeds.py, then rebuild the collector.

Thesis source · shell
docker compose build collector
docker compose up -d collector
docker compose logs --tail=30 collector

Expected: Startup logs enumerate feed intervals. COLLECTION_INTERVAL_SECONDS is not a global scheduler override. The active fetcher uses REQUEST_TIMEOUT = (10, 30); the general REQUEST_TIMEOUT_SECONDS variable does not control that path.

Run the source tests

Thesis source · Python 3.12 shell
python3.12 -m venv .venv
.venv/bin/python -m pip install -r requirements/dev.txt
.venv/bin/python -m pytest -p no:cacheprovider

Expected: Pytest exits 0. The submitted snapshot has 55 parametrized cases across 13 files. Database-query tests use test doubles, not a live database. The quickstart fixture separately exercises real PostgreSQL.

Persistent alert functions/tests exist, but the main collector/dashboard flow does not call sync_alerts. Quality is computed at read time; historical unassessed fields do not preserve a versioned quality decision.

Source files

Paths identify the relevant files and symbols in the inspected source distribution; they are not links to an assumed public repository. See access requirements.

collector/scheduler.py
run_scheduler
collector/fetcher.py
create_http_session / fetch_feed
collector/collector.py
collect_feed / collect_once
collector/raw_archive.py
archive_payload
database/lossless.py
register_snapshot / persist_parsed_snapshot
database/db.py
initialize_database / _query_rows
dashboard/app.py
main and live fragments
tests/test_collector_resilience.py / tests/test_lossless_collection.py
Isolation, archive and HTTP checks