cloud

package
v0.7.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 7, 2026 License: MIT Imports: 32 Imported by: 0

Documentation

Index

Constants

View Source
const (
	FreeLLMLimit = 50
	ProLLMLimit  = 1000
)

Plan tier limits for LLM calls per month.

Variables

View Source
var Version = "0.1.0-dev"

Version is set at build time via ldflags.

Functions

func AuthMiddleware

func AuthMiddleware(store Store, jwtSecret string, logger *slog.Logger) func(http.Handler) http.Handler

AuthMiddleware validates authentication via JWT cookie or API key Bearer token. JWT cookie is tried first (dashboard auth), then API key (CLI auth). Requests to public endpoints bypass auth entirely.

func CORSMiddleware

func CORSMiddleware(next http.Handler) http.Handler

CORSMiddleware adds CORS headers. For same-origin dashboard requests (cookie auth), CORS is not needed. These headers support CLI access from any origin.

func ClearAuthCookie

func ClearAuthCookie(w http.ResponseWriter, domain string, secure bool)

ClearAuthCookie removes the auth cookie.

func DeliverWebhook added in v0.7.0

func DeliverWebhook(wh *OrgWebhook, payload WebhookPayload, logger *slog.Logger)

DeliverWebhook signs the payload with HMAC-SHA256 and sends it to the webhook URL. Retries up to 3 times with exponential backoff on non-2xx responses.

func GenerateJWT

func GenerateJWT(userID, email, secret string, expiry time.Duration) (string, error)

GenerateJWT creates a signed HMAC-SHA256 JWT token.

func GenerateRawAPIKey

func GenerateRawAPIKey() (string, error)

GenerateRawAPIKey creates a new random API key with the fk_ prefix.

func GetGoogleAuthURL

func GetGoogleAuthURL(clientID, redirectURI, state string) string

GetGoogleAuthURL constructs the Google OAuth authorization URL.

func GetTokenFromCookie

func GetTokenFromCookie(r *http.Request) string

GetTokenFromCookie extracts the JWT token from the request cookie.

func HashAPIKey

func HashAPIKey(raw string) string

HashAPIKey computes the SHA-256 hash of a raw API key.

func RequestLogger

func RequestLogger(logger *slog.Logger) func(http.Handler) http.Handler

RequestLogger is middleware that logs each incoming request with method, path, status code, and duration.

func SetAuthCookie

func SetAuthCookie(w http.ResponseWriter, token, domain string, secure bool)

SetAuthCookie sets the JWT token as an httpOnly cookie.

func UsageLimitsMiddleware

func UsageLimitsMiddleware(engine *limits.Engine, logger *slog.Logger) func(http.Handler) http.Handler

UsageLimitsMiddleware checks the limits engine before allowing requests to analysis endpoints. Returns 429 with rate limit headers when usage is exceeded.

Types

type AddMemberRequest added in v0.7.0

type AddMemberRequest struct {
	Email string `json:"email"`
	Role  string `json:"role"`
}

AddMemberRequest is the payload for adding an org member.

type AnalyzeConfidenceRequest

type AnalyzeConfidenceRequest struct {
	Diff     string `json:"diff"`
	Language string `json:"language,omitempty"`
}

AnalyzeConfidenceRequest is the payload for the confidence analysis endpoint.

type AnalyzeResponse

type AnalyzeResponse struct {
	Result      json.RawMessage `json:"result"`
	TokensInput int64           `json:"tokens_input"`
	TokensOut   int64           `json:"tokens_output"`
}

AnalyzeResponse is returned by both analysis endpoints.

type AnalyzeSpecRequest

type AnalyzeSpecRequest struct {
	Diff      string `json:"diff"`
	Spec      string `json:"spec"`
	Language  string `json:"language,omitempty"`
	SpecTitle string `json:"spec_title,omitempty"`
}

AnalyzeSpecRequest is the payload for the spec comparison endpoint.

type AuditEntry added in v0.7.0

type AuditEntry struct {
	ID           string          `json:"id"`
	OrgID        string          `json:"org_id"`
	UserID       string          `json:"user_id"`
	Action       string          `json:"action"`
	ResourceType string          `json:"resource_type"`
	ResourceID   string          `json:"resource_id"`
	Details      json.RawMessage `json:"details"`
	CreatedAt    time.Time       `json:"created_at"`
	UserEmail    string          `json:"user_email,omitempty"`
}

AuditEntry represents a single entry in the audit log.

type AuthHandlers

type AuthHandlers struct {
	// contains filtered or unexported fields
}

AuthHandlers holds dependencies for authentication handlers.

func NewAuthHandlers

func NewAuthHandlers(store Store, logger *slog.Logger, clientID, clientSecret, jwtSecret, baseURL, cookieDomain string, cookieSecure bool, allowedEmails []string) *AuthHandlers

NewAuthHandlers creates auth handlers.

func (*AuthHandlers) HandleAuthMe

func (ah *AuthHandlers) HandleAuthMe(w http.ResponseWriter, r *http.Request)

HandleAuthMe returns the current authenticated user (if any). This is a public endpoint — returns {"user": null} when not authenticated.

func (*AuthHandlers) HandleGoogleCallback

func (ah *AuthHandlers) HandleGoogleCallback(w http.ResponseWriter, r *http.Request)

HandleGoogleCallback handles the OAuth callback from Google.

func (*AuthHandlers) HandleGoogleLogin

func (ah *AuthHandlers) HandleGoogleLogin(w http.ResponseWriter, r *http.Request)

HandleGoogleLogin redirects the user to Google's OAuth consent page.

func (*AuthHandlers) HandleLogout

func (ah *AuthHandlers) HandleLogout(w http.ResponseWriter, r *http.Request)

HandleLogout clears the auth cookie.

type BillingHandlers

type BillingHandlers struct {
	// contains filtered or unexported fields
}

BillingHandlers holds dependencies for billing-related HTTP handlers.

func NewBillingHandlers

