Documentation
¶
Overview ¶
Package contract wires Ledger into the Forge dashboard's contract path. It declares the `ledger` contributor and its intents, and binds the typed handlers that answer them. The React plugin in forge-dashboard (packages/plugin-ledger) reads these intents.
Index ¶
- func Register(d *dispatcher.Dispatcher, reg dash.Registry, wreg dash.WardenRegistry, ...) error
- type Ack
- type CouponApplyInput
- type CouponCreateInput
- type CouponUpdateInput
- type CouponsListInput
- type Deps
- type EntitlementCheckInput
- type EntitlementInvalidateInput
- type FeatureCreateInput
- type FeatureUpdateInput
- type FeatureUsage
- type FeaturesListInput
- type IDInput
- type ImportInput
- type InvoiceDetail
- type InvoiceExport
- type InvoiceExportInput
- type InvoiceGenerateInput
- type InvoiceMarkPaidInput
- type InvoiceVoidInput
- type InvoicesListInput
- type Nullable
- type OverviewStats
- type Page
- type PageInput
- type PaymentMethods
- type PaymentMethodsInput
- type PlanCreateInput
- type PlanUpdateInput
- type PlansListInput
- type RecentInvoicesInput
- type SettingsDetail
- type SettingsView
- type SubscriptionCancelInput
- type SubscriptionChangePlanInput
- type SubscriptionCreateInput
- type SubscriptionDetail
- type SubscriptionUsage
- type SubscriptionsListInput
- type UsageAggregateInput
- type UsageEventsInput
- type UsageTotals
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Register ¶
func Register(d *dispatcher.Dispatcher, reg dash.Registry, wreg dash.WardenRegistry, deps Deps) error
Register loads and validates the manifest, registers the contributor, and binds every intent. The dashboard calls it through Extension.RegisterContractContributor.
Types ¶
type Ack ¶
type Ack struct {
OK bool `json:"ok"`
}
Ack is the answer to a command with nothing else to report.
type CouponApplyInput ¶
type CouponCreateInput ¶
type CouponCreateInput struct {
Code string `json:"code"`
Name string `json:"name"`
Type string `json:"type"`
Amount types.Money `json:"amount"`
Percentage int `json:"percentage"`
Currency string `json:"currency"`
MaxRedemptions int `json:"max_redemptions"`
ValidFrom *time.Time `json:"valid_from"`
ValidUntil *time.Time `json:"valid_until"`
Metadata map[string]string `json:"metadata"`
}
type CouponUpdateInput ¶
type CouponUpdateInput struct {
ID string `json:"id"`
Name *string `json:"name"`
MaxRedemptions *int `json:"max_redemptions"`
ValidFrom Nullable[time.Time] `json:"valid_from"`
ValidUntil Nullable[time.Time] `json:"valid_until"`
Metadata *map[string]string `json:"metadata"`
}
CouponUpdateInput carries only the fields a coupon may change after it is created. Its code, type, value and currency are fixed, because applied coupons are priced from them on every future invoice.
type CouponsListInput ¶
type Deps ¶
type Deps struct {
Engine func() *ledger.Ledger
// AppID is the extension's configured app, used when the principal carries
// no app_id claim. Empty in a single-app deployment.
AppID string
// RequireAppClaim refuses any request whose principal has no app_id claim,
// even when AppID is set. Turn it on in a multi-app deployment, where an
// unscoped read would return every app's rows.
RequireAppClaim bool
Settings func() SettingsView
}
Deps is everything the handlers need. Engine is a function because the dashboard registers contributors before every extension has finished starting; a handler that runs before the engine exists answers UNAVAILABLE.
type EntitlementCheckInput ¶
type FeatureCreateInput ¶
type FeatureCreateInput struct {
Key string `json:"key"`
Name string `json:"name"`
Description string `json:"description"`
Type string `json:"type"`
DefaultLimit int64 `json:"default_limit"`
Period string `json:"period"`
SoftLimit bool `json:"soft_limit"`
Metadata map[string]string `json:"metadata"`
}
FeatureCreateInput carries a new catalog feature. Its key and type are fixed once created: plans refer to a catalog feature by key and price it by type.
type FeatureUpdateInput ¶
type FeatureUpdateInput struct {
ID string `json:"id"`
Name *string `json:"name"`
Description *string `json:"description"`
DefaultLimit *int64 `json:"default_limit"`
Period *string `json:"period"`
SoftLimit *bool `json:"soft_limit"`
Metadata *map[string]string `json:"metadata"`
}
FeatureUpdateInput names only what changes. An omitted field is left alone. There is no key or type: those are fixed once the feature is created.
type FeatureUsage ¶
type FeatureUsage struct {
Key string `json:"key"`
Name string `json:"name"`
Type string `json:"type"`
Period string `json:"period"`
Limit int64 `json:"limit"`
Used int64 `json:"used"`
Remaining int64 `json:"remaining"`
SoftLimit bool `json:"soft_limit"`
OverLimit bool `json:"over_limit"`
Enabled bool `json:"enabled"`
}
type FeaturesListInput ¶
type IDInput ¶
type IDInput struct {
ID string `json:"id"`
}
IDInput is the request for every intent that names one entity.
type ImportInput ¶
type ImportInput struct {
ProviderName string `json:"provider_name"`
ProviderID string `json:"provider_id"`
}
ImportInput names one record at a payment provider. An empty provider_name means the first registered provider, as the engine reads it.
type InvoiceDetail ¶
type InvoiceDetail struct {
Invoice *invoice.Invoice `json:"invoice"`
Subscription *subscription.Subscription `json:"subscription"`
ExportFormats []string `json:"export_formats"`
}
type InvoiceExport ¶
type InvoiceExportInput ¶
type InvoiceGenerateInput ¶
type InvoiceGenerateInput struct {
SubscriptionID string `json:"subscription_id"`
PeriodStart *time.Time `json:"period_start,omitempty"`
PeriodEnd *time.Time `json:"period_end,omitempty"`
}
InvoiceGenerateInput names the subscription and, optionally, a period it has already had. With no period the invoice is for the current one.
type InvoiceMarkPaidInput ¶
type InvoiceVoidInput ¶
type InvoicesListInput ¶
type Nullable ¶
Nullable is an update field that can be left alone, cleared, or set. A pointer cannot do this: JSON null and an absent key both decode to nil. A non-pointer type implementing json.Unmarshaler is called for null, so the three cases stay distinct.
func (*Nullable[T]) UnmarshalJSON ¶
type OverviewStats ¶
type OverviewStats struct {
Plans int `json:"plans"`
ActivePlans int `json:"active_plans"`
SubscriptionsByStatus map[string]int `json:"subscriptions_by_status"`
PendingInvoices int `json:"pending_invoices"`
PastDueInvoices int `json:"past_due_invoices"`
Coupons int `json:"coupons"`
// Capped is true when a count reached the scan bound; the counts are then
// lower bounds and the page must say so.
Capped bool `json:"capped"`
}
type Page ¶
type Page[T any] struct { Items []T `json:"items"` Limit int `json:"limit"` Offset int `json:"offset"` HasMore bool `json:"has_more"` }
Page is the shape of every list response.
type PaymentMethods ¶
type PaymentMethods struct {
Configured bool `json:"configured"`
Methods []provider.PaymentMethod `json:"methods"`
}
type PaymentMethodsInput ¶
type PaymentMethodsInput struct {
TenantID string `json:"tenant_id"`
}
type PlanCreateInput ¶
type PlanCreateInput struct {
Name string `json:"name"`
Slug string `json:"slug"`
Description string `json:"description"`
Currency string `json:"currency"`
TrialDays int `json:"trial_days"`
Features []plan.Feature `json:"features"`
Pricing *plan.Pricing `json:"pricing"`
Metadata map[string]string `json:"metadata"`
}
type PlanUpdateInput ¶
type PlanUpdateInput struct {
ID string `json:"id"`
Name *string `json:"name"`
Slug *string `json:"slug"`
Description *string `json:"description"`
Currency *string `json:"currency"`
TrialDays *int `json:"trial_days"`
Features *[]plan.Feature `json:"features"`
Pricing *plan.Pricing `json:"pricing"`
Metadata *map[string]string `json:"metadata"`
}
PlanUpdateInput names only what changes. An omitted field is left alone. `features` and `pricing`, when present, replace the plan's whole list or pricing block.
type PlansListInput ¶
type RecentInvoicesInput ¶
type RecentInvoicesInput struct {
Limit int `json:"limit"`
}
type SettingsDetail ¶
type SettingsDetail struct {
SettingsView
AppID string `json:"app_id"`
RequireAppClaim bool `json:"require_app_claim"`
Providers []string `json:"providers"`
InvoiceFormats []string `json:"invoice_formats"`
}
type SettingsView ¶
type SettingsView struct {
MeterBatchSize int `json:"meter_batch_size"`
MeterFlushInterval string `json:"meter_flush_interval"`
EntitlementCacheTTL string `json:"entitlement_cache_ttl"`
// LifecycleInterval is how often the lifecycle clock runs, as a Go
// duration, or "off".
LifecycleInterval string `json:"lifecycle_interval"`
}
SettingsView is the read-only engine configuration settings.detail reports. It comes from the extension's resolved configuration, not from constants.
type SubscriptionCancelInput ¶
type SubscriptionCreateInput ¶
type SubscriptionDetail ¶
type SubscriptionDetail struct {
Subscription *subscription.Subscription `json:"subscription"`
Plan *plan.Plan `json:"plan"`
AppliedCoupons []*coupon.Coupon `json:"applied_coupons"`
}
type SubscriptionUsage ¶
type SubscriptionUsage struct {
Features []FeatureUsage `json:"features"`
}