Geopolitical and Macro Analyst for the upcoming big crisis of 2026 https://read.markets
Find a file
Giorgio Gilestro 411094d7b8 admin: internal-only superadmin console (users, payments, DB stats)
New independent `admin` service (admin.main:app) on the same image, reusing
app.db/app.models read-only. Never runs migrations or the scheduler; issues
SELECTs only.

- Password-gated (ADMIN_CONSOLE_PASSWORD) with a 12h signed cookie; closed by
  default when the password is empty.
- Bound to 127.0.0.1:8091 (SSH-tunnel access); off the intranet/NPM network.
- Pages: overview stats, user list + search, per-user history/payment detail,
  DB usage (information_schema size + row estimates).
- Compose: base `admin` service (+prod DB-host override, test mount); Dockerfile
  bakes admin/ into runtime + test stages.
- Tests: tests/test_admin_console.py (auth, queries, page wiring) — 12 passing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 16:08:20 +02:00
admin admin: internal-only superadmin console (users, payments, DB stats) 2026-07-01 16:08:20 +02:00
alembic feedback: thumb up/down on logs + reviewer self-score 0-10 2026-05-29 21:28:03 +02:00
app admin: internal-only superadmin console (users, payments, DB stats) 2026-07-01 16:08:20 +02:00
config add ECB Data Portal source; group-aware stale thresholds 2026-05-15 23:13:58 +01:00
docs docs: mobile responsiveness design spec 2026-05-28 18:30:42 +02:00
scripts scripts: one-off purge of unclean IndicatorSummary rows 2026-05-29 13:56:47 +02:00
tasks phase G: data minimisation + passwordless auth + DeepSeek-first LLM 2026-05-18 14:16:57 +01:00
tests admin: internal-only superadmin console (users, payments, DB stats) 2026-07-01 16:08:20 +02:00
.dockerignore initial commit — cassandra v0.1 2026-05-15 21:56:10 +01:00
.env.example admin: internal-only superadmin console (users, payments, DB stats) 2026-07-01 16:08:20 +02:00
.gitignore docs: mobile responsiveness design spec 2026-05-28 18:30:42 +02:00
alembic.ini initial commit — cassandra v0.1 2026-05-15 21:56:10 +01:00
docker-compose.override.yml sync: encrypted cloud backup for portfolios + settings UX rework 2026-05-23 16:15:54 +02:00
docker-compose.prod.yml admin: internal-only superadmin console (users, payments, DB stats) 2026-07-01 16:08:20 +02:00
docker-compose.test.yml admin: internal-only superadmin console (users, payments, DB stats) 2026-07-01 16:08:20 +02:00
docker-compose.yml admin: internal-only superadmin console (users, payments, DB stats) 2026-07-01 16:08:20 +02:00
Dockerfile admin: internal-only superadmin console (users, payments, DB stats) 2026-07-01 16:08:20 +02:00
pyproject.toml i18n: bilingual landing page (EN / IT) with auto-detect routing 2026-05-29 17:10:45 +02:00
README.md deploy: split compose into base (prod-ready) + dev override 2026-05-22 21:30:28 +01:00
requirements.lock deps: add requirements.lock for reproducible builds 2026-05-28 00:07:38 +02:00

Read the Markets

Containerised macro-strategy dashboard — hourly market data, RSS news, Trading 212 portfolio, and an AI-generated strategic log written by Cassandra, the in-product seer. Read-only by design.

Production:

The Python package is still named cassandra and several internal identifiers (cookie names, advisory-lock keys, CASSANDRA_TOKEN env var, CSS filename) keep the legacy name on purpose — renaming them would invalidate live sessions / locks / configs for no user benefit. See app/branding.py for the brand single-source-of-truth.

Quick start (local dev)

cp .env.example .env       # fill in API keys; set CASSANDRA_TOKEN if exposing
docker compose up --build  # db + app + scheduler + daily backup sidecar
open http://localhost:8000/  # or whichever CASSANDRA_PORT you set

docker-compose.override.yml is auto-loaded and adds the host port binding so the app is reachable on localhost.

Production (VPS, NPM-fronted)

Always invoke with explicit -f flags — that way the dev override is skipped and the prod overlay (no host port, joins the external intranet Docker network, uvicorn on port 80) is applied:

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build

Point Nginx Proxy Manager at upstream readmarkets-app-1:80.

Architecture

  • app (FastAPI + Jinja2 + HTMX) — web dashboard on port 8000
  • scheduler (APScheduler) — hourly ingestion jobs (market, news, portfolio, AI log)
  • db (MariaDB 11) — quotes, headlines, portfolio snapshots, strategic logs, job runs
  • backup (sidecar) — daily mariadb-dump to ./backup/

See /home/gg/.claude/plans/ok-i-think-this-tidy-lake.md for the design plan.

Config

File Purpose
config/default.toml Universal data tables: indicator groups, RSS feeds, keyword presets
config/portfolio.toml User-specific portfolios (overrides default.toml)
.env Secrets and runtime knobs — mounted read-only into containers

Endpoints

  • GET / — dashboard
  • GET /portfolio/{name} — portfolio detail
  • GET /news — news feed
  • GET /log — strategic-log archive
  • GET /api/health — job status (last success / failure per job)

All authenticated routes require Authorization: Bearer $CASSANDRA_TOKEN if the env is set; if unset, the app is open (LAN-only mode).