Skip to content

feat: deposit receipt reset (#1049), developer usage dashboard (#1043), onboarding drip campaign (#1044) - #1177

Merged
vjuliaife merged 1 commit into
vjuliaife:mainfrom
bade2brazy:tariff-1043-1044-1049
Aug 29, 2026
Merged

feat: deposit receipt reset (#1049), developer usage dashboard (#1043), onboarding drip campaign (#1044)#1177
vjuliaife merged 1 commit into
vjuliaife:mainfrom
bade2brazy:tariff-1043-1044-1049

Conversation

@bade2brazy

Copy link
Copy Markdown
Contributor

#1049 — Deposit receipt is no longer a dead end

DepositWizard's receipt step gains two actions:

  • Make another depositresetWizard() returns step/xlm/txHash/busy to the amount step, clearing the previous txHash so the next receipt can't show a stale hash.
  • DonehandleCancel() (resets + fires the optional onCancel).

The receipt stays rendered until the user picks one of these — nothing auto-navigates away.

#1043 — Developer dashboard: API usage & rate-limit status

There is no API-key auth gate in front of the REST API today, so this meters rather than enforces.

  • Metering — a global, non-gating middleware (apiKeyUsageMeter) records requests that carry a recognised X-Api-Key into per-(key, endpoint category, minute) buckets in the new api_key_usage table. rate_limit_per_min is a new nullable column on api_keys (NULL = no configured limit → volume only, no quota indicator).
  • RetentionstartApiKeyUsagePruneScheduler sweeps buckets older than 30 days daily.
  • API (authMiddleware + privacy/ToS gates):
    • GET /developer/keys — the caller's keys (metadata only)
    • GET /developer/keys/:id/usage — rollup for one key
    • GET /developer/usage — rollup across all the caller's active keys
    • Response: requests per hour (24h), per day (30d), per endpoint category (24h), current-minute count, remaining, and approachingLimit (≥80% of the configured limit).
  • UI — new /developer page renders an inline-SVG hourly bar chart, a remaining-quota bar, the category breakdown, and a warning banner when approaching the limit.

#1044 — Onboarding drip campaign

The platform's delivery primitive is the in-app notifications table (see services/upgrade-notifications.ts), so drip "sends" are createNotification calls, not SMTP.

  • Signup enrolls importers into onboarding_drip_enrollments (best-effort — never fails signup).
  • startOnboardingDripScheduler (15 min) walks onboarding_drip_steps by position: when a step comes due (enrolled_at + delay_hours), it is sent, or skipped if the importer already did the action it nudges toward — kyc (importers.kyc_status='approved'), deposit (a deposit contract_events row), tariff (a tariff_uploads row). One step per enrollment per pass. When every active step has a send row the enrollment is marked completed_at and no longer processed.
  • POST /onboarding/drip/unsubscribe — importer opt-out, independent of transactional notifications.
  • GET /onboarding/drip — enrollment status + send log.
  • GET /onboarding/drip/steps, PUT /onboarding/drip/steps/:stepKeysurety_admin edits subject/body/delay_hours/is_active.

Migration 0008 adds api_key_usage, api_keys.rate_limit_per_min, and onboarding_drip_steps / _enrollments / _sends, seeding the default 3-step sequence.

⚠️ Pre-existing migration collision (not introduced here)

main currently has two 0006_ migrations — 0006_importers_and_events_perf_indexes.ts and 0006_stakeholder_subscriptions_annotations_sla.ts — which runner.ts rejects with "Duplicate migration version detected: 6". This PR's migration is numbered 0008 and runs cleanly once that collision is resolved (renumber one of the 0006s); it is not fixed here to avoid touching another issue's migration.

Notes

Not built or tested locally. No API-key auth/enforcement is added — #1043 is scoped to visibility. Drip emails are delivered as in-app notifications to match the existing notification infrastructure.

Closes #1049
Closes #1043
Closes #1044

- vjuliaife#1049: the DepositWizard receipt step gains 'Make another deposit'
  (resets step/xlm/txHash to the amount step, clearing the prior txHash)
  and 'Done' actions, so it is no longer a reload-only dead end.

- vjuliaife#1043: per-API-key request metering. A global, non-gating middleware
  meters traffic carrying a recognised X-Api-Key into minute buckets
  (api_key_usage, 30-day retention via a daily prune job). New
  GET /developer/usage, /developer/keys, /developer/keys/:id/usage return
  volume per hour/day, an endpoint-category breakdown, and current-minute
  count vs the optional per-key rate_limit_per_min with an
  'approaching limit' flag. New /developer page renders a usage chart,
  remaining-quota bar, and warning banner.

- vjuliaife#1044: onboarding drip campaign. Signup enrols importers
  (onboarding_drip_enrollments); a 15-minute scheduler walks the
  admin-editable onboarding_drip_steps sequence, sending each due step as
  an in-app notification or skipping it when the importer has already done
  the action (KYC / first deposit / tariff upload), and marks the
  enrollment complete when the sequence is exhausted. Importers can
  unsubscribe (POST /onboarding/drip/unsubscribe) without touching
  transactional notifications; admins edit content/timing via
  PUT /onboarding/drip/steps/:stepKey.

Migration 0008 adds api_key_usage, the api_keys.rate_limit_per_min column,
and the three onboarding_drip_* tables (with the default 3-step sequence
seeded).

Not built or tested locally.
@drips-wave

drips-wave Bot commented Aug 28, 2026

Copy link
Copy Markdown

@bade2brazy 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! 🚀

Learn more about application limits

@vercel

vercel Bot commented Aug 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tariff-shield-web Error Error Aug 28, 2026 7:31pm

@vjuliaife
vjuliaife merged commit d7aefec into vjuliaife:main Aug 29, 2026
1 of 2 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

2 participants