initial commit — cassandra v0.1
Containerised macro-strategy dashboard: 4-panel web UI (indicators, portfolio, flash news, AI strategic log), MariaDB store, hourly ingestion jobs, OpenRouter-backed AI analysis. Ports the four prototype scripts in the parent dir (market_pulse, flash_news, trading212, strategic_log) into async services backed by a persistent DB and served via FastAPI + Jinja2 + HTMX. APScheduler runs as a separate compose service for crash-safety and easier restarts. Portfolio composition + position names come live from Trading 212; news per-ticker headlines reuse those names. Tone (NOVICE/INTERMEDIATE/ PRO) and analysis style (DRY/SPECULATIVE) are env-configurable and stored on each log row so historical entries show what produced them. Default model is deepseek/deepseek-v4-flash (overridable via env). Light/dark theme toggle, sans-serif for prose surfaces, monospace for data. Bearer-token auth, OpenRouter monthly cost cap, RSS feeds auto- disabled on consecutive failures. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
a10409c02b
61 changed files with 4890 additions and 0 deletions
75
docker-compose.yml
Normal file
75
docker-compose.yml
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
# Cassandra — app + scheduler + MariaDB + daily backup sidecar.
|
||||
# .env is mounted read-only; never bake secrets into the image.
|
||||
|
||||
services:
|
||||
db:
|
||||
image: mariadb:11
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD:-changeme-root}
|
||||
MARIADB_DATABASE: ${MARIADB_DATABASE:-cassandra}
|
||||
MARIADB_USER: ${MARIADB_USER:-cassandra}
|
||||
MARIADB_PASSWORD: ${MARIADB_PASSWORD:-changeme}
|
||||
volumes:
|
||||
- db-data:/var/lib/mysql
|
||||
- ./backup:/backup
|
||||
healthcheck:
|
||||
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
app:
|
||||
build: .
|
||||
restart: unless-stopped
|
||||
command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "1"]
|
||||
env_file: .env
|
||||
environment:
|
||||
DATABASE_URL: mysql+aiomysql://${MARIADB_USER:-cassandra}:${MARIADB_PASSWORD:-changeme}@db:3306/${MARIADB_DATABASE:-cassandra}
|
||||
volumes:
|
||||
- ./config:/app/config:ro
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "${CASSANDRA_PORT:-8000}:8000"
|
||||
|
||||
scheduler:
|
||||
build: .
|
||||
restart: unless-stopped
|
||||
command: ["python", "-m", "app.scheduler_main"]
|
||||
env_file: .env
|
||||
environment:
|
||||
DATABASE_URL: mysql+aiomysql://${MARIADB_USER:-cassandra}:${MARIADB_PASSWORD:-changeme}@db:3306/${MARIADB_DATABASE:-cassandra}
|
||||
volumes:
|
||||
- ./config:/app/config:ro
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
|
||||
backup:
|
||||
image: mariadb:11
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MARIADB_HOST: db
|
||||
MARIADB_USER: ${MARIADB_USER:-cassandra}
|
||||
MARIADB_PASSWORD: ${MARIADB_PASSWORD:-changeme}
|
||||
MARIADB_DATABASE: ${MARIADB_DATABASE:-cassandra}
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
# Daily dump at 03:00 UTC; keeps last 14 days.
|
||||
command: |
|
||||
"while true; do
|
||||
sleep $$((86400 - $$(date +%s) % 86400 + 10800));
|
||||
f=/backup/cassandra-$$(date -u +%Y-%m-%d).sql.gz;
|
||||
echo \"[backup] $$f\";
|
||||
mariadb-dump -h $$MARIADB_HOST -u $$MARIADB_USER -p$$MARIADB_PASSWORD $$MARIADB_DATABASE | gzip > $$f || echo '[backup] FAILED';
|
||||
find /backup -name 'cassandra-*.sql.gz' -mtime +14 -delete;
|
||||
done"
|
||||
volumes:
|
||||
- ./backup:/backup
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
|
||||
volumes:
|
||||
db-data:
|
||||
Loading…
Add table
Add a link
Reference in a new issue