BE-050 — Escrow-based payout service (escrow_payout) - #910
Open
graceful-tech12 wants to merge 1 commit into
Open
graceful-tech12 wants to merge 1 commit into
graceful-tech12 wants to merge 1 commit into
Conversation
…en main Implements the escrow_payout backlog item (BlockDash-Studios#803): time-locked escrow for tutor earnings with accrual on confirmed contributions, unlock per the tutor's payout schedule (BE-082), and a withdraw endpoint. - EscrowPayoutService: accrue/list/balance/releaseUnlocked/withdraw with a locked → unlocked → withdrawn lifecycle. Withdrawal before unlock is rejected with ESCROW_LOCKED; the unlock job releases entries on schedule. - REST surface at /api/v1/escrow (accrue, withdraw, release, entries, balance, withdrawals) with stroop amounts carried as strings on the wire. - UsersModule wiring EscrowPayoutService to TutorPayoutScheduleService. - Unit tests covering both acceptance criteria (163 unit tests pass). - Migration 003: durable schema for escrow entries and withdrawals. Also repairs pre-existing breakage on main so the suite and CI can pass: - courses.controller.ts had two files concatenated (syntax error); restored both the v1 controller and the legacy /api/courses controller its e2e contract exercises, and registered CoursesService in the module. - chat/registration.ts, health/wallet.ts, health/coverage.ts were stale duplicates importing modules that do not exist there; removed. - Added the missing ChatRoomService its spec expects. - TooManyRequestsException does not exist in @nestjs/common v10; defined it locally where chat moderation and submission protection need it. - horizon.service: narrow balance asset_type before reading asset_code / asset_issuer (liquidity-pool shares carry neither); nextCursor derived from the last record so a full page still yields a cursor. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
|
@graceful-tech12 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #803 (BE-050 — Escrow-based payout service).
Implements time-locked escrow for tutor earnings in BackendAcademy: accrue on confirmed contributions, unlock per the tutor's payout schedule (BE-082), withdraw endpoint.
Acceptance criteria
withdraw()before the earliest unlock throwsESCROW_LOCKED(400) naming the earliest unlock time; funds remain held.releaseUnlocked()flips entries tounlockedexactly when their unlock time arrives (idempotent), after which withdrawal succeeds.What's included
EscrowPayoutServicewith alocked → unlocked → withdrawnlifecycle; unlock times computed byTutorPayoutScheduleServiceat accrual time so later schedule changes never shift existing entries. Amounts in stroops (bigint), carried as strings on the wire./api/v1/escrow:POST accrue|withdraw|release,GET tutors/:id/entries|balance|withdrawals.UsersModulewiring the service + controller into the app.003_tutor_escrow.sqlwith the durable schema (entries, withdrawals, line items) and index for the unlock job scan.Repairs to main (needed for tests/CI to pass)
While getting the suite green I found
mainwas already broken; this PR also fixes:BackendAcademy/src/courses/courses.controller.tshad two files concatenated (syntax error) — restored both the v1 controller and the legacy/api/coursescontroller thattest/courses.e2e-spec.tsexercises, and registeredCoursesServiceinCoursesModule.chat/registration.ts,health/wallet.ts,health/coverage.tswere stale duplicates importing modules that don't exist at their paths — removed.ChatRoomServicethatchat-room.service.spec.tsexpects.TooManyRequestsExceptiondoesn't exist in@nestjs/commonv10 — defined locally in the two modules that need it (chat moderation, submission protection).horizon.service: narrowasset_typebefore readingasset_code/asset_issuer(liquidity-pool shares carry neither);nextCursornow derived from the last record so a full page still yields a cursor (fixeshorizon.service.spec.ts).Verification
pnpm type-check(BackendAcademy): cleanpnpm test(BackendAcademy): 19 suites / 163 tests passingpnpm test:e2e(BackendAcademy): 5 suites / 8 tests passingpnpm build(BackendAcademy): clean🤖 Generated with Codebuff
Co-Authored-By: Codebuff noreply@codebuff.com