Files
brain/main.go
T
Andrew S Erwin 4e421f6ea2
release gate / check (push) Failing after 6m43s
Address code review findings across API, web and deployment
High severity:
- wire TRUSTED_PROXY through Compose/deploy/docs and warn at web startup
- bucket public rate limits on effective client IP, add per-bookmark budget,
  and forward the signed browser identity from the share page
- disable first-run bootstrap in server deployments and document seeding
- serialize last-admin demotion in one advisory-locked transaction

Medium/low:
- cap and batch share recipient inserts
- add a shared outbound budget for preview/CardDAV/IMAP/signal work
- pin CardDAV dials to 443 and bound IMAP logout
- fix rightward kanban column drags and normalize cards on column delete
- classify backend outages in auth guards, add request timeouts and an
  error boundary, remove the dead login route, surface throttling
- enforce pinned/unpinned page reorder grouping server-side
- avoid preview work for stale bookmark versions; drop duplicate dialog fetch
- sequence-guard collection/tag/calendar/quick-find loads
- validate property config and fix MULTI_SELECT/DATE filter inputs
- document index maintenance; apply same-origin check to sign-out
- trim signup names, unique shared dates and kanban keys (migration 010),
  reset reference cache on identity changes, hide OIDC issuer, return 413
  for oversized direct bodies, escape Markdown link destinations
- remove dead template files and duplicate test helper

Verified with go build/vet, full PostgreSQL race suite, db convergence,
tsc, both ESLint configs and a Next production build.
2026-10-20 00:13:30 -05:00

79 lines
1.9 KiB
Go

package main
import (
"context"
"errors"
"github.com/andrew/go-computer/internal/config"
"github.com/andrew/go-computer/internal/db"
"github.com/andrew/go-computer/internal/http"
"github.com/andrew/go-computer/internal/scripts"
"github.com/andrew/go-computer/internal/signals"
"log"
stdhttp "net/http"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
if len(os.Args) > 1 && os.Args[1] == "--healthcheck" {
client := stdhttp.Client{Timeout: 3 * time.Second}
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
res, err := client.Get("http://127.0.0.1:" + port + "/readyz")
if err != nil {
os.Exit(1)
}
res.Body.Close()
if res.StatusCode != 200 {
os.Exit(1)
}
return
}
cfg := config.Load()
if err := cfg.Validate(); err != nil {
log.Fatalf("config: %v", err)
}
d, err := db.New(cfg)
if err != nil {
log.Fatalf("db: %v", err)
}
defer d.Close()
if len(os.Args) > 1 && os.Args[1] == "--seed" {
if err := scripts.Seed(context.Background(), d); err != nil {
log.Fatal(err)
}
return
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
// Shutdown order is owned by main (review OPS-01): drain in-flight HTTP
// requests first, then await the background loops, and only afterwards let
// the deferred db close run. Previously Shutdown raced ListenAndServe's
// return and the process exited mid-drain.
workersDone := make(chan struct{})
go func() {
defer close(workersDone)
signals.RunLoop(ctx, d)
}()
srv := http.NewServer(cfg, d)
go func() {
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, stdhttp.ErrServerClosed) {
log.Fatalf("server failed: %v", err)
}
}()
log.Printf("computer API listening on %s", srv.Addr)
<-ctx.Done()
stop()
shutdown, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
if err := srv.Shutdown(shutdown); err != nil {
log.Printf("shutdown: %v", err)
}
<-workersDone
}