diff --git a/api/api.go b/api/api.go index 2149cb8..6870e65 100644 --- a/api/api.go +++ b/api/api.go @@ -278,6 +278,11 @@ func RegisterRoutes(r *gin.Engine, opts ...Option) { authProtected.POST("/admin/users/:userId/role", h.updateUserRole) authProtected.DELETE("/admin/users/:userId/role", h.resetUserRole) + // Internal routes for service-to-service reads. + internalGroup := r.Group("/api/internal") + internalGroup.Use(auth.InternalAuthMiddleware()) + internalGroup.GET("/public-overview", h.internalPublicOverview) + // Public /api routes for admin/management (expected by frontend at /api/admin/...) apiGroup := r.Group("/api") if h.tokenService != nil { diff --git a/api/internal_public_overview.go b/api/internal_public_overview.go new file mode 100644 index 0000000..4f24d99 --- /dev/null +++ b/api/internal_public_overview.go @@ -0,0 +1,26 @@ +package api + +import ( + "net/http" + "time" + + "github.com/gin-gonic/gin" +) + +type internalPublicOverviewResponse struct { + RegisteredUsers int `json:"registeredUsers"` + UpdatedAt time.Time `json:"updatedAt"` +} + +func (h *handler) internalPublicOverview(c *gin.Context) { + users, err := h.store.ListUsers(c.Request.Context()) + if err != nil { + respondError(c, http.StatusInternalServerError, "list_users_failed", "failed to fetch users") + return + } + + c.JSON(http.StatusOK, internalPublicOverviewResponse{ + RegisteredUsers: len(users), + UpdatedAt: time.Now().UTC(), + }) +}