func NewBillingHandlers(
	store Store,
	stripeClient *magmastripe.Client,
	limitsEngine *limits.Engine,
	webhookHandler *magmastripe.WebhookHandler,
	prices map[string]string,
	appURL string,
	logger *slog.Logger,
) *BillingHandlers

NewBillingHandlers creates a new BillingHandlers.

func (*BillingHandlers) HandleCheckout

func (bh *BillingHandlers) HandleCheckout(w http.ResponseWriter, r *http.Request)

HandleCheckout creates a Stripe checkout session for plan upgrade.

func (*BillingHandlers) HandlePortal

func (bh *BillingHandlers) HandlePortal(w http.ResponseWriter, r *http.Request)

HandlePortal creates a Stripe billing portal session.

func (*BillingHandlers) HandleSubscription

func (bh *BillingHandlers) HandleSubscription(w http.ResponseWriter, r *http.Request)

HandleSubscription returns the current subscription status and usage.

func (*BillingHandlers) HandleWebhook

func (bh *BillingHandlers) HandleWebhook(w http.ResponseWriter, r *http.Request)

HandleWebhook proxies Stripe webhook events to the magma WebhookHandler.

type CheckoutRequest

type CheckoutRequest struct {
	Plan string `json:"plan"` // "pro" or "team"
}

CheckoutRequest is the payload for creating a checkout session.

type CheckoutResponse

type CheckoutResponse struct {
	CheckoutURL string `json:"checkout_url"`
}

CheckoutResponse is returned with the Stripe checkout URL.

type Claims

type Claims struct {
	Sub   string `json:"sub"`
	Email string `json:"email"`
	Exp   int64  `json:"exp"`
	Iat   int64  `json:"iat"`
}

Claims represents the JWT payload.

func ValidateJWT

func ValidateJWT(tokenStr, secret string) (*Claims, error)

ValidateJWT verifies a JWT token and returns its claims.

type Config

type Config struct {
	Port        string
	DatabaseURL string
	LogLevel    string

	// Google OAuth
	GoogleClientID     string
	GoogleClientSecret string
	JWTSecret          string
	CookieDomain       string
	CookieSecure       bool
	AllowedEmails      []string

	// Stripe billing (optional — billing disabled if StripeSecretKey is empty)
	StripeSecretKey     string
	StripeWebhookSecret string
	StripePriceIDPro    string
	StripePriceIDTeam   string
	AppURL              string

	// Web dashboard directory (optional — SPA serving disabled if empty)
	WebDir string
}

Config holds configuration for the cloud API server.

func ConfigFromEnv

func ConfigFromEnv() Config

ConfigFromEnv loads server configuration from environment variables.

type CreateOrgRequest added in v0.7.0

type CreateOrgRequest struct {
	Name string `json:"name"`
	Slug string `json:"slug"`
}

CreateOrgRequest is the payload for creating an organization.

type CreateRunRequest

type CreateRunRequest struct {
	RepoURL         string          `json:"repo_url"`
	Branch          string          `json:"branch"`
	CommitSHA       string          `json:"commit_sha"`
	CommitRange     string          `json:"commit_range"`
	Mode            string          `json:"mode"`
	DurationMs      int             `json:"duration_ms"`
	FilesChanged    int             `json:"files_changed"`
	Errors          int             `json:"errors"`
	Warnings        int             `json:"warnings"`
	Infos           int             `json:"infos"`
	TotalIssues     int             `json:"total_issues"`
	Issues          json.RawMessage `json:"issues"`
	ConfidenceScore *float64        `json:"confidence_score,omitempty"`
	Summary         string          `json:"summary"`
	Metadata        json.RawMessage `json:"metadata,omitempty"`
	OrgID           string          `json:"org_id,omitempty"`
}

CreateRunRequest is the payload for uploading an audit run.

type CreateRunResponse

type CreateRunResponse struct {
	ID        string    `json:"id"`
	CreatedAt time.Time `json:"created_at"`
}

CreateRunResponse is returned after creating a run.

type CreateWebhookRequest added in v0.7.0

type CreateWebhookRequest struct {
	URL    string   `json:"url"`
	Secret string   `json:"secret"`
	Events []string `json:"events"`
}

CreateWebhookRequest is the payload for creating a webhook.

type FaultPlanProvider

type FaultPlanProvider struct {
	// contains filtered or unexported fields
}

FaultPlanProvider implements magma's limits.PlanProvider by looking up the user's plan from the store and mapping it to a SimplePlan with LLM call limits.

func NewFaultPlanProvider

func NewFaultPlanProvider(store Store) *FaultPlanProvider

NewFaultPlanProvider creates a new plan provider wrapping the given store.

func (*FaultPlanProvider) GetPlan

func (p *FaultPlanProvider) GetPlan(entityID string) limits.Plan

GetPlan returns the plan for the given user ID.

type FaultWebhookCallbacks

type FaultWebhookCallbacks struct {
	// contains filtered or unexported fields
}

FaultWebhookCallbacks implements the magma stripe.WebhookCallbacks interface to handle Stripe subscription lifecycle events.

func NewFaultWebhookCallbacks

func NewFaultWebhookCallbacks(store Store, prices map[string]string, logger *slog.Logger) *FaultWebhookCallbacks

NewFaultWebhookCallbacks creates webhook callbacks with a reversed price map (priceID → planName) for mapping Stripe events back to plan names.

func (*FaultWebhookCallbacks) OnPaymentFailed

func (cb *FaultWebhookCallbacks) OnPaymentFailed(ctx context.Context, invoice *stripe.Invoice) error

OnPaymentFailed logs failed payments.

func (*FaultWebhookCallbacks) OnPaymentSucceeded

func (cb *FaultWebhookCallbacks) OnPaymentSucceeded(ctx context.Context, invoice *stripe.Invoice) error

OnPaymentSucceeded logs successful payments.

func (*FaultWebhookCallbacks) OnSubscriptionCreated

func (cb *FaultWebhookCallbacks) OnSubscriptionCreated(ctx context.Context, sub *stripe.Subscription) error

