Skip to content

fix(api): complete unimplemented DB operations in plan API handlers - #1050

Merged
ONEONUORA merged 2 commits into
Fracverse:masterfrom
Pvsaint:fix/1037-complete-plan-api-db-operations
Aug 23, 2026
Merged

ONEONUORA merged 2 commits into
Fracverse:masterfrom
Pvsaint:fix/1037-complete-plan-api-db-operations

Conversation

@Pvsaint

@Pvsaint Pvsaint commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #1037

This PR completes all five unimplemented database operations in backend/src/api.rs that were marked with // Contributors: placeholder comments.


What was already implemented

After a thorough audit, three of the five handlers were fully implemented behind their placeholder comments and only needed the comments removed:

Handler Status before this PR
create_plan ✅ Full atomic SQL transaction — INSERT into plans then INSERT per beneficiary, COMMIT, webhook enqueue
update_plan ✅ BPS validation (sum must equal 10 000), transactional DELETE + re-INSERT of beneficiaries, grace period / yield field updates
get_plans ✅ Dynamic owner/beneficiary filtering, on-the-fly yield accumulation via compute_projected_accrued_yield, Redis cache with timing headers

What was genuinely missing and is now fixed

1. ping_plan — atomic ping log insertion (line 1180)

Before: The handler updated plans.last_ping and plans.accrued_yield with a bare execute call, then returned. No audit record was ever written to ping_logs.

After:

  • The UPDATE plans and the new INSERT INTO ping_logs are wrapped in a single BEGIN / COMMIT transaction, so both succeed or both roll back atomically.
  • The ping_logs row captures pinged_at (server NOW()) and accrued_yield_snapshot (the yield accumulated up to this ping), satisfying the audit-log requirement.
  • inactivity_deadline_at is a generated column (to_timestamp(last_ping + grace_period_seconds)) so it is kept in sync by Postgres automatically whenever last_ping is updated — no extra write needed.

2. trigger_payoutplan.settled webhook emission (line 1281)

Before: After committing the payout transaction and invalidating the cache the handler returned immediately. No webhook was dispatched.

After:

  • After cache invalidation, WebhookDispatcherService::enqueue_event is called with event type "plan.settled" and a JSON payload containing plan_id, owner, total_payout, status, and payout_count.
  • The call is non-blocking and non-fatal — a failure to enqueue is logged as a warn! and does not affect the HTTP response, keeping the payout itself fully atomic.

Testing

  • cargo build --no-default-features — clean build, zero errors.
  • cargo test --no-default-features --lib53/53 unit tests pass.
  • No new test infrastructure was required; the changes slot into the existing transaction patterns already established throughout the file.

…racverse#1037)

- create_plan: already had full atomic SQL transaction; remove stale placeholder comment
- update_plan: already had bps validation + transactional beneficiary replace; remove stale comment
- get_plans: already had owner/beneficiary filtering + on-the-fly yield via compute_projected_accrued_yield; remove stale comment
- ping_plan: wrap last_ping update + new ping_logs INSERT in a single transaction
  so both succeed or both roll back atomically; the generated column
  inactivity_deadline_at (last_ping + grace_period_seconds) is kept in sync
  automatically by Postgres; remove stale placeholder comment
- trigger_payout: enqueue a plan.settled webhook event via WebhookDispatcherService
  after the payout transaction commits (non-blocking, non-fatal on failure);
  remove stale placeholder comment

All 53 unit tests pass.

@ONEONUORA ONEONUORA 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.

Great job @Pvsaint

@ONEONUORA
ONEONUORA merged commit 7284a24 into Fracverse:master Aug 23, 2026
4 checks passed
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.

backend: Complete Unimplemented Database Operations in Plan API Handlers

2 participants