package api import ( "github.com/go-chi/chi/v5" "github.com/alexei/docker-watcher/internal/docker" "github.com/alexei/docker-watcher/internal/store" "github.com/alexei/docker-watcher/internal/webhook" ) // Server holds all dependencies for the API layer. type Server struct { store *store.Store docker *docker.Client deployer DeployTriggerer webhook *webhook.Handler encKey [32]byte } // NewServer creates a new API Server with all required dependencies. func NewServer( st *store.Store, dockerClient *docker.Client, deployer DeployTriggerer, webhookHandler *webhook.Handler, encKey [32]byte, ) *Server { return &Server{ store: st, docker: dockerClient, deployer: deployer, webhook: webhookHandler, encKey: encKey, } } // Router returns a chi router with all API routes mounted. func (s *Server) Router() chi.Router { r := chi.NewRouter() // Global middleware. r.Use(recovery) r.Use(logging) r.Use(cors) r.Use(jsonContentType) r.Route("/api", func(r chi.Router) { // Project endpoints. r.Get("/projects", s.listProjects) r.Post("/projects", s.createProject) r.Route("/projects/{id}", func(r chi.Router) { r.Get("/", s.getProject) r.Put("/", s.updateProject) r.Delete("/", s.deleteProject) // Stage endpoints. r.Post("/stages", s.createStage) r.Put("/stages/{stage}", s.updateStage) r.Delete("/stages/{stage}", s.deleteStage) // Instance endpoints. r.Get("/stages/{stage}/instances", s.listInstances) r.Post("/stages/{stage}/instances", s.deployInstance) r.Delete("/stages/{stage}/instances/{iid}", s.removeInstance) // Instance control endpoints. r.Post("/stages/{stage}/instances/{iid}/stop", s.stopInstance) r.Post("/stages/{stage}/instances/{iid}/start", s.startInstance) r.Post("/stages/{stage}/instances/{iid}/restart", s.restartInstance) }) // Deploy endpoints. r.Get("/deploys", s.listDeploys) r.Get("/deploys/{id}/logs", s.getDeployLogs) // Quick deploy endpoints. r.Post("/deploy/inspect", s.inspectImage) r.Post("/deploy/quick", s.quickDeploy) // Registry endpoints. r.Get("/registries", s.listRegistries) r.Post("/registries", s.createRegistry) r.Route("/registries/{id}", func(r chi.Router) { r.Put("/", s.updateRegistry) r.Delete("/", s.deleteRegistry) r.Post("/test", s.testRegistry) r.Get("/tags/*", s.listRegistryTags) }) // Settings endpoints. r.Get("/settings", s.getSettings) r.Put("/settings", s.updateSettings) r.Get("/settings/webhook-url", s.getWebhookURL) r.Post("/settings/regenerate", s.regenerateWebhookSecret) // Webhook handler (from webhook package). r.Mount("/webhook", s.webhook.Route()) }) return r }