OnSubscriptionCreated handles new subscription creation from Stripe.

func (*FaultWebhookCallbacks) OnSubscriptionDeleted

func (cb *FaultWebhookCallbacks) OnSubscriptionDeleted(ctx context.Context, sub *stripe.Subscription) error

OnSubscriptionDeleted handles subscription cancellation.

func (*FaultWebhookCallbacks) OnSubscriptionUpdated

func (cb *FaultWebhookCallbacks) OnSubscriptionUpdated(ctx context.Context, sub *stripe.Subscription) error

OnSubscriptionUpdated handles subscription changes (plan, status, period).

type GetOrgConfigResponse added in v0.7.0

type GetOrgConfigResponse struct {
	ConfigYAML string `json:"config_yaml"`
	Version    int    `json:"version"`
	UpdatedBy  string `json:"updated_by,omitempty"`
	UpdatedAt  string `json:"updated_at,omitempty"`
}

GetOrgConfigResponse is returned by the get org config endpoint.

type GoogleTokenResponse

type GoogleTokenResponse struct {
	AccessToken string `json:"access_token"`
	TokenType   string `json:"token_type"`
	ExpiresIn   int    `json:"expires_in"`
}

GoogleTokenResponse is the response from Google's token endpoint.

func ExchangeGoogleCode

func ExchangeGoogleCode(ctx context.Context, clientID, clientSecret, code, redirectURI string) (*GoogleTokenResponse, error)

ExchangeGoogleCode exchanges an authorization code for an access token.

type GoogleUserInfo

type GoogleUserInfo struct {
	ID         string `json:"id"`
	Email      string `json:"email"`
	Name       string `json:"name"`
	PictureURL string `json:"picture"`
}

GoogleUserInfo represents the user info returned by Google.

func GetGoogleUserInfo

func GetGoogleUserInfo(ctx context.Context, accessToken string) (*GoogleUserInfo, error)

GetGoogleUserInfo fetches the user's profile from Google.

type Handlers

type Handlers struct {
	// contains filtered or unexported fields
}

Handlers holds dependencies for HTTP route handlers.

func NewHandlers

func NewHandlers(store Store, limitsEngine *limits.Engine, logger *slog.Logger) *Handlers

NewHandlers creates a new Handlers with the given store, limits engine, and logger.

func (*Handlers) HandleAddOrgMember added in v0.7.0

func (h *Handlers) HandleAddOrgMember(w http.ResponseWriter, r *http.Request)

HandleAddOrgMember adds a user to the organization by email.

func (*Handlers) HandleAnalyzeConfidence

func (h *Handlers) HandleAnalyzeConfidence(w http.ResponseWriter, r *http.Request)

HandleAnalyzeConfidence proxies a confidence analysis request to the Anthropic API.

func (*Handlers) HandleAnalyzeSpec

func (h *Handlers) HandleAnalyzeSpec(w http.ResponseWriter, r *http.Request)

HandleAnalyzeSpec proxies a spec comparison request to the Anthropic API.

func (*Handlers) HandleAnalyzeSpecStructured

func (h *Handlers) HandleAnalyzeSpecStructured(w http.ResponseWriter, r *http.Request)

HandleAnalyzeSpecStructured proxies a structured per-requirement spec comparison to the Anthropic API.

func (*Handlers) HandleCreateOrg added in v0.7.0

func (h *Handlers) HandleCreateOrg(w http.ResponseWriter, r *http.Request)

HandleCreateOrg creates a new organization.

func (*Handlers) HandleCreateRun

func (h *Handlers) HandleCreateRun(w http.ResponseWriter, r *http.Request)

HandleCreateRun accepts an uploaded audit run result.

func (*Handlers) HandleCreateWebhook added in v0.7.0

func (h *Handlers) HandleCreateWebhook(w http.ResponseWriter, r *http.Request)

HandleCreateWebhook creates a new webhook for an organization.

func (*Handlers) HandleDeleteOIDCConfig added in v0.7.0

func (h *Handlers) HandleDeleteOIDCConfig(w http.ResponseWriter, r *http.Request)

HandleDeleteOIDCConfig deletes the OIDC IdP configuration for an organization. Requires owner or admin role.

func (*Handlers) HandleDeleteWebhook added in v0.7.0

func (h *Handlers) HandleDeleteWebhook(w http.ResponseWriter, r *http.Request)

HandleDeleteWebhook removes a webhook from an organization.

func (*Handlers) HandleGetOIDCConfig added in v0.7.0

func (h *Handlers) HandleGetOIDCConfig(w http.ResponseWriter, r *http.Request)

HandleGetOIDCConfig returns the OIDC IdP configuration for an organization. The client_secret is masked.

func (*Handlers) HandleGetOrg added in v0.7.0

func (h *Handlers) HandleGetOrg(w http.ResponseWriter, r *http.Request)

HandleGetOrg returns organization details with member count.

func (*Handlers) HandleGetOrgConfig added in v0.7.0

func (h *Handlers) HandleGetOrgConfig(w http.ResponseWriter, r *http.Request)

HandleGetOrgConfig returns the organization's shared config.

func (*Handlers) HandleGetOrgRunStats added in v0.7.0

func (h *Handlers) HandleGetOrgRunStats(w http.ResponseWriter, r *http.Request)

HandleGetOrgRunStats returns aggregate run statistics for the organization.

func (*Handlers) HandleGetRun

func (h *Handlers) HandleGetRun(w http.ResponseWriter, r *http.Request)

HandleGetRun returns a single run by ID.

func (*Handlers) HandleGetRunStats

func (h *Handlers) HandleGetRunStats(w http.ResponseWriter, r *http.Request)

HandleGetRunStats returns aggregate run statistics for the authenticated user.

func (*Handlers) HandleHealth

func (h *Handlers) HandleHealth(w http.ResponseWriter, r *http.Request)

HandleHealth returns the health check response.

func (*Handlers) HandleListAuditEntries added in v0.7.0

