feat: add institutional membership tiers and correct member directory
Corrections per 2026-04 institutional review:
- MLFO reclassified as Global Family Office (was incorrectly labeled central bank)
- BIS Innovation Hub reclassified as Standards Body (does not hold observer seat)
- Added missing entities: ICCC, SAID, PANDA, Order of Hospitallers (XOM)
- Added BRICS founding + expanded member central banks (10 entries)
New institutional tier taxonomy (7 tiers):
sovereign_central_bank, global_family_office, settlement_member,
infrastructure_operator, oversight_judicial, delegated_authority,
standards_body
Backend changes:
- New auth/membership.go: tier types, DefaultTrackForTier mapping,
MembershipStore with DB queries for member directory
- New migration 0017: institutional_members + institutional_member_wallets
tables with seed data for all corrected members
- Updated wallet_auth.go getUserTrack(): now resolves institutional
membership (via wallet junction table) before defaulting to Track 1
- WalletAuthResponse now includes institutional_tier and institution_name
- New REST endpoints: GET /api/v1/membership/{tiers,members,members/:slug}
- Added TrackLabel() helper in featureflags
Frontend changes:
- Added InstitutionalTier type and label map to access.ts
- WalletAccessSession extended with institutionalTier/institutionName
- Navbar getAccessTier() now displays institutional tier label when present
- Session summary shows institution name
Co-Authored-By: Nakamoto, S <defi@defi-oracle.io>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import Link from 'next/link'
|
||||
import { usePathname, useRouter } from 'next/navigation'
|
||||
import { type ReactNode, useEffect, useId, useMemo, useRef, useState } from 'react'
|
||||
import { accessApi, type WalletAccessSession } from '@/services/api/access'
|
||||
import { accessApi, institutionalTierLabels, type WalletAccessSession } from '@/services/api/access'
|
||||
import BrandLockup from './BrandLockup'
|
||||
import HeaderCommandPalette, { type HeaderCommandItem } from './HeaderCommandPalette'
|
||||
import { useUiMode } from './UiModeContext'
|
||||
@@ -310,6 +310,9 @@ function SearchControl({
|
||||
}
|
||||
|
||||
function getAccessTier(walletSession: WalletAccessSession) {
|
||||
if (walletSession.institutionalTier) {
|
||||
return institutionalTierLabels[walletSession.institutionalTier] ?? walletSession.institutionalTier
|
||||
}
|
||||
const permissions = walletSession.permissions || []
|
||||
if (permissions.some((permission) => permission.startsWith('operator.'))) {
|
||||
return 'Operator Tier'
|
||||
@@ -326,10 +329,11 @@ function getAccessTier(walletSession: WalletAccessSession) {
|
||||
function getSessionSummary(walletSession: WalletAccessSession) {
|
||||
const permissionCount = walletSession.permissions?.length || 0
|
||||
const tierLabel = getAccessTier(walletSession)
|
||||
const institutionSuffix = walletSession.institutionName ? ` (${walletSession.institutionName})` : ''
|
||||
if (permissionCount > 0) {
|
||||
return `${tierLabel} · ${permissionCount} permission${permissionCount === 1 ? '' : 's'}`
|
||||
return `${tierLabel}${institutionSuffix} · ${permissionCount} permission${permissionCount === 1 ? '' : 's'}`
|
||||
}
|
||||
return `${tierLabel} · Explorer access active`
|
||||
return `${tierLabel}${institutionSuffix} · Explorer access active`
|
||||
}
|
||||
|
||||
function UiModeToggle({ mobile = false }: { mobile?: boolean }) {
|
||||
|
||||
Reference in New Issue
Block a user