Enhance ledger operations and referral lifecycle
Add traceable ledger filtering and permanent referral codes so operators can investigate credit activity without weakening immutable accounting guarantees.
This commit is contained in:
+98
-13
@@ -263,17 +263,18 @@ paths:
|
||||
default: { $ref: "#/components/responses/Error" }
|
||||
/v1/referrals/me:
|
||||
get:
|
||||
summary: Return the referral profile and idempotently provision its invite code
|
||||
summary: Return the referral profile and provision its permanent account invite code
|
||||
responses:
|
||||
"200":
|
||||
description: Referral profile
|
||||
content:
|
||||
application/json:
|
||||
schema: { type: object, additionalProperties: true }
|
||||
schema: { $ref: "#/components/schemas/ReferralProfile" }
|
||||
default: { $ref: "#/components/responses/Error" }
|
||||
/v1/referrals/code:
|
||||
post:
|
||||
summary: Idempotently create the current campaign invite code
|
||||
deprecated: true
|
||||
summary: Compatibility endpoint for the permanent account invite code
|
||||
responses:
|
||||
"200":
|
||||
description: Invite code
|
||||
@@ -685,11 +686,14 @@ paths:
|
||||
- $ref: "#/components/parameters/AdminFrom"
|
||||
- $ref: "#/components/parameters/AdminUntil"
|
||||
- $ref: "#/components/parameters/AdminLedgerType"
|
||||
- $ref: "#/components/parameters/AdminCreatedAtSort"
|
||||
- $ref: "#/components/parameters/AdminLedgerEntryType"
|
||||
- $ref: "#/components/parameters/AdminLedgerUsageType"
|
||||
- $ref: "#/components/parameters/AdminLedgerReferenceId"
|
||||
- $ref: "#/components/parameters/AdminLedgerSort"
|
||||
- $ref: "#/components/parameters/AdminSortOrder"
|
||||
responses:
|
||||
"200":
|
||||
description: Credit ledger entries ordered by creation time and entry ID
|
||||
description: Credit ledger entries ordered by the requested field and unique entry ID
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/AdminLedgerPage" }
|
||||
@@ -710,11 +714,14 @@ paths:
|
||||
- $ref: "#/components/parameters/AdminFrom"
|
||||
- $ref: "#/components/parameters/AdminUntil"
|
||||
- $ref: "#/components/parameters/AdminLedgerType"
|
||||
- $ref: "#/components/parameters/AdminCreatedAtSort"
|
||||
- $ref: "#/components/parameters/AdminLedgerEntryType"
|
||||
- $ref: "#/components/parameters/AdminLedgerUsageType"
|
||||
- $ref: "#/components/parameters/AdminLedgerReferenceId"
|
||||
- $ref: "#/components/parameters/AdminLedgerSort"
|
||||
- $ref: "#/components/parameters/AdminSortOrder"
|
||||
responses:
|
||||
"200":
|
||||
description: Latest credit ledger entries ordered by creation time and entry ID
|
||||
description: Latest credit ledger entries ordered by the requested field and unique entry ID
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: "#/components/schemas/AdminLedgerPage" }
|
||||
@@ -1007,7 +1014,26 @@ components:
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
enum: [grant, reserve, settle, refund, adjustment]
|
||||
enum: [grant, reserve, settle, refund]
|
||||
AdminLedgerEntryType:
|
||||
name: entryType
|
||||
in: query
|
||||
description: Exact immutable ledger entry type. This filter is ANDed with all other filters.
|
||||
schema:
|
||||
$ref: "#/components/schemas/LedgerEntryType"
|
||||
AdminLedgerUsageType:
|
||||
name: usageType
|
||||
in: query
|
||||
description: Product usage associated with the reservation. HOTWORD request source takes precedence over capability.
|
||||
schema: { type: string, enum: [polish, asr, ai, agent, hotword] }
|
||||
AdminLedgerReferenceId:
|
||||
name: referenceId
|
||||
in: query
|
||||
schema: { type: string, format: uuid }
|
||||
AdminLedgerSort:
|
||||
name: sort
|
||||
in: query
|
||||
schema: { type: string, enum: [createdAt, amount], default: createdAt }
|
||||
AdminLedgerLimit:
|
||||
name: limit
|
||||
in: query
|
||||
@@ -1411,21 +1437,58 @@ components:
|
||||
type: array
|
||||
items: { $ref: "#/components/schemas/AdminUsageAggregate" }
|
||||
referral: { $ref: "#/components/schemas/AdminUserReferral" }
|
||||
LedgerEntryType:
|
||||
type: string
|
||||
enum:
|
||||
- SIGNUP_TRIAL
|
||||
- MANUAL_GRANT
|
||||
- USAGE_RESERVE
|
||||
- USAGE_SETTLE
|
||||
- USAGE_RELEASE
|
||||
- USAGE_REFUND
|
||||
- REFERRAL_INVITER
|
||||
- REFERRAL_INVITEE
|
||||
- STOREKIT_PURCHASE
|
||||
- SUBSCRIPTION_GRANT
|
||||
AdminLedgerDetails:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [kind]
|
||||
description: Privacy-minimized source metadata. Missing source associations omit the details object.
|
||||
properties:
|
||||
kind: { type: string, enum: [manualGrant, storeKit, referral, usage] }
|
||||
reason: { type: string, description: Present for manualGrant details }
|
||||
operatorName: { type: string, description: Present for manualGrant details }
|
||||
productId: { type: string, description: Present for storeKit details }
|
||||
transactionId: { type: string, description: Present for storeKit details }
|
||||
originalTransactionId: { type: string, description: Present for storeKit details }
|
||||
environment: { type: string, enum: [SANDBOX, PRODUCTION], description: Present for storeKit details }
|
||||
purchasedAt: { type: string, format: date-time, description: Present for storeKit details }
|
||||
role: { type: string, enum: [inviter, invitee], description: Present for referral details }
|
||||
relatedUserId: { type: string, format: uuid, description: Present for referral details }
|
||||
reservationId: { type: string, format: uuid, description: Present for usage details }
|
||||
AdminLedgerEntry:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [entryId, userId, type, amount, balanceAfter, reasonCode, createdAt]
|
||||
required: [entryId, userId, type, entryType, amount, balanceAfter, reasonCode, createdAt]
|
||||
properties:
|
||||
entryId: { type: string, format: uuid }
|
||||
userId: { type: string, format: uuid }
|
||||
type: { type: string, enum: [grant, reserve, settle, refund, adjustment] }
|
||||
type: { type: string, enum: [grant, reserve, settle, refund] }
|
||||
entryType: { $ref: "#/components/schemas/LedgerEntryType" }
|
||||
amount: { type: integer, format: int64 }
|
||||
balanceAfter: { type: integer, format: int64, minimum: 0 }
|
||||
reasonCode: { type: string }
|
||||
reasonCode:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/LedgerEntryType"
|
||||
deprecated: true
|
||||
description: Compatibility alias for entryType
|
||||
referenceId: { type: ["string", "null"], format: uuid }
|
||||
usageType:
|
||||
type: ["string", "null"]
|
||||
enum: [polish, asr, ai, agent, hotword, null]
|
||||
description: Product usage associated with this ledger operation
|
||||
details: { $ref: "#/components/schemas/AdminLedgerDetails" }
|
||||
createdAt: { type: string, format: date-time }
|
||||
AdminLedgerPage:
|
||||
type: object
|
||||
@@ -1728,9 +1791,31 @@ components:
|
||||
items: { type: object, additionalProperties: true }
|
||||
ReferralCode:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
additionalProperties: false
|
||||
required: [code, inviteUrl, createdAt]
|
||||
properties:
|
||||
code: { type: string, pattern: "^[A-Za-z0-9_-]{22}$" }
|
||||
code:
|
||||
type: string
|
||||
pattern: "^[A-Za-z0-9_-]{22}$"
|
||||
description: Permanent opaque identifier assigned once to the account.
|
||||
inviteUrl:
|
||||
type: string
|
||||
format: uri
|
||||
description: Stable first-party invitation URL containing the permanent code.
|
||||
campaignId:
|
||||
type: ["string", "null"]
|
||||
format: uuid
|
||||
description: Legacy creation metadata; it does not limit the invitation lifetime.
|
||||
createdAt: { type: string, format: date-time }
|
||||
ReferralProfile:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [code]
|
||||
properties:
|
||||
code: { $ref: "#/components/schemas/ReferralCode" }
|
||||
binding:
|
||||
type: ["object", "null"]
|
||||
additionalProperties: true
|
||||
RedeemReferralRequest:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
Reference in New Issue
Block a user