Documentation
¶
Index ¶
Constants ¶
const IAMUserKind = "iam-user"
IAMUserKind is the destination/source kind of the gateway-spendable wallet: the balance the cloud gateway's prepaid gate reads and its usage debits. A credit INTO this wallet mints spendable inference/GPU value cross-charged to Hanzo's real upstream spend, so it is the money-GA asset the mint invariant protects. Legacy per-org "user"/"account" order wallets are org-scoped store credit (checkout capture, account balance) and are NOT gateway-spendable.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Transaction ¶
type Transaction struct {
mixin.Model[Transaction]
DestinationId string `json:"destinationId"`
DestinationKind string `json:"destinationKind"`
Currency currency.Type `json:"currency"`
Amount currency.Cents `json:"amount"`
Type Type `json:"type"`
Test bool `json:"test"`
// Short text human readable description
Notes string `json:"notes,omitempty"`
// For searching
Tags string `json:"tags,omitempty"`
Event string `json:"event,omitempty"`
// Source Data
// We store Kind even though it is encoded in id for easier reference
SourceId string `json:"sourceId,omitempty"`
SourceKind string `json:"sourceKind,omitempty"`
// Scope attribution for per-scope spend caps (issue #70). Both are INDEXED so
// spend can be summed per (project,service) scope for the calendar-month
// period. Empty = the org-wide default scope (a legacy row that predates
// scoping has NO Project/Service property and is therefore only ever counted
// in an unfiltered org-wide sum, never in a project- or service-scoped one).
Project string `json:"project,omitempty"`
Service string `json:"service,omitempty"`
// AccountId funds this row — the BillingAccount (models/billingaccount) whose
// balance and calendar-month cap this row counts against. INDEXED so an
// account's balance and period spend can be summed per account. "" = the
// org-wide default pool (every row that predates billing accounts), so the org
// total stays the unfiltered sum and existing balances are byte-preserved.
AccountId string `json:"accountId,omitempty"`
// ExpiresAt marks when a deposit credit expires. Zero value means no expiry.
// Expired deposits are excluded from balance calculations.
ExpiresAt time.Time `json:"expiresAt,omitempty"`
// Deprecated
UserId string `json:"-"`
Metadata Map `json:"metadata,omitempty" datastore:"-"`
Metadata_ string `json:"-" datastore:",noindex"`
}
func Fake ¶
func Fake(db *datastore.Datastore) *Transaction
func New ¶
func New(db *datastore.Datastore) *Transaction
func (*Transaction) MintRequiresAuthorization ¶
func (t *Transaction) MintRequiresAuthorization() bool
MintRequiresAuthorization implements mintauth.Guarded: it reports whether persisting THIS transaction mints spendable balance into the gateway-honored IAM-user wallet. The datastore write sink (mintauth.Enforce) consults it so that enforcement lives at the ledger layer, not in per-route gates.
- Deposit → mints: a deposit has NO funded source, so any deposit crediting the IAM-user wallet creates spendable balance from nothing.
- Transfer → mints when its destination is the IAM-user wallet: value moves INTO the gateway-spendable balance. A legitimate internal transfer between the org's own funded IAM-user accounts is itself a debit on the source (which required a prior authorized mint), and moving value into the gateway wallet is exactly what must be authorized.
- Withdraw / Hold / HoldRemoved → never mint (debits / reservations).
Non-IAM-user destinations (legacy order wallets) are not gateway-spendable and are deliberately out of scope — gating them would break checkout capture with no money-GA benefit.
func (*Transaction) Validator ¶
func (t *Transaction) Validator() *val.Validator