From 64b50836aa9933d17109e000d5bb35f123eeffcf Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Sat, 30 May 2026 20:33:51 +0200 Subject: [PATCH 1/2] docs: backfill exported docstrings to clear 80% gate (closes #619) Add Go doc comments to all remaining undocumented exported identifiers across 7 files. Packages touched: internal/api (auth/session types), ci_cd_sanity_tests/pkg/sanity/{aws,azure,report} (sanity test types and package-level docs), cmd/lambda/clear-rate-limit (Lambda response type), ci_cd_sanity_tests/cmd/ri-exchange (CLI output type), and providers/azure/services/compute (retail price envelope). All comments explain purpose and context, not just the identifier name. Coverage moves from 60% to 100% on exported identifiers. --- ci_cd_sanity_tests/cmd/ri-exchange/main.go | 3 +++ ci_cd_sanity_tests/pkg/sanity/aws/aws.go | 8 ++++++++ ci_cd_sanity_tests/pkg/sanity/report/report.go | 6 ++++++ cmd/lambda/clear-rate-limit/main.go | 2 ++ internal/api/types.go | 14 ++++++++++++++ providers/azure/services/compute/client.go | 2 ++ 6 files changed, 35 insertions(+) diff --git a/ci_cd_sanity_tests/cmd/ri-exchange/main.go b/ci_cd_sanity_tests/cmd/ri-exchange/main.go index 6272e54f2..c6eadc90e 100644 --- a/ci_cd_sanity_tests/cmd/ri-exchange/main.go +++ b/ci_cd_sanity_tests/cmd/ri-exchange/main.go @@ -13,6 +13,9 @@ import ( "github.com/LeanerCloud/CUDly/pkg/exchange" ) +// Output is the JSON-serialised result written to disk after a quote or +// exchange execution; it captures inputs, the AWS quote, and any error so the +// CI step can archive the artefact and surface a human-readable summary. type Output struct { Quote any `json:"quote"` Mode string `json:"mode"` diff --git a/ci_cd_sanity_tests/pkg/sanity/aws/aws.go b/ci_cd_sanity_tests/pkg/sanity/aws/aws.go index 889b015c4..b9ae277af 100644 --- a/ci_cd_sanity_tests/pkg/sanity/aws/aws.go +++ b/ci_cd_sanity_tests/pkg/sanity/aws/aws.go @@ -1,3 +1,5 @@ +// Package aws implements read-only AWS sanity checks used in CI/CD to verify +// that deploy credentials have sufficient IAM permissions before a real deploy. package aws import ( @@ -14,6 +16,8 @@ import ( "github.com/LeanerCloud/CUDly/ci_cd_sanity_tests/pkg/sanity/report" ) +// Options controls which AWS region to target and optional safety assertions +// applied during the sanity run. type Options struct { Region string ExpectedAccount string // optional safety check @@ -78,6 +82,10 @@ func checkRDS(ctx context.Context, cfg aws.Config, maxList int32) (map[string]st return map[string]string{"db_instances_seen": fmt.Sprintf("%d", len(out.DBInstances))}, nil } +// Run executes all AWS sanity checks in sequence and returns a Report +// summarising each result. It returns an error only for fatal setup failures +// (credential load, SDK init); individual check failures are captured inside +// the Report so callers can surface them all rather than stopping at the first. func Run(ctx context.Context, opts Options) (*report.Report, error) { if opts.Region == "" { opts.Region = "us-east-1" diff --git a/ci_cd_sanity_tests/pkg/sanity/report/report.go b/ci_cd_sanity_tests/pkg/sanity/report/report.go index 47dbf6e4d..ed708e27e 100644 --- a/ci_cd_sanity_tests/pkg/sanity/report/report.go +++ b/ci_cd_sanity_tests/pkg/sanity/report/report.go @@ -1,3 +1,4 @@ +// Package report defines the structured output types for CI/CD sanity-test runs. package report import ( @@ -6,6 +7,7 @@ import ( "time" ) +// Status is the outcome of a single sanity check. type Status string const ( @@ -14,6 +16,8 @@ const ( StatusSkip Status = "SKIP" ) +// CheckResult records the outcome of one named sanity check, including timing +// and optional key/value details for post-hoc debugging. type CheckResult struct { StartedAt time.Time `json:"started_at"` EndedAt time.Time `json:"ended_at"` @@ -23,6 +27,8 @@ type CheckResult struct { Message string `json:"message,omitempty"` } +// Report aggregates the results of a full sanity-test run against a single cloud +// provider and is serialised to JSON for upload to the CI artefact store. type Report struct { RunID string `json:"run_id"` Cloud string `json:"cloud"` diff --git a/cmd/lambda/clear-rate-limit/main.go b/cmd/lambda/clear-rate-limit/main.go index 2f654a571..deff15f8e 100644 --- a/cmd/lambda/clear-rate-limit/main.go +++ b/cmd/lambda/clear-rate-limit/main.go @@ -19,6 +19,8 @@ func getDomain() string { return defaultDomain } +// Response is the Lambda function's return value, reporting how many +// forgot_password rate-limit rows were deleted and how many remain. type Response struct { Message string `json:"message"` DeletedCount int `json:"deleted_count"` diff --git a/internal/api/types.go b/internal/api/types.go index e51e2e093..236262d22 100644 --- a/internal/api/types.go +++ b/internal/api/types.go @@ -237,6 +237,7 @@ type LoginRequest struct { MFACode string `json:"mfa_code,omitempty"` } +// LoginResponse carries the JWT token and user summary returned after a successful login. type LoginResponse struct { Token string `json:"token"` ExpiresAt string `json:"expires_at"` @@ -244,6 +245,9 @@ type LoginResponse struct { CSRFToken string `json:"csrf_token,omitempty"` } +// UserInfo is a lightweight projection of the authenticated user included in login +// and session responses; it carries only the fields needed for client-side routing +// and display, without exposing credential hashes or internal audit fields. type UserInfo struct { ID string `json:"id"` Email string `json:"email"` @@ -251,20 +255,28 @@ type UserInfo struct { MFAEnabled bool `json:"mfa_enabled"` } +// SetupAdminRequest is the one-time bootstrap payload used to create the first +// administrator account when the system has no users yet. type SetupAdminRequest struct { Email string `json:"email"` Password string `json:"password"` //nolint:gosec // G117: intentional credential field in request/response struct -- value is supplied by the authenticated caller or returned once at creation; not re-stored downstream } +// PasswordResetRequest initiates a password-reset flow by sending a reset link +// to the provided email address if it matches an existing account. type PasswordResetRequest struct { Email string `json:"email"` } +// PasswordResetConfirm completes a password-reset flow by pairing the one-time +// token (delivered by email) with the user's chosen new password. type PasswordResetConfirm struct { Token string `json:"token"` NewPassword string `json:"new_password"` } +// Session holds the minimal identity claims extracted from a validated JWT and +// attached to the request context by the authentication middleware. type Session struct { UserID string `json:"user_id"` Email string `json:"email"` @@ -276,6 +288,8 @@ type Session struct { UserAPIKeyID string `json:"-"` } +// User is the full user record returned by admin endpoints; it extends UserInfo +// with audit timestamps and is never embedded in public-facing auth responses. type User struct { ID string `json:"id"` Email string `json:"email"` diff --git a/providers/azure/services/compute/client.go b/providers/azure/services/compute/client.go index 6ef720dcd..8088098b4 100644 --- a/providers/azure/services/compute/client.go +++ b/providers/azure/services/compute/client.go @@ -170,6 +170,8 @@ type AzureRetailPriceItem struct { Type string `json:"type"` } +// AzureRetailPrice is the paginated response envelope returned by the Azure +// Retail Prices API; NextPageLink is non-empty when additional pages exist. type AzureRetailPrice struct { Items []AzureRetailPriceItem `json:"Items"` NextPageLink string `json:"NextPageLink"` From dc264a95e09560e16bafea416c8c49af7a58786e Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Sat, 30 May 2026 21:37:12 +0200 Subject: [PATCH 2/2] docs: tighten doc accuracy and cover Report methods (refs #619) Three small follow-up tweaks to the docstring backfill: - clear-rate-limit/main.go: Response.RemainingCount counts ALL rate-limit rows, not only forgot_password rows; reword the doc to match. - internal/api/types.go: replace the colloquial "extends UserInfo" wording on User with an explicit field-level description and a callout that User is reserved for admin endpoints (LoginResponse/CurrentUserResponse use UserInfo / its own type). - ci_cd_sanity_tests/pkg/sanity/report: document the exported Add, HasFailures, and WriteJSON methods; Add notes the not-safe-for-concurrent use contract that current callers rely on. --- ci_cd_sanity_tests/pkg/sanity/report/report.go | 6 ++++++ cmd/lambda/clear-rate-limit/main.go | 3 ++- internal/api/types.go | 6 ++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ci_cd_sanity_tests/pkg/sanity/report/report.go b/ci_cd_sanity_tests/pkg/sanity/report/report.go index ed708e27e..afe22fe88 100644 --- a/ci_cd_sanity_tests/pkg/sanity/report/report.go +++ b/ci_cd_sanity_tests/pkg/sanity/report/report.go @@ -38,10 +38,14 @@ type Report struct { Results []CheckResult `json:"results"` } +// Add appends a single check result to the report. Not safe for concurrent +// use; callers running checks in goroutines must serialise Add calls. func (r *Report) Add(res CheckResult) { r.Results = append(r.Results, res) } +// HasFailures reports whether any recorded check ended in StatusFail. Skips +// and passes do not count as failures. func (r *Report) HasFailures() bool { for _, rr := range r.Results { if rr.Status == StatusFail { @@ -51,6 +55,8 @@ func (r *Report) HasFailures() bool { return false } +// WriteJSON serialises the report to path with indented JSON and 0600 +// permissions so it can be uploaded as a CI artefact. func (r *Report) WriteJSON(path string) error { b, err := json.MarshalIndent(r, "", " ") if err != nil { diff --git a/cmd/lambda/clear-rate-limit/main.go b/cmd/lambda/clear-rate-limit/main.go index deff15f8e..ff2ed891b 100644 --- a/cmd/lambda/clear-rate-limit/main.go +++ b/cmd/lambda/clear-rate-limit/main.go @@ -20,7 +20,8 @@ func getDomain() string { } // Response is the Lambda function's return value, reporting how many -// forgot_password rate-limit rows were deleted and how many remain. +// forgot_password rate-limit rows were deleted and how many rate-limit +// rows (across all endpoints) remain in the table. type Response struct { Message string `json:"message"` DeletedCount int `json:"deleted_count"` diff --git a/internal/api/types.go b/internal/api/types.go index 236262d22..75738c361 100644 --- a/internal/api/types.go +++ b/internal/api/types.go @@ -288,8 +288,10 @@ type Session struct { UserAPIKeyID string `json:"-"` } -// User is the full user record returned by admin endpoints; it extends UserInfo -// with audit timestamps and is never embedded in public-facing auth responses. +// User is the full user record returned by the admin user-management endpoints. +// It mirrors UserInfo's identity fields and adds CreatedAt/UpdatedAt audit +// timestamps; it is never embedded in the public-facing login or session +// responses, which use the slimmer UserInfo / CurrentUserResponse types instead. type User struct { ID string `json:"id"` Email string `json:"email"`