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:
@@ -39,6 +39,36 @@ class DeploymentConsistencyTest : FunSpec({
|
||||
openApi shouldContain "referralCode"
|
||||
}
|
||||
|
||||
test("admin ledger operations stay indexed exact and privacy minimized") {
|
||||
val migration = root.read(
|
||||
"src/main/resources/db/migration/V19__admin_ledger_operations.sql",
|
||||
)
|
||||
migration shouldContain
|
||||
"MODIFY reference_id CHAR(36) CHARACTER SET ascii COLLATE ascii_bin NULL"
|
||||
migration shouldContain
|
||||
"MODIFY reservation_id CHAR(36) CHARACTER SET ascii COLLATE ascii_bin NULL"
|
||||
migration shouldContain "ON credit_ledger (amount_delta, id)"
|
||||
migration shouldContain "ON credit_ledger (user_id, amount_delta, id)"
|
||||
migration shouldContain "ON provider_requests (capability, request_source, reservation_id)"
|
||||
migration shouldContain "ON provider_requests (request_source, capability, reservation_id)"
|
||||
|
||||
val openApi = root.read("docs/openapi.yaml")
|
||||
val ledgerSchema = openApi
|
||||
.substringAfter(" LedgerEntryType:")
|
||||
.substringBefore(" AdminLedgerPage:")
|
||||
LEDGER_ENTRY_TYPE_NAMES.forEach(ledgerSchema::shouldContain)
|
||||
ledgerSchema shouldContain "deprecated: true"
|
||||
ledgerSchema shouldContain "referenceId"
|
||||
ledgerSchema shouldContain "reservationId"
|
||||
ledgerSchema shouldContain
|
||||
"required: [entryId, userId, type, entryType, amount, balanceAfter, reasonCode, createdAt]"
|
||||
ledgerSchema shouldNotContain "enum: [grant, reserve, settle, refund, adjustment]"
|
||||
ledgerSchema shouldNotContain "idempotencyKey"
|
||||
ledgerSchema shouldNotContain "appAccountToken"
|
||||
ledgerSchema shouldNotContain "signedTransaction"
|
||||
ledgerSchema shouldNotContain "appleSubject"
|
||||
}
|
||||
|
||||
test("provider defaults and Apple integrity contract stay production compatible") {
|
||||
val providerConfigurations = listOf(
|
||||
root.read("src/main/kotlin/com/osglab/account/config/AppConfig.kt"),
|
||||
@@ -248,6 +278,19 @@ class DeploymentConsistencyTest : FunSpec({
|
||||
private fun Path.read(relativePath: String): String =
|
||||
Files.readString(resolve(relativePath))
|
||||
|
||||
private val LEDGER_ENTRY_TYPE_NAMES = listOf(
|
||||
"SIGNUP_TRIAL",
|
||||
"MANUAL_GRANT",
|
||||
"USAGE_RESERVE",
|
||||
"USAGE_SETTLE",
|
||||
"USAGE_RELEASE",
|
||||
"USAGE_REFUND",
|
||||
"REFERRAL_INVITER",
|
||||
"REFERRAL_INVITEE",
|
||||
"STOREKIT_PURCHASE",
|
||||
"SUBSCRIPTION_GRANT",
|
||||
)
|
||||
|
||||
private val EXPECTED_PUBLIC_PATHS = setOf(
|
||||
"/health",
|
||||
"/health/live",
|
||||
|
||||
Reference in New Issue
Block a user