feat: Go backend production cutover — website layer, ingest forwarding, alerts, live fixes
Completes the Go backend so it can fully replace Python in production: tracker-go website layer (serves the unchanged frontend): - static file serving + SPA fallback + /icons (website.go) - login/logout with itsdangerous cookie ISSUING (bcrypt, Python-interop) and the /me handler (auth.go issueSessionCookie + website.go) - admin user CRUD (website_admin.go) and the issue-board write side (website_issues.go) - request-scoped user context + requireAdmin (auth.go) cutover ingest (gated off during the parallel run, required for a clean cutover): - inventory forwarding: full_inventory -> /process-inventory, inventory_delta -> item POST/DELETE, per-character serialized, fire-and-forget (inventory_forward.go) - death/idle Discord alerts via DISCORD_ACLOG_WEBHOOK (aclog.go) - SKIP_SCHEMA_INIT so write mode against the prod DBs runs no DDL (tracker-go + inventory-go) two bugs found live and fixed: - coerceNum: the plugin sends kills_per_hour/deaths/total_deaths/prismatic_taper_count as STRINGS; pydantic coerced them, Go's number helpers wrote null/0 (reads.go/ingest.go) - telemetry is broadcast TYPELESS so the browser ignores it and uses the /live poll; broadcasting it typed flapped the per-player counters 0<->value (ingest.go stripType) docker-compose.cutover.yml: reversible override flipping the Go services to write mode against the production DBs and repointing the Discord bot at the Go /ws/live. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
776076b981
commit
5ade47dc64
13 changed files with 1074 additions and 66 deletions
|
|
@ -87,9 +87,13 @@ func (s *Server) loadIssues() []any {
|
|||
return v
|
||||
}
|
||||
|
||||
// GET /me — current user. Phase 1 has no session-cookie verification yet, so
|
||||
// (like the Python service for an unauthenticated request) this is 401. The
|
||||
// loopback internal-trust path carries no user identity. (main.py:1455)
|
||||
// GET /me — current user from the session (main.py:1455). Internal-trust
|
||||
// loopback requests carry no user identity, so they get 401 too.
|
||||
func (s *Server) handleMe(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, http.StatusUnauthorized, map[string]any{"detail": "Not authenticated"})
|
||||
u := currentUser(r)
|
||||
if u == nil {
|
||||
writeJSON(w, http.StatusUnauthorized, map[string]any{"detail": "Not authenticated"})
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, map[string]any{"username": u.Username, "is_admin": u.IsAdmin})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue