// Command postgis-probe performs a read-only, non-record-level readiness audit. package main import ( "context" "encoding/json" "fmt" "log" "os" "os/signal" "syscall" "time" "fire-safety-ymd/internal/config" "fire-safety-ymd/internal/repository" ) const probeTimeout = 45 * time.Second func main() { cfg, err := config.Load() if err != nil { log.Fatalf("load configuration: %v", err) } if !cfg.PostGIS.Enabled { log.Fatalf("%s must be true to run the PostGIS readiness probe", config.PostGISEnabledEnv) } signalCtx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() ctx, cancel := context.WithTimeout(signalCtx, probeTimeout) defer cancel() postGIS, err := repository.OpenPostGIS(ctx, repository.PostGISOptions{ DSN: cfg.PostGIS.DSN, MaxConns: cfg.PostGIS.MaxConns, ConnectTimeout: cfg.PostGIS.ConnectTimeout, QueryTimeout: cfg.PostGIS.QueryTimeout, }) if err != nil { log.Fatalf("initialize PostGIS: %v", err) } defer postGIS.Close() var report repository.ReadinessReport if cfg.PostGIS.ExpectedSRID == 0 { report, err = postGIS.Audit(ctx) } else { report, err = postGIS.ValidateForMCP(ctx, cfg.PostGIS.ExpectedSRID) } if len(report.Tables) > 0 { if encodeErr := json.NewEncoder(os.Stdout).Encode(report); encodeErr != nil { log.Fatalf("encode readiness report: %v", encodeErr) } } if err != nil { log.Fatalf("audit PostGIS: %v", err) } if cfg.PostGIS.ExpectedSRID == 0 { fmt.Fprintln(os.Stderr, "readiness note: FIRE_SAFETY_POSTGIS_EXPECTED_SRID is not set; audit only, MCP spatial validation was not performed") return } fmt.Fprintln(os.Stderr, "MCP spatial validation passed") }