func (h *Handlers) HandleListAuditEntries(w http.ResponseWriter, r *http.Request)

HandleListAuditEntries returns the audit log for the organization.

func (*Handlers) HandleListOrgMembers added in v0.7.0

func (h *Handlers) HandleListOrgMembers(w http.ResponseWriter, r *http.Request)

HandleListOrgMembers returns all members of the organization.

func (*Handlers) HandleListOrgRuns added in v0.7.0

func (h *Handlers) HandleListOrgRuns(w http.ResponseWriter, r *http.Request)

HandleListOrgRuns returns paginated runs for the organization.

func (*Handlers) HandleListOrgs added in v0.7.0

func (h *Handlers) HandleListOrgs(w http.ResponseWriter, r *http.Request)

HandleListOrgs returns the authenticated user's organizations.

func (*Handlers) HandleListRuns

func (h *Handlers) HandleListRuns(w http.ResponseWriter, r *http.Request)

HandleListRuns returns paginated runs for the authenticated user.

func (*Handlers) HandleListSpecResults

func (h *Handlers) HandleListSpecResults(w http.ResponseWriter, r *http.Request)

HandleListSpecResults returns paginated spec validation results for the authenticated user.

func (*Handlers) HandleListWebhooks added in v0.7.0

func (h *Handlers) HandleListWebhooks(w http.ResponseWriter, r *http.Request)

HandleListWebhooks returns all webhooks for an organization.

func (*Handlers) HandlePullOrgConfig added in v0.7.0

func (h *Handlers) HandlePullOrgConfig(w http.ResponseWriter, r *http.Request)

HandlePullOrgConfig returns the org config as raw YAML (for CLI consumption).

func (*Handlers) HandleRemoveOrgMember added in v0.7.0

func (h *Handlers) HandleRemoveOrgMember(w http.ResponseWriter, r *http.Request)

HandleRemoveOrgMember removes a user from the organization.

func (*Handlers) HandleRotateKey

func (h *Handlers) HandleRotateKey(w http.ResponseWriter, r *http.Request)

HandleRotateKey generates a new API key for the authenticated user, invalidating the old one. The new key is only shown once.

func (*Handlers) HandleSaveOIDCConfig added in v0.7.0

func (h *Handlers) HandleSaveOIDCConfig(w http.ResponseWriter, r *http.Request)

HandleSaveOIDCConfig saves the OIDC IdP configuration for an organization. Requires owner or admin role.

func (*Handlers) HandleSaveOrgConfig added in v0.7.0

func (h *Handlers) HandleSaveOrgConfig(w http.ResponseWriter, r *http.Request)

HandleSaveOrgConfig saves the organization's shared config.

func (*Handlers) HandleSignup

func (h *Handlers) HandleSignup(w http.ResponseWriter, r *http.Request)

HandleSignup creates a new user and returns their API key. If the user already exists, a new key is generated (old key is invalidated).

func (*Handlers) HandleUsage

func (h *Handlers) HandleUsage(w http.ResponseWriter, r *http.Request)

HandleUsage returns the current month's usage for the authenticated user.

type HealthResponse

type HealthResponse struct {
	Status  string `json:"status"`
	Version string `json:"version"`
}

HealthResponse is returned by the health check endpoint.

type LimitsStorageAdapter

type LimitsStorageAdapter struct {
	// contains filtered or unexported fields
}

LimitsStorageAdapter wraps the cloud Store to satisfy magma's limits.Storage interface. It reads from the existing usage table. IncrementUsage is a no-op because the analysis handlers already call store.IncrementUsage after each LLM call.

func NewLimitsStorageAdapter

func NewLimitsStorageAdapter(store Store) *LimitsStorageAdapter

NewLimitsStorageAdapter creates a new adapter wrapping the given store.

func (*LimitsStorageAdapter) GetUsage

func (a *LimitsStorageAdapter) GetUsage(ctx context.Context, entityID string) (*models.Usage, error)

GetUsage returns the current month's usage as a magma Usage struct.

func (*LimitsStorageAdapter) IncrementUsage

func (a *LimitsStorageAdapter) IncrementUsage(ctx context.Context, entityID, resource string) error

IncrementUsage is a no-op. The analysis handlers already track usage via store.IncrementUsage after each successful LLM call.

type ListAuditResponse added in v0.7.0

type ListAuditResponse struct {
	Entries []AuditEntry `json:"entries"`
	Total   int          `json:"total"`
	Limit   int          `json:"limit"`
	Offset  int          `json:"offset"`
}

ListAuditResponse is returned by the audit log listing endpoint.

type ListOrgRunsResponse added in v0.7.0

type ListOrgRunsResponse struct {
	Runs   []Run `json:"runs"`
	Total  int   `json:"total"`
	Limit  int   `json:"limit"`
	Offset int   `json:"offset"`
}

ListOrgRunsResponse is returned by the org runs listing endpoint.

type ListRunsResponse

type ListRunsResponse struct {
	Runs   []Run `json:"runs"`
	Total  int   `json:"total"`
	Limit  int   `json:"limit"`
	Offset int   `json:"offset"`
}

ListRunsResponse is returned by the list runs endpoint.

type ListSpecResultsResponse

type ListSpecResultsResponse struct {
	Results []SpecResult `json:"results"`
	Total   int          `json:"total"`
	Limit   int          `json:"limit"`
	Offset  int          `json:"offset"`
}

ListSpecResultsResponse is returned by the spec results listing endpoint.

type MonthlyUsage

type MonthlyUsage struct {
	UserID       string `json:"user_id"`
	Month        string `json:"month"` // YYYY-MM
	LLMCalls     int    `json:"llm_calls"`
	TokensInput  int64  `json:"tokens_input"`
	TokensOutput int64  `json:"tokens_output"`
	Analyses     int    `json:"analyses"`
}

MonthlyUsage tracks per-user LLM usage for a given month.

type OIDCHandlers added in v0.7.0

