Skip to content

fix: track affiliate rebates from redeem codes and admin recharges - #6321

Open
QHSsss wants to merge 4 commits into
Wei-Shaw:mainfrom
QHSsss:fix/redeem-affiliate-rebate-records
Open

fix: track affiliate rebates from redeem codes and admin recharges#6321
QHSsss wants to merge 4 commits into
Wei-Shaw:mainfrom
QHSsss:fix/redeem-affiliate-rebate-records

Conversation

@QHSsss

@QHSsss QHSsss commented Aug 28, 2026

Copy link
Copy Markdown

Summary

  • Track affiliate rebate sources for payment orders, balance redeem codes, and admin balance adjustments.
  • Accrue balance redeem code and admin recharge rebates in the same transaction as the related balance change.
  • Show all rebate sources in the admin rebate records table with source filtering, masked source references, and consistent status badges.
  • Add deployment-safe migrations, concurrent indexes, duplicate-source prechecks, and stable pagination ordering.

Problem

Affiliate rebates generated by balance redeem code top-ups were written to the affiliate ledger without a payment order.

The admin rebate records query only exposed payment-order-backed records, so rebates generated by balance redeem codes were missing from the page and could not be filtered or audited by source.

Admin balance recharge rebates also lacked a mandatory source reference, which made their origin difficult to verify.

Implementation

  • Add source_type, base_amount, and source_redeem_code_id to affiliate rebate ledger records.
  • Support the following rebate sources:
    • payment_order
    • balance_redeem_code
    • admin_recharge
    • legacy_unknown
  • Validate that every new rebate source:
    • exists;
    • belongs to the invitee;
    • has the expected source type;
    • has already been used or completed;
    • contains a valid positive base amount.
  • Require admin recharge rebates to reference the corresponding admin balance adjustment record.
  • Keep redeem status, user balance, affiliate quota, and affiliate ledger writes in the same database transaction.
  • Roll back the entire redemption when affiliate rebate accrual fails.
  • Skip redeem-level affiliate accrual during payment fulfillment to prevent duplicate rebates.
  • Treat historical records without reliable source identifiers as legacy_unknown instead of inferring their sources from timestamps.
  • Add source filtering, masked source references, and source-specific status display to the admin rebate records table.
  • Add a deterministic ledger ID tie-breaker so pagination remains stable when multiple records have the same source or status.
  • Preserve legacy payment-order behavior when source_type is omitted from the API request.

Migration Safety

  • Keep the core migration limited to fast column additions.
  • Create rebate source indexes concurrently outside the startup transaction.
  • Check for duplicate order and redeem-code sources before creating unique indexes.
  • Stop with actionable duplicate details instead of deleting or merging financial records automatically.
  • Clean up invalid concurrent indexes before retrying an interrupted migration.
  • Add foreign keys and source constraints with NOT VALID to avoid scanning the full ledger during deployment while still validating new writes.
  • Preserve compatibility with the known checksum of the superseded migration draft.
  • Conservatively repair only the unsafe admin-source classifications created by that known draft.

Testing

  • Affiliate rebate source validation tests
  • Balance redeem code rebate service tests
  • Admin recharge transaction commit and rollback tests
  • Payment fulfillment rebate deduplication tests
  • Migration checksum compatibility tests
  • Concurrent index execution mode tests
  • Duplicate source precheck tests
  • Invalid concurrent index retry tests
  • Admin affiliate handler tests
  • Admin rebate records component tests
  • PostgreSQL integration tests for redeem transaction atomicity
  • PostgreSQL integration tests for source idempotency
  • PostgreSQL integration tests for concurrent per-invitee rebate caps
  • PostgreSQL integration tests for historical migration repair

Commands executed:

go test ./migrations -run TestAffiliateRebateSourcesMigrationAvoidsHistoricalGuessingAndBlockingIndexes -count=1

go test ./internal/repository -run "Test(ValidateMigrationExecutionMode|AffiliateRebateSourceIndexesMigrationUsesSupportedExecutionMode|ApplyMigrationsFS_AffiliateRebateSourceIndexesMigration|MigrationChecksumCompatibility)" -count=1

go test -tags=unit ./internal/service -run "Test.*(Affiliate|AdminService_UpdateUserBalance|PaymentFulfillment)" -count=1

go test ./internal/handler/admin -run "TestAffiliate|Test.*RebateRecords" -count=1

pnpm test:run src/views/admin/__tests__/AdminAffiliateRecordsTable.spec.ts

go test -tags=integration ./internal/repository -run "TestAffiliateRepository_AccrueQuota_|TestAdminService_UpdateUserBalance_AdminRechargeCommitsOrRollsBackAsOneTransaction|TestRedeemService_BalanceAndAffiliateRebateShareTransaction|TestAffiliateRebateSourcesMigration_DoesNotGuessHistoryAndRepairsSupersededDraft" -count=1 -v

All targeted tests passed.

CLA

I have read the CLA Document and I hereby sign the CLA

