User reported 'still broken' on /ui/tags/ai/ right after the 20-card cap
shipped — the deployed HTML was correct (verified in-pod: 20 cards + View
all 363 posts) but Safari was serving a heuristically cached copy of the
previous template. UI HTML responses had no Cache-Control at all.
- core/middleware.NoCacheUiPagesMiddleware: /ui/* HTML → Cache-Control:
no-cache, no-store, must-revalidate (+ Pragma/Expires). API untouched.
- tag_detail: defensive width:100% + box-sizing on .tags-page/.apple-card
- Add django.contrib.humanize; apply intcomma to every currency amount across invest templates (dashboard, portfolio detail, transactions)
- get_risk_summary now aggregates top_positions by ticker (MRVL across MOMO+IBKR merges into one row with Accounts column), keeping Top 1/3/5 cards and table on the same basis
- Mobile: metric cards all 2-col (2x2 + 2+1 with Last Snapshot spanning full width), no more 1-col break
- Transactions show source badges: purple 🤖 AI (source ai/ocr), grey 手动, amber ⚠ 低置信 when confidence < 0.9
- Delete unused invest/base.html (dead nav; page extends GoLinks base.html)
- tailwind.config.js: add invest/jbot/routermon template dirs so their classes are scanned (text-[10px] etc. were silently missing)
- Portfolio management (MOMO, IBKR personal, IBKR Yanhua)
- Stock holdings with transaction history (buy/sell)
- Weekly AI report generation
- Real-time price cache via Finnhub API
- Dashboard with tree view and performance charts
- REST API with AI-friendly batch update endpoint
- Management command for scheduled report generation
For大哥's personal investment advisor system.
- Remove SO_REUSEADDR from UDP socket so only one gunicorn worker binds
port 5514 (second worker intentionally gets EADDRINUSE and skips)
- Add print() fallback for bind confirmation/errors so startup is visible
even when Django logging config is not fully set up
- Fix duplicate LOGGING dict in settings.py: second assignment was
overriding the first and removing the root logger handler, silently
swallowing all routermon/core startup logs
- Add sys.stderr fallback in core/apps.py ready() for startup exceptions
- Fix JS SyntaxError: {{ top_domains_json }} needs |safe filter since
Django auto-escapes quotes to " inside script tags
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>