type OIDCHandlers struct {
	// contains filtered or unexported fields
}

OIDCHandlers manages OIDC SSO authentication flows.

func NewOIDCHandlers added in v0.7.0

func NewOIDCHandlers(store Store, logger *slog.Logger, jwtSecret, appURL, cookieDomain string, cookieSecure bool) *OIDCHandlers

NewOIDCHandlers creates a new OIDCHandlers.

func (*OIDCHandlers) HandleOIDCCallback added in v0.7.0

func (oh *OIDCHandlers) HandleOIDCCallback(w http.ResponseWriter, r *http.Request)

HandleOIDCCallback handles the OIDC callback after IdP authentication.

func (*OIDCHandlers) HandleOIDCLogin added in v0.7.0

func (oh *OIDCHandlers) HandleOIDCLogin(w http.ResponseWriter, r *http.Request)

HandleOIDCLogin starts the OIDC login flow for an organization.

type OIDCState added in v0.7.0

type OIDCState struct {
	OrgSlug   string
	ExpiresAt time.Time
	Nonce     string
}

OIDCState holds state for the OIDC login flow.

type OrgConfig added in v0.7.0

type OrgConfig struct {
	ID         string    `json:"id"`
	OrgID      string    `json:"org_id"`
	ConfigYAML string    `json:"config_yaml"`
	Version    int       `json:"version"`
	UpdatedBy  string    `json:"updated_by"`
	CreatedAt  time.Time `json:"created_at"`
	UpdatedAt  time.Time `json:"updated_at"`
}

OrgConfig represents an organization's shared configuration.

type OrgDetailResponse added in v0.7.0

type OrgDetailResponse struct {
	Organization
	MemberCount int `json:"member_count"`
}

OrgDetailResponse is returned by the get org endpoint.

type OrgIDPConfig added in v0.7.0

type OrgIDPConfig struct {
	ID           string    `json:"id"`
	OrgID        string    `json:"org_id"`
	Provider     string    `json:"provider"`
	ClientID     string    `json:"client_id"`
	ClientSecret string    `json:"-"`
	DiscoveryURL string    `json:"discovery_url"`
	CreatedAt    time.Time `json:"created_at"`
	UpdatedAt    time.Time `json:"updated_at"`
}

OrgIDPConfig represents an organization's OIDC identity provider configuration.

type OrgMember added in v0.7.0

type OrgMember struct {
	ID        string    `json:"id"`
	OrgID     string    `json:"org_id"`
	UserID    string    `json:"user_id"`
	Role      string    `json:"role"` // owner, admin, member
	CreatedAt time.Time `json:"created_at"`
	Email     string    `json:"email,omitempty"` // populated from join
	Name      string    `json:"name,omitempty"`  // populated from join
}

OrgMember represents a user's membership in an organization.

type OrgWebhook added in v0.7.0

