Members
Members are users within your application with specific roles and attributes. On this page, we'll dive into the different member endpoints you can use to manage members programmatically. We'll look at how to query, create, update, and delete members.
The member model
The member model extends from the profile model and includes detailed information about the member, including their status, activity logs, medical records, and membership details.
Properties
- Name
id- Type
- string
- Description
Unique identifier for the member.
- Name
firstName- Type
- string
- Description
The first name of the member.
- Name
lastName- Type
- string
- Description
The last name of the member.
- Name
email- Type
- string
- Description
The email address of the member.
- Name
role- Type
- enum
- Description
The role of the member, can be one of:
- root
- admin
- member
- employee
- Name
avatar- Type
- string
- Description
The avatar URL for the member.
- Name
createdAt- Type
- string
- Description
Timestamp of when the member was created.
- Name
updatedAt- Type
- string
- Description
Timestamp of when the member was last updated.
- Name
bornDate- Type
- string
- Description
The birthdate of the member.
- Name
document- Type
- string
- Description
The document identifier for the member.
- Name
address- Type
- string
- Description
The address of the member.
- Name
phoneNumber- Type
- string
- Description
The phone number of the member.
- Name
phoneCountry- Type
- string
- Description
The country code for the member's phone number.
- Name
onboardingStep- Type
- enum
- Description
The current onboarding step for the member, can be one of:
- PhoneVerification
- HasReprocann
- PersonalInformation
- Schedule
- Payment
- ReprocannSyncCode
- MedicalConsultation
- DocumentSigning
- ReprocannPending
- Contract
- MembershipSelection
- Done
- Name
medicalRecord- Type
- object
- Description
The medical record details for the member.
- Name
reprocannCode- Type
- string
- Description
The Reprocann code for the member.
- Name
reprocannExpiration- Type
- string
- Description
The expiration date of the Reprocann code.
- Name
emergencyContact- Type
- object
- Description
The emergency contact details.
- Name
name- Type
- string
- Description
The name of the emergency contact.
- Name
phoneNumber- Type
- string
- Description
The phone number of the emergency contact.
- Name
relationship- Type
- string
- Description
The relationship to the member.
- Name
allergies- Type
- array
- Description
List of allergies.
- Name
diseases- Type
- array
- Description
List of diseases.
- Name
medications- Type
- array
- Description
List of medications.
- Name
treatments- Type
- array
- Description
List of treatments.
- Name
diagnostic- Type
- array
- Description
List of diagnostics.
- Name
cannabisUses- Type
- array
- Description
List of cannabis uses.
- Name
membership- Type
- object
- Description
The membership details for the member.
- Name
id- Type
- string
- Description
Unique identifier for the membership.
- Name
name- Type
- string
- Description
The name of the membership.
- Name
dueDate- Type
- string
- Description
The due date for the membership payment.
- Name
expirationDate- Type
- string
- Description
The expiration date of the membership.
- Name
status- Type
- enum
- Description
The status of the membership, can be one of:
- PAID
- PENDING
- EXPIRED
- INACTIVE
- Name
paymentMethod- Type
- string
- Description
The payment method used for the membership.
- Name
price- Type
- number
- Description
The price of the membership.
- Name
status- Type
- enum
- Description
The status of the member. Can be one of:
- INVITED: Invitation sent, not yet registered
- IN_REVIEW: Registration received, pending approval
- APPROVED: Approved, completing activation wizard
- IN_PROGRESS: Completing onboarding process
- ACTIVE: Full access to dispensary
- DEBTOR: Payment pending, limited access
- INACTIVE: Suspended or deactivated
- Name
addresses- Type
- array
- Description
Array of delivery addresses for the member.
- Name
hasReprocann- Type
- boolean
- Description
Whether the member has REPROCANN registration.
- Name
permissions- Type
- array
- Description
Array of permission strings (only for staff roles).
Complete member example
{
"id": "usr_01HQ8XYZABC123",
"firstName": "María",
"lastName": "González",
"email": "maria.gonzalez@email.com",
"role": "member",
"avatar": "https://storage.cannahub.tech/avatars/maria-g.jpg",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-03-20T14:22:00Z",
"bornDate": "1985-06-20",
"document": "35123456",
"address": "Av. Corrientes 1234, CABA",
"phoneNumber": "1145678901",
"phoneCountry": "54",
"onboardingStep": "Done",
"medicalRecord": {
"reprocannCode": "REPRO-2024-AR-001234",
"reprocannExpiration": "2025-01-15",
"emergencyContact": {
"name": "Carlos González",
"phoneNumber": "+541145678902",
"relationship": "Hermano"
},
"allergies": ["Polen", "Penicilina"],
"diseases": ["Ansiedad crónica", "Insomnio"],
"medications": ["Sertralina 50mg"],
"treatments": ["Terapia cognitivo-conductual"],
"diagnostic": ["Trastorno de ansiedad generalizada"],
"cannabisUses": [
"Manejo de ansiedad",
"Mejora del sueño",
"Relajación muscular"
]
},
"membership": {
"id": "mbr_01HQ9ABC456",
"name": "Premium",
"dueDate": "2024-04-01",
"expirationDate": "2025-01-15",
"status": "PAID",
"paymentMethod": "MercadoPago",
"price": 12000
},
"status": "ACTIVE",
"addresses": [
{
"id": "addr_01HQ9XYZ789",
"name": "Casa",
"customerId": "usr_01HQ8XYZABC123",
"address1": "Av. Corrientes 1234",
"address2": "Piso 5, Depto A",
"city": "Ciudad Autónoma de Buenos Aires",
"state": "CABA",
"postalCode": "C1043",
"countryCode": "AR",
"phone": "+541145678901",
"company": "",
"isDefaultBilling": true,
"isDefaultShipping": true
}
],
"hasReprocann": true,
"nextAppointment": null,
"referrer": null,
"referrals": []
}
Field Mapping Reference
Cannahub uses Medusa.js as the backend e-commerce platform. Here's how frontend types map to the Medusa API:
Member ↔ Customer Mapping
| Cannahub Frontend | Medusa API | Type | Notes |
|---|---|---|---|
id | customer.id | string | Medusa customer ID |
firstName | customer.first_name | string | - |
lastName | customer.last_name | string | - |
email | customer.email | string | Unique identifier |
phoneNumber | customer.phone | string | With country code |
addresses | customer.shipping_addresses | Address[] | Array of delivery addresses |
createdAt | customer.created_at | timestamp | - |
updatedAt | customer.updated_at | timestamp | - |
role | customer.metadata.role | enum | Stored in metadata |
status | customer.metadata.status | enum | Member status |
onboardingStep | customer.metadata.onboardingStep | enum | Current step in onboarding |
medicalRecord | customer.metadata.medicalRecord | object | Full medical record object |
membership | customer.metadata.membership | object | Membership details |
hasReprocann | customer.metadata.hasReprocann | boolean | - |
avatar | customer.metadata.avatar | string (URL) | Profile image URL |
bornDate | customer.metadata.bornDate | string | ISO date format |
document | customer.metadata.document | string | DNI or ID number |
Complete Metadata Structure
The customer.metadata field in Medusa contains all Cannahub-specific data:
{
"metadata": {
"role": "member",
"status": "ACTIVE",
"onboardingStep": "Done",
"hasReprocann": true,
"avatar": "https://storage.cannahub.tech/avatars/user-123.jpg",
"bornDate": "1985-06-20",
"document": "35123456",
"phoneCountry": "54",
"medicalRecord": {
"reprocannCode": "REPRO-2024-AR-001234",
"reprocannExpiration": "2025-01-15",
"emergencyContact": {
"name": "Carlos González",
"phoneNumber": "+541145678902",
"relationship": "Hermano"
},
"allergies": ["Polen", "Penicilina"],
"diseases": ["Ansiedad crónica", "Insomnio"],
"medications": ["Sertralina 50mg"],
"treatments": ["Terapia cognitivo-conductual"],
"diagnostic": ["Trastorno de ansiedad generalizada"],
"cannabisUses": [
"Manejo de ansiedad",
"Mejora del sueño"
]
},
"membership": {
"id": "mbr_01HQ9ABC456",
"name": "Premium",
"dueDate": "2024-04-01",
"expirationDate": "2025-01-15",
"status": "PAID",
"paymentMethod": "MercadoPago",
"price": 12000
},
"nextAppointment": null,
"referrer": null,
"permissions": []
}
}
List all members
This endpoint allows you to retrieve a paginated list of all your members. By default, a maximum of ten members are shown per page.
Optional attributes
- Name
limit- Type
- integer
- Description
Limit the number of members returned.
- Name
offset- Type
- integer
- Description
Start offset of members returned.
- Name
search- Type
- text
- Description
Search by name or email.
Request
curl -G https://yourapp.com/api/members \
-H "Authorization: Bearer {token}" \
-d limit=10
Response
[
{
"id": "l7cGNIBKZiNJ6wqF",
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"role": "member",
"avatar": "https://assets.yourapp.com/avatars/johndoe.jpg",
"createdAt": "2023-05-13T12:00:00Z",
"updatedAt": "2023-06-13T12:00:00Z",
"bornDate": "1990-01-01",
"document": "123456789",
"address": "123 Main St",
"phoneNumber": "234567890",
"phoneCountry": "1",
"onboardingStep": "completed",
"medicalRecord": {
"reprocannCode": "ABC123",
"reprocannExpiration": "2024-05-13",
"emergencyContact": {
"name": "Jane Doe",
"phoneNumber": "+1234567891",
"relationship": "Spouse"
},
"allergies": ["Peanuts"],
"diseases": ["Hypertension"],
"medications": ["Amlodipine"],
"treatments": ["Blood pressure monitoring"],
"diagnostic": ["High blood pressure"],
"cannabisUses": ["Chronic pain"]
},
"membership": {
"id": "m1n2o3p4",
"name": "Premium",
"dueDate": "2023-12-31",
"expirationDate": "2024-05-13",
"status": "PAID",
"paymentMethod": "Credit Card",
"price": 99.99
},
"status": "ACTIVE",
}
]
Create a member
This endpoint allows you to create a new member in your application.
Medusa Reference
Required attributes
- Name
firstName- Type
- string
- Description
The first name of the member.
- Name
lastName- Type
- string
- Description
The last name of the member.
- Name
email- Type
- string
- Description
The email address of the member.
- Name
role- Type
- enum
- Description
The role of the member
Optional attributes
- Name
avatar- Type
- string
- Description
The avatar URL for the member.
- Name
bornDate- Type
- string
- Description
The birthdate of the member.
- Name
document- Type
- string
- Description
The document identifier for the member.
- Name
address- Type
- string
- Description
The address of the member.
- Name
phoneNumber- Type
- string
- Description
The phone number of the member.
- Name
phoneCountry- Type
- string
- Description
The country code for the member's phone number.
- Name
medicalRecord- Type
- object
- Description
The medical record details for the member.
- Name
reprocannCode- Type
- string
- Description
The Reprocann code for the member.
- Name
reprocannExpiration- Type
- string
- Description
The expiration date of the Reprocann code.
- Name
emergencyContact- Type
- object
- Description
The emergency contact details.
- Name
name- Type
- string
- Description
The name of the emergency contact.
- Name
phoneNumber- Type
- string
- Description
The phone number of the emergency contact.
- Name
relationship- Type
- string
- Description
The relationship to the member.
- Name
allergies- Type
- array
- Description
List of allergies.
- Name
diseases- Type
- array
- Description
List of diseases.
- Name
medications- Type
- array
- Description
List of medications.
- Name
treatments- Type
- array
- Description
List of treatments.
- Name
diagnostic- Type
- array
- Description
List of diagnostics.
- Name
cannabisUses- Type
- array
- Description
List of cannabis uses.
- Name
membership- Type
- object
- Description
The membership details for the member.
- Name
id- Type
- string
- Description
Unique identifier for the membership.
- Name
name- Type
- string
- Description
The name of the membership.
- Name
dueDate- Type
- string
- Description
The due date for the membership payment.
- Name
expirationDate- Type
- string
- Description
The expiration date of the membership.
- Name
status- Type
- enum
- Description
The status of the membership, can be one of:
- Name
paymentMethod- Type
- string
- Description
The payment method used for the membership.
- Name
price- Type
- number
- Description
The price of the membership.
- Name
status- Type
- enum
- Description
The status of the member.
Request
curl -X POST https://yourapp.com/api/members \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com"
}'
Response
{
"id": "l7cGNIBKZiNJ6wqF",
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"role": "member",
"avatar": null,
"createdAt": "2023-05-13T12:00:00Z",
"updatedAt": "2023-06-13T12:00:00Z",
"bornDate": null,
"document": null,
"address": null,
"phoneNumber": null,
"phoneCountry": null,
"onboardingStep": null,
"medicalRecord": null,
"membership": null,
"status": "ACTIVE"
}
Update a member
This endpoint allows you to update an existing member in your application.
Medusa Reference
Optional attributes
- Name
firstName- Type
- string
- Description
The first name of the member.
- Name
lastName- Type
- string
- Description
The last name of the member.
- Name
email- Type
- string
- Description
The email address of the member.
- Name
avatar- Type
- string
- Description
The avatar URL for the member.
- Name
bornDate- Type
- string
- Description
The birthdate of the member.
- Name
document- Type
- string
- Description
The document identifier for the member.
- Name
address- Type
- string
- Description
The address of the member.
- Name
phoneNumber- Type
- string
- Description
The phone number of the member.
- Name
phoneCountry- Type
- string
- Description
The country code for the member's phone number.
- Name
medicalRecord- Type
- object
- Description
The medical record details for the member.
- Name
reprocannCode- Type
- string
- Description
The Reprocann code for the member.
- Name
reprocannExpiration- Type
- string
- Description
The expiration date of the Reprocann code.
- Name
emergencyContact- Type
- object
- Description
The emergency contact details.
- Name
name- Type
- string
- Description
The name of the emergency contact.
- Name
phoneNumber- Type
- string
- Description
The phone number of the emergency contact.
- Name
relationship- Type
- string
- Description
The relationship to the member.
- Name
allergies- Type
- array
- Description
List of allergies.
- Name
diseases- Type
- array
- Description
List of diseases.
- Name
medications- Type
- array
- Description
List of medications.
- Name
treatments- Type
- array
- Description
List of treatments.
- Name
diagnostic- Type
- array
- Description
List of diagnostics.
- Name
cannabisUses- Type
- array
- Description
List of cannabis uses.
- Name
membership- Type
- object
- Description
The membership details for the member.
- Name
id- Type
- string
- Description
Unique identifier for the membership.
- Name
name- Type
- string
- Description
The name of the membership.
- Name
dueDate- Type
- string
- Description
The due date for the membership payment.
- Name
expirationDate- Type
- string
- Description
The expiration date of the membership.
- Name
status- Type
- enum
- Description
The status of the membership
- Name
paymentMethod- Type
- string
- Description
The payment method used for the membership.
- Name
price- Type
- number
- Description
The price of the membership.
- Name
status- Type
- enum
- Description
The status of the member.
Request
curl -X PUT https://yourapp.com/api/members/l7cGNIBKZiNJ6wqF \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com"
}'
Response
{
"id": "l7cGNIBKZiNJ6wqF",
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"role": "member",
"avatar": "https://assets.yourapp.com/avatars/johndoe.jpg",
"createdAt": "2023-05-13T12:00:00Z",
"updatedAt": "2023-06-13T12:00:00Z",
"bornDate": "1990-01-01",
"document": "123456789",
"address": "123 Main St",
"phoneNumber": "+1234567890",
"phoneCountry": "1",
"onboardingStep": "completed",
"medicalRecord": {
"reprocannCode": "ABC123",
"reprocannExpiration": "2024-05-13",
"emergencyContact": {
"name": "Jane Doe",
"phoneNumber": "+1234567891",
"relationship": "Spouse"
},
"allergies": ["Peanuts"],
"diseases": ["Hypertension"],
"medications": ["Amlodipine"],
"treatments": ["Blood pressure monitoring"],
"diagnostic": ["High blood pressure"],
"cannabisUses": ["Chronic pain"]
},
"membership": {
"id": "m1n2o3p4",
"name": "Premium",
"dueDate": "2023-12-31",
"expirationDate": "2024-05-13",
"status": "PAID",
"paymentMethod": "Credit Card",
"price": 99.99
},
"status": "ACTIVE"
}
Update member status
This endpoint allows you to update the status of an existing member.
Required attributes
- Name
status- Type
- enum
- Description
The status of the member, can be one of:
- INVITED
- IN_REVIEW
- APPROVED
- IN_PROGRESS
- ACTIVE
- DEBTOR
- INACTIVE
Request
curl -X POST https://yourapp.com/api/members/l7cGNIBKZiNJ6wqF/status \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"status": "ACTIVE"
}'
Response
{
"id": "l7cGNIBKZiNJ6wqF",
"status": "ACTIVE"
}
BFF Route: Perfil Completo
Esta ruta BFF retorna el perfil completo de un miembro con todos sus datos relacionados en una sola llamada. Agrega información de órdenes, membresía, historial médico y actividad.
Problema que resuelve
Flujo actual (4+ calls):
1. GET /admin/customers/:id → Perfil básico
2. GET /admin/orders?customer_id=:id → Historial de órdenes
3. GET /admin/customer-groups/:id → Detalles de membresía
4. GET /api/appointments?user=:id → Citas médicas
5. GET /api/activities?user=:id → Log de actividad
Query Parameters
- Name
includeOrders- Type
- boolean
- Description
Incluir historial de órdenes (default: true).
- Name
ordersLimit- Type
- number
- Description
Límite de órdenes a incluir (default: 10).
- Name
includeMedical- Type
- boolean
- Description
Incluir historial médico completo (default: true).
- Name
includeActivity- Type
- boolean
- Description
Incluir log de actividad (default: false).
Response
- Name
member- Type
- User
- Description
Perfil completo del miembro (incluye membership y medicalRecord en el objeto).
- Name
orders- Type
- Order[]
- Description
Historial de órdenes del miembro.
- Name
stats- Type
- MemberStats
- Description
Estadísticas del miembro.
- Name
totalOrders- Type
- number
- Description
Total de órdenes realizadas.
- Name
totalSpent- Type
- number
- Description
Total gastado en el club (en centavos).
- Name
monthlyAverage- Type
- number
- Description
Promedio mensual de gasto.
- Name
favoriteStrains- Type
- string[]
- Description
Nombres de las cepas más compradas (top 3).
- Name
memberSince- Type
- string
- Description
Fecha de alta como miembro (ISO timestamp).
Request
curl "https://api.cannahub.tech/api/members/usr_01HQ8XYZABC123/complete" \
-H "Authorization: Bearer {token}"
Response
{
"member": {
"id": "usr_01HQ8XYZABC123",
"firstName": "María",
"lastName": "González",
"email": "maria.gonzalez@email.com",
"role": "member",
"status": "ACTIVE",
"avatar": "https://storage.cannahub.tech/avatars/maria-g.jpg",
"phoneNumber": "+541145678901",
"document": "35123456",
"bornDate": "1985-06-20",
"onboardingStep": "Done",
"hasReprocann": true,
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-03-20T14:22:00Z",
"membership": {
"id": "mbr_01HQ9ABC456",
"name": "Premium",
"status": "PAID",
"expirationDate": "2025-01-15",
"price": 12000
},
"medicalRecord": {
"reprocannCode": "REPRO-2024-AR-001234",
"reprocannExpiration": "2025-01-15",
"allergies": ["Polen", "Penicilina"],
"diseases": ["Ansiedad crónica", "Insomnio"],
"medications": ["Sertralina 50mg"],
"treatments": ["Terapia cognitivo-conductual"],
"diagnostic": ["Trastorno de ansiedad generalizada"],
"cannabisUses": ["Manejo de ansiedad", "Mejora del sueño"],
"emergencyContact": {
"name": "Carlos González",
"phoneNumber": "+541145678902",
"relationship": "Hermano"
}
}
},
"orders": [
{
"id": "order_01HQ9ORDER001",
"displayId": 1234,
"status": "completed",
"total": 350000,
"subtotal": 320000,
"taxTotal": 30000,
"currencyCode": "ARS",
"paymentStatus": "captured",
"fulfillmentStatus": "fulfilled",
"createdAt": "2024-03-15T14:30:00Z",
"items": [
{
"id": "item_001",
"name": "Blue Dream 3.5g",
"quantity": 2,
"unitPrice": 175000,
"total": 350000
}
]
}
],
"stats": {
"totalOrders": 15,
"totalSpent": 2500000,
"monthlyAverage": 208333,
"favoriteStrains": ["Blue Dream", "OG Kush", "Sour Diesel"],
"memberSince": "2024-01-15T10:30:00Z"
}
}
Flujo interno del BFF
Comparación de rendimiento
| Métrica | Sin BFF | Con BFF | Mejora |
|---|---|---|---|
| Llamadas API | 4-5 | 1 | -80% |
| Latencia típica | ~800ms | ~250ms | -69% |
| Cálculo de stats | Cliente | Servidor | Centralizado |
| Validación REPROCANN | Manual | Automático | Incluido |
Casos de uso
- Panel de administrador: Ver perfil completo de un miembro
- Atención al cliente: Consultar historial rápidamente
- Dashboard de miembro: Mostrar resumen personalizado
- Dispensación: Verificar estado y límites antes de venta
Delete a member
This endpoint allows you to delete an existing member from your organization.
Deleting a member is a permanent action. Consider using status change to INACTIVE instead for most cases.
Request
curl -X DELETE https://api.cannahub.tech/api/members/usr_01HQ8XYZABC123 \
-H "Authorization: Bearer {token}"
Response
{
"success": true
}
React Query Hooks
Cannahub provides pre-built React Query hooks for managing members. These hooks interact with the BFF API routes and handle caching, invalidation, and error handling automatically.
Query Keys
// /features/Club/Members/hooks/keys.ts
export const memberKeys = {
all: ['members'] as const,
lists: () => [...memberKeys.all, 'list'] as const,
list: (filters?: MemberFilters) => [...memberKeys.lists(), filters] as const,
details: () => [...memberKeys.all, 'detail'] as const,
detail: (id: string) => [...memberKeys.details(), id] as const,
complete: (id: string) => [...memberKeys.detail(id), 'complete'] as const,
}
export const membershipKeys = {
all: ['memberships'] as const,
lists: () => [...membershipKeys.all, 'list'] as const,
list: () => [...membershipKeys.lists()] as const,
details: () => [...membershipKeys.all, 'detail'] as const,
detail: (id: string) => [...membershipKeys.details(), id] as const,
}
Queries
import { useMembersQuery, useMemberQuery, useMemberCompleteQuery } from '@/features/Club/Members/hooks'
// List all members with optional filters
const { data, isLoading } = useMembersQuery({
page: '1',
search: 'maria',
status: 'ACTIVE'
})
// Get a single member
const { data: member } = useMemberQuery('usr_01HQ8XYZABC123')
// Get complete member profile with orders and stats
const { data: profile } = useMemberCompleteQuery('usr_01HQ8XYZABC123')
Mutations
import {
useCreateMemberMutation,
useUpdateMemberMutation,
useUpdateMemberStatusMutation,
useDeleteMemberMutation
} from '@/features/Club/Members/hooks'
// Create a new member
const { mutate: createMember } = useCreateMemberMutation()
createMember({
data: {
firstName: 'Juan',
lastName: 'Perez',
email: 'juan@example.com',
status: MemberStatus.INVITED
}
})
// Update a member
const { mutate: updateMember } = useUpdateMemberMutation()
updateMember({
id: 'usr_01HQ8XYZABC123',
data: { firstName: 'María', phoneNumber: '1145678901' }
})
// Update member status only
const { mutate: updateStatus } = useUpdateMemberStatusMutation()
updateStatus({
id: 'usr_01HQ8XYZABC123',
status: MemberStatus.APPROVED
})
// Delete a member
const { mutate: deleteMember } = useDeleteMemberMutation()
deleteMember('usr_01HQ8XYZABC123')
Cache Invalidation
All mutations automatically invalidate relevant query keys on success:
// After successful mutation, these queries are invalidated:
queryClient.invalidateQueries({ queryKey: memberKeys.detail(id) })
queryClient.invalidateQueries({ queryKey: memberKeys.all })
Member Status Flow
The member lifecycle follows a defined state machine:
INVITED → IN_REVIEW → APPROVED → IN_PROGRESS → ACTIVE
↓
DEBTOR
↓
INACTIVE
Status Transitions
| From | To | Trigger |
|---|---|---|
| INVITED | IN_REVIEW | Member completes registration |
| IN_REVIEW | APPROVED | Admin approves member |
| IN_REVIEW | INACTIVE | Admin rejects member |
| APPROVED | IN_PROGRESS | Member starts onboarding |
| IN_PROGRESS | ACTIVE | Member completes onboarding |
| ACTIVE | DEBTOR | Payment overdue |
| DEBTOR | ACTIVE | Payment received |
| DEBTOR | INACTIVE | Extended non-payment |
| ACTIVE | INACTIVE | Manual deactivation |