Skip to content

feat(partner): add /partner dashboard for partner self-service#1114

Draft
TaprootFreak wants to merge 1 commit into
developfrom
feat/partner-dashboard
Draft

feat(partner): add /partner dashboard for partner self-service#1114
TaprootFreak wants to merge 1 commit into
developfrom
feat/partner-dashboard

Conversation

@TaprootFreak

Copy link
Copy Markdown
Collaborator

Summary

  • New /partner route family on app.dfx.swiss, gated by usePartnerGuard (Admin + Partner)
  • Three lazy-loaded screens:
    • /partner — hub with two tiles
    • /partner/onboarding — lookup-by-address form, fee dropdown, Set Fee + Activate / Remove Fee buttons
    • /partner/history — table of all users currently linked to caller's usedRef
  • usePartner hook with 5 methods against /v1/partner/* (api#3787)
  • Local PartnerUserInfo / PartnerFee DTOs (admin-style, mirrors compliance.hook pattern)

Why

Referral partners like Fab today rely on the internal DFX Admin Google Sheet (operated by the Compliance team) to set custom onboarding fees on their referees. This PR moves that workflow into a self-service UI on app.dfx.swiss, paired with backend scope enforcement.

Dependencies

  • Hard: api#3787 — adds UserRole.PARTNER + /v1/partner/* endpoints with server-side scope check (caller can only act on users with usedRef ∈ { defaultRef, caller.ref })
  • Soft: packages#178PARTNER enum value + PartnerUrl constants in @dfx.swiss/core. Not consumed in this PR (cast workaround in guard.hook.ts); a follow-up can migrate to native UserRole.PARTNER once packages 1.4.0-beta.2 is published.

Operational notes

  • After merge to DEV: set Fab's test-account user.role = 'Partner' via DB to test scope behaviour.
  • After merge to PROD: same one-off UPDATE for the actual partner accounts.

Test plan

  • npm run lint clean
  • npm run build:lib (tsc) clean
  • npm run test — 283 passed
  • npm run build:dev clean
  • DEV: login as test partner (role=Partner, ref=158-532), navigate /partner
  • /partner/onboarding: paste an unowned address → Lookup → see UserCard with canModify=true → pick fee → Set → success, UserCard refreshes with new fee + Active + caller's ref
  • Remove Fee on a fee that's currently assigned → success
  • Lookup an address with another partner's usedRefcanModify=false, dropdown disabled, message visible
  • /partner/history: see table of own referees
  • Non-partner login → redirect to /

Adds the frontend counterpart to DFXswiss/api#3787. Referral partners
(role=Partner) can now look up their referees, assign or remove
individual onboarding fees, and review their full referee list directly
on app.dfx.swiss — replacing the manual Google-Sheet workflow currently
operated by the Compliance team.

- usePartnerGuard (Admin + Partner)
- usePartner hook with 5 methods against /v1/partner/* endpoints
- Local PartnerUserInfo / PartnerFee DTOs (admin-style, mirrors
  compliance.hook pattern; can later migrate to @dfx.swiss/react once
  packages 1.4.0-beta.2 is consumed)
- Routes:
    /partner            → hub (set-fee tile + referees tile)
    /partner/onboarding → lookup-by-address form + fee dropdown
                           + Set / Remove buttons, server enforces scope
    /partner/history    → table of all users with usedRef == caller.ref
- PartnerUserCard component for the lookup result

Backend scope enforcement (api#3787) guarantees the partner can only
touch users whose usedRef is either empty (defaultRef '000-000') or
equal to the caller's own ref; UI surfaces this via the canModify flag.
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.

1 participant