feat(plugin-quota): add typed summary metrics

This commit is contained in:
Angello Picasso
2026-09-14 00:12:07 +00:00
parent 44e62bc8ac
commit acb0eae2eb
3 changed files with 25 additions and 0 deletions

View File

@@ -45,6 +45,9 @@ func (m *mockQuotaProvider) FetchQuota(ctx context.Context, req pluginapi.QuotaF
TierID: "pro-tier",
},
ServerTimeOffsetMs: 42,
Summary: []pluginapi.QuotaMetric{
{Key: "credits_used", Label: "Credits used", Value: 1740.28, Unit: "credits"},
},
Groups: []pluginapi.QuotaGroup{
{
DisplayName: "Standard Limits",
@@ -181,6 +184,9 @@ func TestFetchCredentialQuota_Endpoint(t *testing.T) {
if quotaResp.Subscription == nil || quotaResp.Subscription.Plan != "Pro" {
t.Fatalf("unexpected subscription: %+v", quotaResp.Subscription)
}
if len(quotaResp.Summary) != 1 || quotaResp.Summary[0].Key != "credits_used" || quotaResp.Summary[0].Value != 1740.28 {
t.Fatalf("unexpected quota summary: %+v", quotaResp.Summary)
}
if len(quotaResp.Groups) != 1 || len(quotaResp.Groups[0].Buckets) != 1 {
t.Fatalf("unexpected quota groups: %+v", quotaResp.Groups)
}

View File

@@ -1601,9 +1601,21 @@ func (b *QuotaBucket) UnmarshalJSON(data []byte) error {
return nil
}
// QuotaMetric is a provider-defined, bounded numeric account summary for management UI rendering.
// Format is "number" or "currency"; Currency is an ISO 4217 code when Format is "currency".
type QuotaMetric struct {
Key string `json:"key"`
Label string `json:"label"`
Value float64 `json:"value"`
Unit string `json:"unit,omitempty"`
Format string `json:"format,omitempty"`
Currency string `json:"currency,omitempty"`
}
// QuotaFetchResponse carries normalized quota information for management UI rendering.
type QuotaFetchResponse struct {
Subscription *QuotaSubscription `json:"subscription,omitempty"`
Summary []QuotaMetric `json:"summary,omitempty"`
ServerTimeOffsetMs int64 `json:"serverTimeOffsetMs,omitempty"`
Groups []QuotaGroup `json:"groups,omitempty"`
}

View File

@@ -662,6 +662,10 @@ func TestQuotaPayloadJSON(t *testing.T) {
// Test camelCase input
camelJSON := []byte(`{
"subscription": {"plan":"Pro","tierName":"Tier 1","tierId":"t-1"},
"summary": [
{"key":"credits_used","label":"Credits used","value":1740.28,"unit":"credits","format":"number"},
{"key":"charged","label":"Charged","value":29.61,"format":"currency","currency":"USD"}
],
"serverTimeOffsetMs": 100,
"groups": [
{
@@ -680,6 +684,9 @@ func TestQuotaPayloadJSON(t *testing.T) {
if respCamel.Subscription == nil || respCamel.Subscription.TierName != "Tier 1" || respCamel.Subscription.TierID != "t-1" {
t.Fatalf("unexpected camel subscription: %+v", respCamel.Subscription)
}
if len(respCamel.Summary) != 2 || respCamel.Summary[0].Key != "credits_used" || respCamel.Summary[0].Value != 1740.28 || respCamel.Summary[1].Currency != "USD" {
t.Fatalf("unexpected camel summary: %+v", respCamel.Summary)
}
if respCamel.ServerTimeOffsetMs != 100 {
t.Fatalf("unexpected server time offset: %d", respCamel.ServerTimeOffsetMs)
}