@Summary Upsert group AI budget @ID upsert-group-ai-budget @Security CoderSessionToken @Accept json @Produce json @Tags Enterprise @Param group path string true "Group ID" format(uuid) @Param request body codersdk.UpsertGroupAIBudgetRequest true "Upsert group AI budget request" @Success 200 {object}
(rw http.ResponseWriter, r *http.Request)
| 738 | // @Success 200 {object} codersdk.GroupAIBudget |
| 739 | // @Router /api/v2/groups/{group}/ai/budget [put] |
| 740 | func (api *API) upsertGroupAIBudget(rw http.ResponseWriter, r *http.Request) { |
| 741 | var ( |
| 742 | ctx = r.Context() |
| 743 | group = httpmw.GroupParam(r) |
| 744 | auditor = api.AGPL.Auditor.Load() |
| 745 | aReq, commitAudit = audit.InitRequest[database.AuditableGroupAiBudget](rw, &audit.RequestParams{ |
| 746 | Audit: *auditor, |
| 747 | Log: api.Logger, |
| 748 | Request: r, |
| 749 | Action: database.AuditActionWrite, |
| 750 | OrganizationID: group.OrganizationID, |
| 751 | }) |
| 752 | ) |
| 753 | defer commitAudit() |
| 754 | |
| 755 | var req codersdk.UpsertGroupAIBudgetRequest |
| 756 | if !httpapi.Read(ctx, rw, r, &req) { |
| 757 | return |
| 758 | } |
| 759 | |
| 760 | // Capture the existing budget (if any) so the audit log records the |
| 761 | // before-state. An absent row leaves aReq.Old as the zero value. |
| 762 | oldBudget, err := api.Database.GetGroupAIBudget(ctx, group.ID) |
| 763 | if err != nil && !errors.Is(err, sql.ErrNoRows) { |
| 764 | api.Logger.Error(ctx, "fetch existing group AI budget for audit", slog.Error(err)) |
| 765 | httpapi.InternalServerError(rw, err) |
| 766 | return |
| 767 | } |
| 768 | aReq.Old = oldBudget.Auditable(group.Name) |
| 769 | |
| 770 | newBudget, err := api.Database.UpsertGroupAIBudget(ctx, database.UpsertGroupAIBudgetParams{ |
| 771 | GroupID: group.ID, |
| 772 | SpendLimitMicros: req.SpendLimitMicros, |
| 773 | }) |
| 774 | if httpapi.Is404Error(err) { |
| 775 | httpapi.ResourceNotFound(rw) |
| 776 | return |
| 777 | } |
| 778 | if err != nil { |
| 779 | api.Logger.Error(ctx, "upsert group AI budget", slog.Error(err)) |
| 780 | httpapi.InternalServerError(rw, err) |
| 781 | return |
| 782 | } |
| 783 | aReq.New = newBudget.Auditable(group.Name) |
| 784 | |
| 785 | httpapi.Write(ctx, rw, http.StatusOK, db2sdk.GroupAIBudget(newBudget)) |
| 786 | } |
| 787 | |
| 788 | // @Summary Delete group AI budget |
| 789 | // @ID delete-group-ai-budget |
nothing calls this directly
no test coverage detected