package router import ( "net/http" httpapi "crm-core/internal/api/http" "crm-core/internal/api/handlers" "crm-core/internal/infrastructure/auth" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "log/slog" ) func NewRouter(logger *slog.Logger, authMiddleware *auth.Middleware, handlerSet handlers.HandlerSet) http.Handler { r := chi.NewRouter() r.Use(middleware.Recoverer) r.Use(httpapi.RequestID) r.Use(httpapi.Logging(logger)) r.Get("/health", handlerSet.Health) r.Route("/api/v1", func(r chi.Router) { r.Use(authMiddleware.RequireJWT) r.Route("/accounts", func(r chi.Router) { r.With(auth.RequireScopes("crm.read")).Get("/", handlerSet.Accounts.List) r.With(auth.RequireScopes("crm.read")).Get("/{id}", handlerSet.Accounts.Get) r.With(auth.RequireScopes("crm.write")).Post("/", handlerSet.Accounts.Create) r.With(auth.RequireScopes("crm.write")).Patch("/{id}", handlerSet.Accounts.Update) r.With(auth.RequireScopes("crm.write")).Delete("/{id}", handlerSet.Accounts.Archive) }) r.Route("/contacts", func(r chi.Router) { r.With(auth.RequireScopes("crm.read")).Get("/", handlerSet.Contacts.List) r.With(auth.RequireScopes("crm.read")).Get("/{id}", handlerSet.Contacts.Get) r.With(auth.RequireScopes("crm.write")).Post("/", handlerSet.Contacts.Create) r.With(auth.RequireScopes("crm.write")).Patch("/{id}", handlerSet.Contacts.Update) r.With(auth.RequireScopes("crm.write")).Delete("/{id}", handlerSet.Contacts.Archive) }) r.Route("/pipelines", func(r chi.Router) { r.With(auth.RequireScopes("crm.read")).Get("/", handlerSet.Stages.ListPipelines) r.With(auth.RequireScopes("crm.write")).Post("/", handlerSet.Stages.CreatePipeline) r.With(auth.RequireScopes("crm.read")).Get("/{id}/stages", handlerSet.Stages.ListStages) r.With(auth.RequireScopes("crm.write")).Post("/{id}/stages", handlerSet.Stages.CreateStage) }) r.Route("/deals", func(r chi.Router) { r.With(auth.RequireScopes("crm.read")).Get("/", handlerSet.Deals.List) r.With(auth.RequireScopes("crm.read")).Get("/{id}", handlerSet.Deals.Get) r.With(auth.RequireScopes("crm.write")).Post("/", handlerSet.Deals.Create) r.With(auth.RequireScopes("crm.write")).Patch("/{id}", handlerSet.Deals.Update) r.With(auth.RequireScopes("crm.write")).Post("/{id}/move-stage", handlerSet.Deals.MoveStage) r.With(auth.RequireScopes("crm.write")).Post("/{id}/close", handlerSet.Deals.Close) }) r.Route("/activities", func(r chi.Router) { r.With(auth.RequireScopes("crm.read")).Get("/", handlerSet.Activities.List) r.With(auth.RequireScopes("crm.write")).Post("/", handlerSet.Activities.Create) r.With(auth.RequireScopes("crm.write")).Post("/{id}/complete", handlerSet.Activities.Complete) r.With(auth.RequireScopes("crm.write")).Delete("/{id}", handlerSet.Activities.Cancel) }) r.Route("/notes", func(r chi.Router) { r.With(auth.RequireScopes("crm.read")).Get("/", handlerSet.Notes.List) r.With(auth.RequireScopes("crm.write")).Post("/", handlerSet.Notes.Create) }) r.Route("/tags", func(r chi.Router) { r.With(auth.RequireScopes("crm.read")).Get("/", handlerSet.Tags.List) r.With(auth.RequireScopes("crm.write")).Post("/", handlerSet.Tags.Upsert) r.With(auth.RequireScopes("crm.write")).Post("/assign", handlerSet.Tags.Assign) r.With(auth.RequireScopes("crm.write")).Post("/unassign", handlerSet.Tags.Unassign) }) }) return r }