Copilot AI lite review requested due to automatic review settings August 28, 2026 06:55
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA. ✅
Posted by the CLA Assistant Lite bot.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It changes financial-ledger writes, transactional semantics, and production migrations/constraints across multiple layers, warranting final human validation despite strong test coverage.

Pull request overview

This PR extends the affiliate rebate system to track and display rebates generated from multiple “recharge” sources (payment orders, balance redeem codes, and admin balance adjustments), while tightening transactional guarantees (rebate accrual shares the same DB transaction as the underlying balance change) and adding deployment-safe schema changes (fast column adds, concurrent indexes, and NOT VALID constraints).

Changes:

  • Add rebate source typing + base amount snapshotting across backend ledger writes, plus source-based querying/sorting/filtering for admin rebate records.
  • Ensure redeem-code and admin-recharge rebates accrue atomically with their balance mutations (rollback on accrual failure) and prevent duplicate accrual paths.
  • Introduce migration safety measures: concurrent indexes outside transactions, duplicate-source prechecks, and NOT VALID constraints + targeted repair of a superseded migration draft.
File summaries
File Description
frontend/src/views/admin/affiliates/AdminAffiliateRecordsTable.vue Adds rebate source filter UI and displays source type/reference/status/base amount with stable request sequencing.
frontend/src/views/admin/tests/AdminAffiliateRecordsTable.spec.ts Adds component tests for source filtering, status badge rendering, and stale-response protection.
frontend/src/i18n/locales/zh/admin/overview.ts Updates CN admin copy and adds rebate source-related labels and placeholders.
frontend/src/i18n/locales/en/admin/overview.ts Updates EN admin copy and adds rebate source-related labels and placeholders.
frontend/src/api/admin/affiliates.ts Extends rebate record types and request params to include source metadata and filtering.
backend/migrations/affiliate_rebate_sources_migration_test.go Asserts migration SQL stays “fast” (no historical backfills / blocking indexes) and includes required constraints/indexes.
backend/migrations/232_affiliate_rebate_source_constraints.sql Adds NOT VALID FKs + CHECK constraints and repairs unsafe historical admin-source classifications from a known draft.
backend/migrations/231_affiliate_rebate_sources.sql Adds source_type/base_amount/source_redeem_code_id columns to affiliate ledger with comments.
backend/migrations/231_affiliate_rebate_sources_indexes_notx.sql Creates concurrent indexes and unique source idempotency indexes outside transactions.
backend/internal/service/redeem_service.go Moves balance redeem-code rebate accrual into the redemption transaction (rollback on failure) and removes best-effort post-commit accrual.
backend/internal/service/payment_fulfillment.go Switches payment order rebate accrual to the new generic source-based accrual API.
backend/internal/service/payment_fulfillment_test.go Updates fulfillment tests/stubs to assert source type + base amount are passed through.
backend/internal/service/affiliate_service.go Introduces AffiliateRebateSource + validation, threads source + per-invitee cap into repository accrual, and updates record/filter structs.
backend/internal/service/affiliate_service_test.go Adds validation tests for sources and verifies source + cap are passed to the repository layer.
backend/internal/service/admin_user.go Wraps admin balance changes + adjustment record + rebate accrual in a single DB transaction and returns errors on rebate accrual failure.
backend/internal/service/admin_service.go Updates internal interface to the new AccrueInviteRebate signature.
backend/internal/service/admin_service_update_balance_test.go Updates unit tests to reflect transactional behavior, source typing, and rollback-on-accrual-failure semantics.
backend/internal/repository/redeem_code_repo.go Ensures redeem code writes participate in an existing transaction via context client selection.
backend/internal/repository/migrations_runner.go Adds non-tx migration prechecks for duplicate rebate sources and invalid index cleanup; tightens execution-mode validation.
backend/internal/repository/migrations_runner_notx_test.go Adds tests for execution-mode validation and affiliate index migration precheck/invalid-index retry behavior.
backend/internal/repository/migrations_runner_checksum_test.go Adds checksum compatibility coverage for a superseded 231 draft migration.
backend/internal/repository/affiliate_repo.go Implements source validation, idempotent accrual with caps in SQL, and expands rebate records query to include all sources + stable ordering.
backend/internal/repository/affiliate_repo_integration_test.go Adds integration tests for idempotency, transactional atomicity, caps under concurrency, and historical repair behavior.
backend/internal/handler/auth_email_oauth_test.go Updates stub interface to match the new AccrueQuota signature.
backend/internal/handler/admin/affiliate_handler.go Adds source_type parsing/validation with backward-compatible default behavior for legacy admin clients.
backend/internal/handler/admin/affiliate_handler_test.go Adds a focused test that invalid source_type is rejected early with 400.
Review details
  • Files reviewed: 26/26 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@QHSsss QHSsss closed this Aug 28, 2026
@QHSsss QHSsss reopened this Aug 28, 2026
@QHSsss QHSsss closed this Aug 28, 2026
@QHSsss QHSsss reopened this Aug 28, 2026
@QHSsss

QHSsss commented Aug 28, 2026

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants