Client PortalMemberships
Group & Corporate Plans
Manage group memberships and corporate accounts with seat management
Manage group memberships for corporate clients and organizations with centralized billing and seat management.
Capabilities
| Action | ROLE_CLIENT_ADMIN | ROLE_CLIENT_USER |
|---|---|---|
| View group accounts | ✅ | ✅ |
| Create group plans | ✅ | ❌ |
| Manage seats | ✅ | ❌ |
| Assign members | ✅ | ❌ |
| View billing | ✅ | ❌ |
Features
Group Account Structure
Corporate Account
├── Administrator (billing contact)
├── Seat Allocation
│ ├── Total Seats: 50
│ ├── Occupied: 42
│ └── Available: 8
└── Members
├── Member 1
├── Member 2
└── ...
Acceptance Criteria
Frontend
- Group accounts list with member counts
- Group billing history view
- Seat management interface
- Member assignment with email invitation
- Bulk member upload via CSV
- Administrator management
- Seat utilization visualization
Backend / API
- Backend behavior supports this feature as documented.
Permissions
- Access is restricted per the Capabilities matrix on this page (or equivalent role rules).
Business Rules
- Member can only belong to one group at a time
- Group administrator must have valid email
- Group benefits apply to all members in group
- Seat count cannot be reduced below occupied seats
- Payment required before activation
- Seat price may differ from individual membership price
Error Handling
- Error states return clear messages and appropriate HTTP status codes.
Create Group Account
- Group Details
- Group Name (required)
- Group Description (required)
- Group Registration Date (required)
- Group Expiry Date (required)
- Pricing & Seats
- Number of Seats (required)
- Currency
- Price (may be custom per group)
- Membership Plan / Membership Pricing selection
- Administrator
- Group Admin selector (preferred)
- Fallback fields if selector is empty: First Name, Last Name, Email
- Member Seat Assignment
- Membership Plan selection per seat (repeater)
- Member First Name, Last Name, Email (per seat)
Acceptance Criteria
Frontend
- Create group wizard with step-by-step flow
Backend / API
- Backend behavior supports this feature as documented.
Permissions
- Access is restricted per the Capabilities matrix on this page (or equivalent role rules).
Business Rules
- All business rules for this feature are enforced.
Error Handling
- Error states return clear messages and appropriate HTTP status codes.
UI Spec (from supplied spreadsheet)
The following inventory is sourced from workspace/sources/entity-registry.csv ("Group Membership").
| Field | Input Type | Required | Notes |
|---|---|---|---|
| Group Name | Text | Required | model: name, rel: string |
| Group Description | Text | Required | model: description, rel: text |
| Group Registration Date | Date | Required | model: startDate, rel: datetime |
| Group Expiry Date | Date | Required | model: endDate, rel: datetime |
| Group ID | Number | Required | - |
| Is Custom Price | - | - | model: isCustomPrice, rel: boolean |
| Price | Number | Required | model: price, rel: float |
| Currency | - | - | model: currency, rel: string |
| Number of Seats | Number | Required | model: numberOfSeats, rel: integer |
| Members | - | - | model: members, rel: OneToMany MemberProfile |
| Membership Plan | - | - | model: membershipPlan, rel: ManyToOne MembershipPlan |
| Membership Period | - | - | model: MembershipPeriod, rel: ManyToOne MembershipPeriod |
| Membership Pricing | - | - | model: membershipPricing, rel: ManyToOne MembershipPricing |
| Is Automatically Archive | - | - | model: isAutomaticallyArchive, rel: boolean |
| Archive On | - | - | model: archiveOn, rel: datetime |
| Client | - | - | model: client, rel: ManyToOne ClientProfile |
| Group Admin | Selector | Required | model: groupAdmin |
| Group Admin First Name | Text | Required | - |
| Group Admin Last Name | Text | Required | - |
| Group Admin Email | Required | - | |
| Membership Plan (per seat) | Selector | Required | Repeater based on number of seats |
| Member First Name (per seat) | Text | Required | - |
| Member Last Name (per seat) | Text | Required | - |
| Member Email (per seat) | Required | - |
Data Model Cross‑Reference (Entities)
- Primary record:
Group / Corporate Membership - Seat/member assignment: typically a join entity (group ↔ members) rather than embedding large arrays
- Members referenced:
User / Member - Plan used for benefits/pricing:
Membership Plan
Company Industries (for corporate/group accounts)
Corporate/group accounts typically correspond to a Company Profile in the Directory.
- Industries are managed via the company’s Directory profile (not a separate “group plan” setting).
- The canonical field is the company profile’s industry/category field (entity:
CompanyProfile.industryCategory).
Where it’s managed:
- Client admins: Client Portal → Directory → Directory Management / Company Profile Approval
- Group admins (if enabled): Member Portal → Directory → My Company Profile
Data Model Cross‑Reference
- Company listing + industry field:
Company Profile
Acceptance Criteria
Frontend
- Group/corporate account screens link to the associated Company Profile for editing industry/category.
Backend / API
- Group/corporate accounts can be associated to a Company Profile (for shared identity + directory fields).
Permissions
- Only authorized client admins (and group admins, if enabled) can update company industry.
Business Rules
- Company industry/category values come from the Directory category/taxonomy configuration.
Error Handling
- If the Company Profile does not exist, the UI provides a guided way to create/link one.
Seat Management
Assign Seats
Add members to the group account:
- Navigate to group account
- Click "Add Member"
- Enter member email
- Member receives invitation
- Member joins under group
Remove Seats
Remove members from group:
- Select member to remove
- Confirm removal
- Seat becomes available
- Member loses group benefits
Transfer Seats
Move a seat from one member to another:
- Select occupied seat
- Choose "Transfer"
- Enter new member email
- Original member removed
- New member invited
Acceptance Criteria
Frontend
- Seat Management workflow is implemented in the UI as described.
Backend / API
- Backend behavior supports Seat Management as documented.
Permissions
- Access is restricted per the Capabilities matrix on this page (or equivalent role rules).
Business Rules
- All business rules for this feature are enforced.
Error Handling
- Error states return clear messages and appropriate HTTP status codes.
Group Administrator Portal
Group administrators can:
- View all members in their group
- Add/remove members (within seat limit)
- View group invoices
- Update company details
- Request additional seats
Acceptance Criteria
Frontend
- Group Administrator Portal workflow is implemented in the UI as described.
Backend / API
- Backend behavior supports Group Administrator Portal as documented.
Permissions
- Access is restricted per the Capabilities matrix on this page (or equivalent role rules).
Business Rules
- All business rules for this feature are enforced.
Error Handling
- Error states return clear messages and appropriate HTTP status codes.
Implementation Contracts
Backend (API)
GET /api/groups # List all group accounts
POST /api/groups # Create group account
GET /api/groups/{id} # Get group details
PUT /api/groups/{id} # Update group
DELETE /api/groups/{id} # Deactivate group
GET /api/groups/{id}/members # List group members
POST /api/groups/{id}/members # Add member to group
DELETE /api/groups/{id}/members/{memberId} # Remove member
POST /api/groups/{id}/seats/add # Add more seats
POST /api/groups/{id}/seats/transfer # Transfer seat
GET /api/groups/{id}/invoices # Group invoices
Data Model
interface GroupMembership {
id: string;
name: string;
membershipPlanId: string;
// Administrator
adminFirstName: string;
adminLastName: string;
adminEmail: string;
// Seats
totalSeats: number;
occupiedSeats: number;
// Billing
paymentStatus: 'active' | 'past_due' | 'cancelled';
expiryDate: string;
// System
createdAt: string;
updatedAt: string;
}
interface GroupMember {
id: string;
groupId: string;
memberId: string;
memberEmail: string;
memberName: string;
assignedAt: string;
assignedBy: string;
status: 'active' | 'invited' | 'removed';
}
Error Handling
| Error | HTTP Status | Message |
|---|---|---|
| No available seats | 400 | "No seats available. Purchase additional seats." |
| Member in group | 409 | "Member is already in another group" |
| Cannot reduce seats | 400 | "Cannot reduce seats below occupied count" |
| Invalid admin email | 400 | "Administrator email is invalid" |