build source
This commit is contained in:
commit
ee1fec43ed
4171 changed files with 1351288 additions and 0 deletions
99
internal/api/billing.go
Normal file
99
internal/api/billing.go
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"github.com/iliaivanov/spec-kit-remote/cmd/dev-pod-api/internal/model"
|
||||
"github.com/iliaivanov/spec-kit-remote/cmd/dev-pod-api/internal/store"
|
||||
)
|
||||
|
||||
func (s *Server) handleGetUserUsage(w http.ResponseWriter, r *http.Request) {
|
||||
targetUser := chi.URLParam(r, "user")
|
||||
|
||||
if !canAccess(r, targetUser) {
|
||||
writeError(w, http.StatusForbidden, "access denied")
|
||||
return
|
||||
}
|
||||
|
||||
user, err := s.Users.GetUser(r.Context(), targetUser)
|
||||
if err != nil {
|
||||
if errors.Is(err, store.ErrNotFound) {
|
||||
writeError(w, http.StatusNotFound, "user not found")
|
||||
return
|
||||
}
|
||||
writeError(w, http.StatusInternalServerError, "failed to get user")
|
||||
return
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
usage, err := s.Usage.GetUsage(r.Context(), targetUser, now.Year(), now.Month(), user.Quota.MonthlyPodHours)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, "failed to get usage")
|
||||
return
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, map[string]*model.UsageSummary{
|
||||
"current_month": usage,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Server) handleBillingSummary(w http.ResponseWriter, r *http.Request) {
|
||||
if RoleFromContext(r.Context()) != model.RoleAdmin {
|
||||
writeError(w, http.StatusForbidden, "admin access required")
|
||||
return
|
||||
}
|
||||
|
||||
users, err := s.Users.ListUsers(r.Context())
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, "failed to list users")
|
||||
return
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
summaries := make([]model.UserUsageSummary, 0, len(users))
|
||||
for _, u := range users {
|
||||
usage, err := s.Usage.GetUsage(r.Context(), u.ID, now.Year(), now.Month(), u.Quota.MonthlyPodHours)
|
||||
if err != nil {
|
||||
s.Logger.Error("failed to get usage for user", "user", u.ID, "error", err)
|
||||
continue
|
||||
}
|
||||
summaries = append(summaries, model.UserUsageSummary{
|
||||
UserID: u.ID,
|
||||
Usage: *usage,
|
||||
})
|
||||
}
|
||||
writeJSON(w, http.StatusOK, summaries)
|
||||
}
|
||||
|
||||
func (s *Server) handleBillingHistory(w http.ResponseWriter, r *http.Request) {
|
||||
targetUser := chi.URLParam(r, "user")
|
||||
|
||||
if !canAccess(r, targetUser) {
|
||||
writeError(w, http.StatusForbidden, "access denied")
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := s.Users.GetUser(r.Context(), targetUser); err != nil {
|
||||
if errors.Is(err, store.ErrNotFound) {
|
||||
writeError(w, http.StatusNotFound, "user not found")
|
||||
return
|
||||
}
|
||||
writeError(w, http.StatusInternalServerError, "failed to get user")
|
||||
return
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
daily, err := s.Usage.GetDailyUsage(r.Context(), targetUser, now.Year(), now.Month())
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, "failed to get usage history")
|
||||
return
|
||||
}
|
||||
if daily == nil {
|
||||
daily = []model.DailyUsage{}
|
||||
}
|
||||
writeJSON(w, http.StatusOK, daily)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue