Skip to content

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

Closed
thefadah wants to merge 1 commit into
vjuliaife:mainfrom
thefadah:tariff-1043-1044-1049
Closed

feat: deposit receipt reset (#1049), developer usage dashboard (#1043), onboarding drip campaign (#1044)#1176
thefadah wants to merge 1 commit into
vjuliaife:mainfrom
thefadah:tariff-1043-1044-1049

Conversation

@thefadah

Copy link
Copy Markdown

#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.
@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:17pm

@vercel

vercel Bot commented Aug 28, 2026

Copy link
Copy Markdown

Deployment failed for project tariff-shield-web with the following error:

The `vercel.json` schema validation failed with the following message: should NOT have additional property `rootDirectory`

Learn More: https://vercel.com/docs/concepts/projects/project-configuration

@thefadah

Copy link
Copy Markdown
Author

Superseded by #1177 (raised from the correct account). Closing this one.

@thefadah thefadah closed this 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

1 participant