65 lines
1.7 KiB
Go
65 lines
1.7 KiB
Go
// 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")
|
|
}
|