type OrgWebhook struct {
	ID        string    `json:"id"`
	OrgID     string    `json:"org_id"`
	URL       string    `json:"url"`
	Secret    string    `json:"-"`
	Events    []string  `json:"events"`
	Active    bool      `json:"active"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

OrgWebhook represents a webhook configuration for an organization.

type Organization added in v0.7.0

type Organization struct {
	ID        string    `json:"id"`
	Name      string    `json:"name"`
	Slug      string    `json:"slug"`
	OwnerID   string    `json:"owner_id"`
	Plan      string    `json:"plan"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

Organization represents a team organization.

type PortalResponse

type PortalResponse struct {
	PortalURL string `json:"portal_url"`
}

PortalResponse is returned with the Stripe billing portal URL.

type PostgresStore

type PostgresStore struct {
	// contains filtered or unexported fields
}

PostgresStore implements Store using PostgreSQL via pgx.

func NewPostgresStore

func NewPostgresStore(ctx context.Context, databaseURL string) (*PostgresStore, error)

NewPostgresStore creates a new PostgresStore connected to the given database URL.

func (*PostgresStore) AddOrgMember added in v0.7.0

func (s *PostgresStore) AddOrgMember(ctx context.Context, orgID, userID, role string) error

AddOrgMember adds a user to an organization with the given role.

func (*PostgresStore) Close

func (s *PostgresStore) Close()

Close releases the database connection pool.

func (*PostgresStore) CreateOrganization added in v0.7.0

func (s *PostgresStore) CreateOrganization(ctx context.Context, org *Organization) error

CreateOrganization inserts a new organization.

func (*PostgresStore) CreateRun

func (s *PostgresStore) CreateRun(ctx context.Context, run *Run) error

CreateRun inserts a new audit run record.

func (*PostgresStore) CreateUser

func (s *PostgresStore) CreateUser(ctx context.Context, email string) (*User, error)

CreateUser inserts a new user with the given email address.

func (*PostgresStore) CreateUserFromGoogle

func (s *PostgresStore) CreateUserFromGoogle(ctx context.Context, email, googleID, name, pictureURL string) (*User, error)

CreateUserFromGoogle creates a new user from Google OAuth info.

func (*PostgresStore) CreateWebhook added in v0.7.0

func (s *PostgresStore) CreateWebhook(ctx context.Context, wh *OrgWebhook) error

CreateWebhook inserts a new webhook for an organization.

func (*PostgresStore) DeleteOrgIDPConfig added in v0.7.0

func (s *PostgresStore) DeleteOrgIDPConfig(ctx context.Context, orgID string) error

DeleteOrgIDPConfig removes the OIDC IdP configuration for an organization.

func (*PostgresStore) DeleteWebhook added in v0.7.0

func (s *PostgresStore) DeleteWebhook(ctx context.Context, orgID, webhookID string) error

DeleteWebhook removes a webhook by ID, scoped to an organization.

func (*PostgresStore) GenerateAPIKey

func (s *PostgresStore) GenerateAPIKey(ctx context.Context, userID string) (string, error)

GenerateAPIKey creates a new API key for the given user, replacing any existing key. Returns the raw key (with fk_ prefix). Only the SHA-256 hash is stored.

func (*PostgresStore) GetOrgConfig added in v0.7.0

func (s *PostgresStore) GetOrgConfig(ctx context.Context, orgID string) (*OrgConfig, error)

func (*PostgresStore) GetOrgIDPConfig added in v0.7.0

func (s *PostgresStore) GetOrgIDPConfig(ctx context.Context, orgID string) (*OrgIDPConfig, error)

GetOrgIDPConfig retrieves the OIDC IdP configuration for an organization.

func (*PostgresStore) GetOrgMembership added in v0.7.0

func (s *PostgresStore) GetOrgMembership(ctx context.Context, orgID, userID string) (*OrgMember, error)

GetOrgMembership returns a user's membership in an organization, or nil if not a member.

func (*PostgresStore) GetOrgRunStats added in v0.7.0

func (s *PostgresStore) GetOrgRunStats(ctx context.Context, orgID string) (*RunStats, error)

GetOrgRunStats returns aggregate statistics for an organization's runs.

func (*PostgresStore) GetOrganization added in v0.7.0

func (s *PostgresStore) GetOrganization(ctx context.Context, orgID string) (*Organization, error)

GetOrganization retrieves an organization by ID.

func (*PostgresStore) GetOrganizationBySlug added in v0.7.0

func (s *PostgresStore) GetOrganizationBySlug(ctx context.Context, slug string) (*Organization, error)

GetOrganizationBySlug retrieves an organization by its unique slug.

func (*PostgresStore) GetRun

func (s *PostgresStore) GetRun(ctx context.Context, userID, runID string) (*Run, error)

GetRun retrieves a single run by ID for a given user.

func (*PostgresStore) GetRunStats

func (s *PostgresStore) GetRunStats(ctx context.Context, userID string) (*RunStats, error)

GetRunStats returns aggregate statistics for a user's runs.

func (*PostgresStore) GetSpecResults

func (s *PostgresStore) GetSpecResults(ctx context.Context, userID string, limit, offset int) ([]SpecResult, error)

GetSpecResults returns recent spec validation results for a user.

func (*PostgresStore) GetSubscriptionByUserID

func (s *PostgresStore) GetSubscriptionByUserID(ctx context.Context, userID string) (*Subscription, error)

GetSubscriptionByUserID returns the most recent subscription for a user. Returns nil, nil if not found.

func (*PostgresStore) GetUsage

func (s *PostgresStore) GetUsage(ctx context.Context, userID string, month string) (*MonthlyUsage, error)

GetUsage returns usage data for a user in the specified month (YYYY-MM format). Returns zero-value usage if no data exists for that month.

func (*PostgresStore) GetUserByAPIKeyHash

func (s *PostgresStore) GetUserByAPIKeyHash(ctx context.Context, hash string) (*User, error)

GetUserByAPIKeyHash looks up a user by the SHA-256 hash of their API key.

func (*PostgresStore) GetUserByEmail

func (s *PostgresStore) GetUserByEmail(ctx context.Context, email string) (*User, error)

GetUserByEmail looks up a user by email address. Returns nil, nil if not found.

func (*PostgresStore) GetUserByGoogleID

func (s *PostgresStore) GetUserByGoogleID(ctx context.Context, googleID string) (*User, error)

GetUserByGoogleID looks up a user by their Google ID. Returns nil, nil if not found.

func (*PostgresStore) GetUserByID

func (s *PostgresStore) GetUserByID(ctx context.Context, userID string) (*User, error)

GetUserByID looks up a user by their internal ID.

func (*PostgresStore) GetUserByStripeCustomerID

func (s *PostgresStore) GetUserByStripeCustomerID(ctx context.Context, customerID string) (*User, error)

GetUserByStripeCustomerID looks up a user by their Stripe customer ID. Returns nil, nil if not found.

func (*PostgresStore) IncrementUsage

func (s *PostgresStore) IncrementUsage(ctx context.Context, userID string, tokens Usage) error

IncrementUsage adds token counts and increments the call/analysis counters for the current month. Creates the usage row if it does not exist.

func (*PostgresStore) InsertAuditEntry added in v0.7.0

func (s *PostgresStore) InsertAuditEntry(ctx context.Context, entry *AuditEntry) error

InsertAuditEntry inserts a new audit log entry.

func (*PostgresStore) ListAuditEntries added in v0.7.0

func (s *PostgresStore) ListAuditEntries(ctx context.Context, orgID string, limit, offset int) ([]AuditEntry, error)

ListAuditEntries returns audit log entries for an organization, ordered by most recent first.

func (*PostgresStore) ListOrgMembers added in v0.7.0

func (s *PostgresStore) ListOrgMembers(ctx context.Context, orgID string) ([]OrgMember, error)

ListOrgMembers returns all members of an organization with their user details.

func (*PostgresStore) ListOrgRuns added in v0.7.0

func (s *PostgresStore) ListOrgRuns(ctx context.Context, orgID string, limit, offset int) ([]Run, error)

ListOrgRuns returns recent runs for an organization, ordered by timestamp descending.

func (*PostgresStore) ListRuns

func (s *PostgresStore) ListRuns(ctx context.Context, userID string, limit, offset int) ([]Run, error)

ListRuns returns recent runs for a user, ordered by timestamp descending.

func (*PostgresStore) ListUserOrganizations added in v0.7.0

func (s *PostgresStore) ListUserOrganizations(ctx context.Context, userID string) ([]Organization, error)

ListUserOrganizations returns all organizations a user belongs to.

func (*PostgresStore) ListWebhooks added in v0.7.0

func (s *PostgresStore) ListWebhooks(ctx context.Context, orgID string) ([]OrgWebhook, error)

ListWebhooks returns all webhooks for an organization.

func (*PostgresStore) Migrate

func (s *PostgresStore) Migrate(ctx context.Context) error

Migrate runs database migrations. Safe to call on every startup since the DDL uses IF NOT EXISTS.

func (*PostgresStore) RemoveOrgMember added in v0.7.0

func (s *PostgresStore) RemoveOrgMember(ctx context.Context, orgID, userID string) error

RemoveOrgMember removes a user from an organization.

func (*PostgresStore) SaveOrgConfig added in v0.7.0

func (s *PostgresStore) SaveOrgConfig(ctx context.Context, cfg *OrgConfig) error

func (*PostgresStore) SaveOrgIDPConfig added in v0.7.0

func (s *PostgresStore) SaveOrgIDPConfig(ctx context.Context, cfg *OrgIDPConfig) error

SaveOrgIDPConfig upserts an OIDC IdP configuration for an organization.

func (*PostgresStore) SaveSpecResult

func (s *PostgresStore) SaveSpecResult(ctx context.Context, result *SpecResult) error

SaveSpecResult inserts a new spec validation result.

func (*PostgresStore) SetGoogleID

func (s *PostgresStore) SetGoogleID(ctx context.Context, userID, googleID string) error

SetGoogleID sets the Google ID on a user (for linking existing API key users).

func (*PostgresStore) SetStripeCustomerID

func (s *PostgresStore) SetStripeCustomerID(ctx context.Context, userID string, customerID string) error

SetStripeCustomerID sets the Stripe customer ID on a user.

func (*PostgresStore) UpdateUserPlan

func (s *PostgresStore) UpdateUserPlan(ctx context.Context, userID string, plan string) error

UpdateUserPlan sets the plan field on a user.

func (*PostgresStore) UpdateUserProfile

func (s *PostgresStore) UpdateUserProfile(ctx context.Context, userID, name, pictureURL string) error

UpdateUserProfile updates the user's name and picture URL.

func (*PostgresStore) UpsertSubscription

func (s *PostgresStore) UpsertSubscription(ctx context.Context, sub *Subscription) error

UpsertSubscription creates or updates a subscription record.

type RotateKeyResponse

type RotateKeyResponse struct {
	APIKey string `json:"api_key"`
	Email  string `json:"email"`
}

RotateKeyResponse is returned by the key rotation endpoint.

type Run

type Run struct {
	ID              string          `json:"id"`
	UserID          string          `json:"user_id"`
	OrgID           string          `json:"org_id,omitempty"`
	RepoURL         string          `json:"repo_url"`
	Branch          string          `json:"branch"`
	CommitSHA       string          `json:"commit_sha"`
	CommitRange     string          `json:"commit_range"`
	Mode            string          `json:"mode"`
	Timestamp       time.Time       `json:"timestamp"`
	DurationMs      int             `json:"duration_ms"`
	FilesChanged    int             `json:"files_changed"`
	Errors          int             `json:"errors"`
	Warnings        int             `json:"warnings"`
	Infos           int             `json:"infos"`
	TotalIssues     int             `json:"total_issues"`
	Issues          json.RawMessage `json:"issues"`
	ConfidenceScore *float64        `json:"confidence_score,omitempty"`
	Summary         string          `json:"summary"`
	Metadata        json.RawMessage `json:"metadata"`
	CreatedAt       time.Time       `json:"created_at"`
}

Run represents a single audit run stored in the database.

type RunStats

type RunStats struct {
	TotalRuns   int     `json:"total_runs"`
	TotalIssues int     `json:"total_issues"`
	AvgErrors   float64 `json:"avg_errors"`
	AvgWarnings float64 `json:"avg_warnings"`
	AvgDuration float64 `json:"avg_duration_ms"`
}

RunStats provides aggregate statistics for a user's runs.

type SaveOIDCConfigRequest added in v0.7.0

type SaveOIDCConfigRequest struct {
	ClientID     string `json:"client_id"`
	ClientSecret string `json:"client_secret"`
	DiscoveryURL string `json:"discovery_url"`
}

SaveOIDCConfigRequest is the payload for saving an org's OIDC IdP configuration.

type SaveOrgConfigRequest added in v0.7.0

type SaveOrgConfigRequest struct {
	ConfigYAML string `json:"config_yaml"`
}

SaveOrgConfigRequest is the payload for saving org config.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the cloud API HTTP server.

func NewServer

func NewServer(cfg Config, store Store) *Server

NewServer creates a new Server with the given config and store.

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler returns the fully wrapped HTTP handler with all middleware applied.

func (*Server) Start

func (s *Server) Start() error

Start runs the HTTP server and blocks until a shutdown signal is received.

type SignupRequest

type SignupRequest struct {
	Email string `json:"email"`
}

SignupRequest is the payload for the signup endpoint.

type SignupResponse

type SignupResponse struct {
	APIKey string `json:"api_key"`
	Email  string `json:"email"`
}

SignupResponse is returned by the signup endpoint.

type SpecResult

type SpecResult struct {
	ID                string          `json:"id"`
	UserID            string          `json:"user_id"`
	SpecHash          string          `json:"spec_hash"`
	SpecTitle         string          `json:"spec_title"`
	TotalRequirements int             `json:"total_requirements"`
	AnchoredCount     int             `json:"anchored_count"`
	ImplementedCount  int             `json:"implemented_count"`
	PartialCount      int             `json:"partial_count"`
	MissingCount      int             `json:"missing_count"`
	OverallScore      float64         `json:"overall_score"`
	ResultJSON        json.RawMessage `json:"result_json"`
	CreatedAt         time.Time       `json:"created_at"`
}

SpecResult represents a stored spec validation result.

type Store

type Store interface {
	GetUserByAPIKeyHash(ctx context.Context, hash string) (*User, error)
	GetUserByEmail(ctx context.Context, email string) (*User, error)
	GetUserByID(ctx context.Context, userID string) (*User, error)
	GetUserByStripeCustomerID(ctx context.Context, customerID string) (*User, error)
	GetUserByGoogleID(ctx context.Context, googleID string) (*User, error)
	CreateUser(ctx context.Context, email string) (*User, error)
	CreateUserFromGoogle(ctx context.Context, email, googleID, name, pictureURL string) (*User, error)
	GenerateAPIKey(ctx context.Context, userID string) (string, error)
	UpdateUserPlan(ctx context.Context, userID string, plan string) error
	SetStripeCustomerID(ctx context.Context, userID string, customerID string) error
	SetGoogleID(ctx context.Context, userID, googleID string) error
	UpdateUserProfile(ctx context.Context, userID, name, pictureURL string) error
	IncrementUsage(ctx context.Context, userID string, tokens Usage) error
	GetUsage(ctx context.Context, userID string, month string) (*MonthlyUsage, error)
	UpsertSubscription(ctx context.Context, sub *Subscription) error
	GetSubscriptionByUserID(ctx context.Context, userID string) (*Subscription, error)
	CreateRun(ctx context.Context, run *Run) error
	GetRun(ctx context.Context, userID, runID string) (*Run, error)
	ListRuns(ctx context.Context, userID string, limit, offset int) ([]Run, error)
	GetRunStats(ctx context.Context, userID string) (*RunStats, error)
	SaveSpecResult(ctx context.Context, result *SpecResult) error
	GetSpecResults(ctx context.Context, userID string, limit, offset int) ([]SpecResult, error)

	// Organization methods
	CreateOrganization(ctx context.Context, org *Organization) error
	GetOrganization(ctx context.Context, orgID string) (*Organization, error)
	GetOrganizationBySlug(ctx context.Context, slug string) (*Organization, error)
	ListUserOrganizations(ctx context.Context, userID string) ([]Organization, error)
	AddOrgMember(ctx context.Context, orgID, userID, role string) error
	RemoveOrgMember(ctx context.Context, orgID, userID string) error
	ListOrgMembers(ctx context.Context, orgID string) ([]OrgMember, error)
	GetOrgMembership(ctx context.Context, orgID, userID string) (*OrgMember, error)
	ListOrgRuns(ctx context.Context, orgID string, limit, offset int) ([]Run, error)
	GetOrgRunStats(ctx context.Context, orgID string) (*RunStats, error)

	// Webhook methods
	CreateWebhook(ctx context.Context, wh *OrgWebhook) error
	ListWebhooks(ctx context.Context, orgID string) ([]OrgWebhook, error)
	DeleteWebhook(ctx context.Context, orgID, webhookID string) error

	// Org config methods
	GetOrgConfig(ctx context.Context, orgID string) (*OrgConfig, error)
	SaveOrgConfig(ctx context.Context, cfg *OrgConfig) error

	// Org IDP config methods
	GetOrgIDPConfig(ctx context.Context, orgID string) (*OrgIDPConfig, error)
	SaveOrgIDPConfig(ctx context.Context, cfg *OrgIDPConfig) error
	DeleteOrgIDPConfig(ctx context.Context, orgID string) error

	// Audit log methods
	InsertAuditEntry(ctx context.Context, entry *AuditEntry) error
	ListAuditEntries(ctx context.Context, orgID string, limit, offset int) ([]AuditEntry, error)

	Close()
}

Store defines the interface for cloud data access.

type Subscription

type Subscription struct {
	ID                   string     `json:"id"`
	UserID               string     `json:"user_id"`
	StripeSubscriptionID string     `json:"stripe_subscription_id,omitempty"`
	StripeCustomerID     string     `json:"stripe_customer_id,omitempty"`
	Plan                 string     `json:"plan"`
	Status               string     `json:"status"`
	CurrentPeriodStart   *time.Time `json:"current_period_start,omitempty"`
	CurrentPeriodEnd     *time.Time `json:"current_period_end,omitempty"`
	CreatedAt            time.Time  `json:"created_at"`
	UpdatedAt            time.Time  `json:"updated_at"`
}

Subscription tracks a Stripe subscription's state locally.

type SubscriptionResponse

type SubscriptionResponse struct {
	Plan         string `json:"plan"`
	Status       string `json:"status"`
	LLMCalls     int    `json:"llm_calls"`
	LLMLimit     int    `json:"llm_limit"`
	LLMRemaining int    `json:"llm_remaining"`
}

SubscriptionResponse is returned by the subscription status endpoint.

type Usage

type Usage struct {
	TokensInput  int64
	TokensOutput int64
}

Usage represents token counts from a single LLM call.

type UsageResponse

type UsageResponse struct {
	UserID       string `json:"user_id"`
	Email        string `json:"email"`
	Plan         string `json:"plan"`
	Month        string `json:"month"`
	LLMCalls     int    `json:"llm_calls"`
	TokensInput  int64  `json:"tokens_input"`
	TokensOutput int64  `json:"tokens_output"`
	Analyses     int    `json:"analyses"`
	LLMLimit     int    `json:"llm_limit"`
	LLMRemaining int    `json:"llm_remaining"`
}

UsageResponse is returned by the usage endpoint.

type User

type User struct {
	ID               string    `json:"id"`
	Email            string    `json:"email"`
	Plan             string    `json:"plan"` // free, pro, team
	APIKeyHash       string    `json:"-"`
	StripeCustomerID string    `json:"stripe_customer_id,omitempty"`
	GoogleID         string    `json:"google_id,omitempty"`
	Name             string    `json:"name,omitempty"`
	PictureURL       string    `json:"picture_url,omitempty"`
	CreatedAt        time.Time `json:"created_at"`
	LastActiveAt     time.Time `json:"last_active_at"`
}

User represents an authenticated API user.

func UserFromContext

func UserFromContext(ctx context.Context) *User

UserFromContext extracts the authenticated user from the request context.

type UserinfoResponse added in v0.7.0

type UserinfoResponse struct {
	Email string `json:"email"`
	Name  string `json:"name"`
}

UserinfoResponse is used to fetch user info from the OIDC userinfo endpoint.

type WebhookPayload added in v0.7.0

type WebhookPayload struct {
	Event     string      `json:"event"`
	Timestamp time.Time   `json:"timestamp"`
	Data      interface{} `json:"data"`
}

WebhookPayload is the JSON body sent to webhook URLs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL