Documentation
¶
Overview ¶
Package core is the shared kernel of the admin subsystem: the resolved upstream clients (State) plus the one-copy business primitives every admin domain composes — the two-tier gate, the /v1 envelope writers, the tenant-scope predicate, the IAM fan-in, the single credit-grant path, the tamper-evident audit emit, and the fleet activity/time-series model. Each primitive lives EXACTLY once here; the domain packages (audit/customer/revenue/finance) and the top-level admin Mount import it, never duplicating a helper — there is one path to grant, one read, one scope rule.
Index ¶
- Constants
- Variables
- func ApplyGrant(s *cloud.Service[State], c *zip.Ctx, org string, req CreditRequest) error
- func BucketKeyOf(t time.Time, interval string) string
- func CallerCreds(c *zip.Ctx) iam.Creds
- func DayKey(t time.Time) string
- func Descendants(s *cloud.Service[State], org string) []string
- func Display(displayName, fallback string) string
- func EmitAudit(s *cloud.Service[State], c *zip.Ctx, action, resType, resID string, ...)
- func EnumerateBuckets(since, now time.Time, interval string) []string
- func Fail(c *zip.Ctx, msg string) error
- func FindOrg(s *cloud.Service[State], ctx context.Context, cr iam.Creds, org string) (*iam.Org, error)
- func Guard(s *cloud.Service[State], h Handler) zip.Handler
- func GuardScoped(s *cloud.Service[State], h Handler) zip.Handler
- func IndexOf(buckets []string) map[string]int
- func ListOrgs(s *cloud.Service[State], ctx context.Context, cr iam.Creds) ([]iam.Org, error)
- func MonthKey(t time.Time) string
- func OK(c *zip.Ctx, data any) error
- func OKList(c *zip.Ctx, rows any, total int) error
- func OKRaw(c *zip.Ctx, rows json.RawMessage, total int) error
- func OrgMoney(s *cloud.Service[State], ctx context.Context, org string) (spend, credits int64, ok bool)
- func ParseTxnTime(s string) (time.Time, error)
- func ScopedOrgs(s *cloud.Service[State], ctx context.Context, c *zip.Ctx, cr iam.Creds) ([]iam.Org, error)
- func WeekKey(t time.Time) string
- type CreditRequest
- type CustActivity
- type Handler
- type SeriesPoint
- type SourceStatus
- type State
- type TenantScope
- type TxnPoint
Constants ¶
const MaxCustomerConcurrency = 8
MaxCustomerConcurrency bounds the per-org enrichment fan-out so a large fleet does not open one upstream connection per org at once. Admin is low-QPS; 8 keeps latency low without hammering IAM/commerce.
Variables ¶
var ErrPartialRevenue = errors.New("partial: one or more org revenue reads failed")
ErrPartialRevenue marks a revenue read that succeeded at the org-list level but had one or more per-org failures — the fleet total is real but PARTIAL. SrcOf reports it as a not-ok source so the console shows a degraded state rather than presenting an under-count as authoritative.
Functions ¶
func ApplyGrant ¶
ApplyGrant validates the amount + target org, deposits into the org's commerce ledger (trial vs prepaid by source), and records the tamper-evident audit row. One path, one way to grant.
func CallerCreds ¶
CallerCreds captures the caller's replayed authorization context for the IAM fan-out: the raw Cookie header (session model) and the Authorization bearer.
func Descendants ¶
Descendants returns org + every sub-org it owns — the subtree the caller administers. See the RECURSION SEAM note above: today the singleton {org}; the ONE place a future IAM parent-org index is walked.
func EmitAudit ¶
func EmitAudit(s *cloud.Service[State], c *zip.Ctx, action, resType, resID string, before, after any, outcome audit.Outcome)
EmitAudit writes ONE compliance record for a management action to cloud's tamper-evident trail: who (the validated SuperAdmin from the sanitized identity — the gate already proved it), what (action + resource), the redacted before/after, and the outcome. This is the "before/after on a config-affecting change" the request-level middleware record cannot carry (it never reads bodies). Best-effort: a failure here is logged loud, never silent, and never double-fails the response. A nil store (unconfigured deployment) is a no-op, like the middleware.
func EnumerateBuckets ¶
EnumerateBuckets lists every bucket key from since..now inclusive so a series has a continuous axis (a zero-usage bucket is an honest 0, not a gap).
func Fail ¶
Fail writes a { status:"error", msg } envelope. The operator's transport maps a non-ok envelope to a surfaced error (never a fabricated value).
func FindOrg ¶
func FindOrg(s *cloud.Service[State], ctx context.Context, cr iam.Creds, org string) (*iam.Org, error)
FindOrg returns the IAM org by slug (nil, nil when it does not exist) so a management action can validate its target before acting — never credit or suspend an org that isn't real.
func Guard ¶
Guard wraps a handler with the SuperAdmin gate. Fail-closed: any request whose validated identity is not a SuperAdmin (X-User-IsAdmin != "true", which SanitizeIdentity sets only for owner == AdminOrg) is refused 403 before the handler — no upstream is touched, no data leaks.
func GuardScoped ¶
GuardScoped is the gate for the ORG-SCOPED panels (me/overview/orgs/users/usage/ analytics/bases). It admits a SuperAdmin (principal.IsSuperAdmin) OR an ORG admin (an admin of their OWN org — principal.IsOrgAdmin) pinned to a validated org, and the handler then scopes every read to ResolveScope(c) — so a non-super caller passes the gate but the DATA layer hard-limits them to their own org subtree. Cross-tenant reads are impossible for a non-super caller regardless of input.
The non-super admission requires BOTH the sanitizer-minted X-User-IsOrgAdmin (principal.IsOrgAdmin — the "admin of my own org" bit, unforgeable because the boundary strips it on ingress) AND a validated principal pinned to its own org (principal.Org, the ONE org accessor: validated X-User-Id + non-empty in-bounds X-Org-Id). So a validated but NON-admin MEMBER of an org is REFUSED here — the same denial an anonymous caller who forged X-Org-Id gets — closing the same-tenant over-visibility gap where any org member could read their org's admin panels. A validated non-super principal's X-Org-Id is PINNED by the boundary to their own owner, never client-chosen.
func ListOrgs ¶
ListOrgs reads the org directory (owner = admin org) as the typed shape the overview/orgs/usage/customer/revenue/finance aggregators fold over.
func OKRaw ¶
OKRaw writes a { status:"ok", data:<raw>, data2:total } envelope, forwarding an IAM payload verbatim so its exact wire shape (Role, Application, Record, User) reaches the operator field-for-field.
func OrgMoney ¶
func OrgMoney(s *cloud.Service[State], ctx context.Context, org string) (spend, credits int64, ok bool)
OrgMoney returns (spendCents, creditsCents, ok) for one org from commerce. ok is false when the spend OR credits read FAILED — so a fleet aggregator can fold the per-org failure into a PARTIAL/degraded source rather than presenting the resulting undercount as authoritative (the SAME (row, ok) contract revenue.revenueOf uses). An unwired commerce is NOT a failure: Spend/Credits return (0, nil) when unconfigured, so ok stays true and the caller distinguishes "not configured" via Commerce.Ready().
func ParseTxnTime ¶
ParseTxnTime accepts the commerce ledger's RFC3339 forms.
func ScopedOrgs ¶
func ScopedOrgs(s *cloud.Service[State], ctx context.Context, c *zip.Ctx, cr iam.Creds) ([]iam.Org, error)
ScopedOrgs is the ONE fan-in the org-scoped read panels (overview, orgs, usage, analytics) fold over — enforcing the two-scope predicate in a single place. A SuperAdmin gets EVERY org (the cross-tenant list); any other caller gets ONLY their own subtree, each row read from IAM so the display name / createdTime are the REAL values. An org row that can't be read best-effort degrades to a name-only row rather than failing the panel — the scope is unaffected.
Types ¶
type CreditRequest ¶
type CreditRequest struct {
AmountCents int64 `json:"amountCents"`
Currency string `json:"currency"`
Reason string `json:"reason"`
// Source splits the grant into the commerce ledger's two money buckets:
// - "trial" (default) — a non-cash promo/comp credit: spendable on non-premium
// metered usage only, NEVER refundable cash and NEVER paid out.
// - "prepaid" — real money added to the customer's cash balance. Refundable,
// GPU-eligible.
// Unknown/empty → trial (fail-closed to non-cash).
Source string `json:"source"`
}
CreditRequest is the grant body. AmountCents is the credit to add (positive only — a grant, never a silent debit). Reason is the operator's justification, recorded in the audit trail's before/after (refund / comp / support).
type CustActivity ¶
type CustActivity struct {
Org string
Display string
Created time.Time
HasCreated bool
Usage []TxnPoint
SpendCents int64
}
CustActivity is one customer's real analytics input: when they signed up (IAM createdTime) and their consumption events (commerce withdraws). Deposits are NOT activity (a credit grant is not the customer using the product), so only withdraws feed active/retention/churn/usage — the honest "used it" signal.
func FleetActivity ¶
func FleetActivity(s *cloud.Service[State], ctx context.Context, orgs []iam.Org) ([]CustActivity, bool)
FleetActivity reads every org's signup time (already on the org row) + usage ledger, folded into the pure activity model. Returns (acts, ok) where ok is false if ANY org's ledger read failed (the caller marks the source degraded and flags the ledger-backed metrics as not-fully-computed). Fanned out concurrently with a bound.
func (CustActivity) ActiveIn ¶
func (ca CustActivity) ActiveIn(bucket string, interval string) bool
ActiveIn reports whether the customer had a usage event in the given bucket.
func (CustActivity) ActiveSince ¶
func (ca CustActivity) ActiveSince(cut time.Time) bool
ActiveSince reports whether the customer had a usage event at or after cut.
type Handler ¶
Handler is the admin handler shape: a free function over the shared kernel. Every domain handler is `func h(s *cloud.Service[core.State], c *zip.Ctx) error`.
type SeriesPoint ¶
SeriesPoint is one bucketed point (count OR cents, per the series). T is the bucket key (RFC3339 date / "2006-01" month).
func SpendSeries ¶
func SpendSeries(acts []CustActivity, since, now time.Time, interval string) []SeriesPoint
SpendSeries buckets fleet usage cents into a continuous series over since..now. Shared by the analytics usage/revenue trend and the revenue board's spend trend (one implementation, DRY). A bucket with no usage is an honest 0, not a gap.
type SourceStatus ¶
type SourceStatus struct {
Name string `json:"name"`
OK bool `json:"ok"`
Rows int `json:"rows"`
Error string `json:"error"`
At string `json:"at"`
}
SourceStatus is the freshness of one upstream the aggregator pulls from (overview.sources[] / revenue.sources[] / finance.sources[] / analytics.sources[]).
type State ¶
type State struct {
IAM *iam.Client
Commerce *commerce.Client
Health *health.Client
DO *digitalocean.Client
AdminOrg string
AuditStore *audit.Recorder
}
State is admin's own data: the resolved upstream clients + the admin org for this deployment. admin holds NO Base shared deps (it fans out over HTTP replaying the caller's own creds); the embedded cloud.Base carries only the mount-time logger.
AuditStore is cloud's OWN tamper-evident audit store (nil when unconfigured, in which case /v1/admin/audit falls back to the IAM get-records proxy). Serve builds it and hands it over via deps.Audit.
type TenantScope ¶
TenantScope is a request's resolved visibility window. Super and Orgs are the two mutually exclusive views: a SuperAdmin sees all tenants (Orgs ignored); anyone else sees exactly Orgs (their own subtree).
func ResolveScope ¶
ResolveScope derives the request's tenant window from the SANITIZED identity only — never a client-forgeable field. A SuperAdmin (c.IsAdmin(), owner == admin org) is cross-tenant; any other caller is pinned to the subtree of their own (sanitized) org.
func (TenantScope) ScopedToOrg ¶
func (t TenantScope) ScopedToOrg(o string) bool
ScopedToOrg reports whether the scope admits reads for org o. Super admits every org; a scoped caller admits only orgs in their subtree. Used by panels that filter an upstream list (e.g. bases) rather than fanning out per-org.