Professional Services & Client Portals
The Professional vertical powers financial advisors, lawyers, consultants, and accountants with four integrated systems: client portals, document vaults, consultation booking, and compliance tracking. Malet Owners configure these features via the Storefront Window layout system.
NOTE
These features live in the experiences subgraph โ the same cross-vertical Feature Plane that houses Entertainment & Experiences. The architecture is documented in docs/architecture/18-progressive-vertical-extraction.md.
Architecture: Two-Plane Design
The Professional vertical uses the same Control + Feature plane separation as Entertainment:
- Control Plane (
maletssubgraph): VerticalConfig feature flags decide which Professional modules are enabled per Malet โclientPortal,documentVault,complianceTracking,consultationBooking. - Feature Plane (
experiencessubgraph): Self-containedClientPortalModuleandDocumentVaultModule. Each can be extracted to its own subgraph when a dedicated Professional vertical Team forms. - Extensions (
servicessubgraph): Consultation-specific fields on existing Service and Booking entities.
Three new Storefront Window layout slot types are available: CLIENT_PORTAL, DOCUMENT_EXCHANGE, and CONSULTATION_CALENDAR.
Client Portal
Create persistent client engagements with status tracking, notes, and a shared communication timeline.
Engagement Lifecycle
ACTIVE โ PAUSED โ ACTIVE
โ CLOSED
Engagements start as ACTIVE when a Malet Owner onboards a new client. They can be PAUSED during inactive periods and reopened, or CLOSED permanently (with an endDate set automatically). Closed engagements cannot be reopened.
Mutations
# Create a new client engagement (Malet Owner)
mutation {
createEngagement(
maletId: "m_luminara"
clientId: "v_lerato"
title: "Tax Planning 2026"
description: "Annual tax review and strategy session"
) {
id
status
startDate
}
}
# Update engagement status
mutation {
updateEngagementStatus(id: "eng_1", status: PAUSED) {
id
status
}
}
# Add a note from the advisor
mutation {
addEngagementNote(
engagementId: "eng_1"
content: "Reviewed Q1 financials. Recommend re-balancing investment portfolio."
author: ADVISOR
) {
id
notes {
content
author
authorId
createdAt
}
}
}
# Add a note from the client
mutation {
addEngagementNote(
engagementId: "eng_1"
content: "Thanks for the recommendation. Proceeding with Option B."
author: CLIENT
) {
id
notes {
content
author
createdAt
}
}
}
# Close the engagement
mutation {
closeEngagement(id: "eng_1") {
id
status
endDate
}
}
Queries
# Visitor checks their active engagements across all Malets
query {
myEngagements(status: ACTIVE) {
id
maletId
title
status
startDate
notes {
content
author
createdAt
}
}
}
# Malet Owner views all clients
query {
maletClients(maletId: "m_luminara") {
id
clientId
title
status
startDate
tags
}
}
# Single engagement by ID
query {
engagement(id: "eng_1") {
id
title
description
status
notes {
content
author
authorId
createdAt
}
}
}
Note Authors
Each note tracks who wrote it โ ADVISOR (the Malet Owner or staff) or CLIENT (the Visitor). This creates a persistent communication timeline within the engagement, separate from uChat messaging.
Document Vault
Securely share contracts, invoices, reports, and compliance documents between Malet Owners and their clients. The vault stores metadata only โ actual files are uploaded via the existing media subgraph's R2/S3 infrastructure.
Access Levels
| Level | Description |
|---|---|
OWNER_ONLY |
Only the Malet Owner and staff can view (default) |
CLIENT_VISIBLE |
The associated client can also view and download |
PUBLIC |
Visible to anyone with the link |
Document Categories
| Category | Use Case |
|---|---|
CONTRACT |
Engagement agreements, service contracts |
INVOICE |
Bills, payment records, Murchase receipts |
REPORT |
Financial reports, audit summaries, deliverables |
IDENTITY |
ID verification, KYC documents |
TAX |
Tax returns, W-9s, compliance forms |
OTHER |
Miscellaneous documents |
Retention Policies
Set retentionDays on upload to auto-compute an expiresAt date. When the retention period elapses, the document transitions to EXPIRED status via a MongoDB TTL index. Set retentionDays to 0 or omit it for indefinite retention.
Mutations
# Upload document metadata (file already uploaded via media subgraph)
mutation {
uploadDocument(
maletId: "m_luminara"
fileName: "Tax_Strategy_2026.pdf"
fileUrl: "https://r2.mallnline.com/docs/tax_strategy_2026.pdf"
mimeType: "application/pdf"
fileSizeBytes: 245000
engagementId: "eng_1"
accessLevel: CLIENT_VISIBLE
category: REPORT
retentionDays: 365
) {
id
fileName
accessLevel
expiresAt
}
}
# Archive a document (soft-archive โ status โ ARCHIVED)
mutation {
archiveDocument(id: "doc_1") {
id
status
}
}
# Permanently delete a document (Malet Owner only)
mutation {
deleteDocument(id: "doc_1") # Returns: true
}
Queries
# All documents for an engagement (client-facing)
query {
engagementDocuments(engagementId: "eng_1", accessLevel: CLIENT_VISIBLE) {
id
fileName
mimeType
fileSizeBytes
category
createdAt
}
}
# All documents for a Malet (Malet Owner dashboard)
query {
maletDocuments(maletId: "m_luminara", category: CONTRACT, status: ACTIVE) {
id
fileName
accessLevel
category
retentionDays
expiresAt
}
}
# Single document (logs access for compliance)
query {
document(id: "doc_1") {
id
fileName
fileUrl
accessLevel
accessLog {
userId
action
timestamp
}
}
}
# Compliance audit trail
query {
documentAccessLog(documentId: "doc_1") {
id
fileName
accessLog {
userId
action # VIEW, DOWNLOAD, ARCHIVE
timestamp
}
}
}
Compliance Access Logging
Every time a document is viewed via the document query, the requesting Visitor's ID, the action (VIEW), and a timestamp are appended to the embedded accessLog[] array. Archive operations are also logged. This creates an immutable compliance audit trail for regulated industries.
Consultation Booking
Extended booking fields for professional services on the existing services subgraph:
Service Fields
| Field | Type | Description |
|---|---|---|
consultationType |
ConsultationType |
INITIAL, FOLLOW_UP, or RETAINER |
meetingUrl |
String |
Video conference link (Zoom, Teams, Google Meet) |
intakeFormRequired |
Boolean |
Whether the client must complete an intake form before booking |
requiresDeposit |
Boolean |
Whether a deposit is required for the consultation |
depositPercentage |
Float |
Deposit as percentage of service price (e.g., 25 for 25%) |
Booking Fields
| Field | Type | Description |
|---|---|---|
engagementId |
String |
Links to ClientEngagement in the experiences subgraph |
meetingUrl |
String |
Copied from the Service on booking creation |
intakeFormCompleted |
Boolean |
Whether the client completed the intake form |
consultationNotes |
String |
Post-session notes recorded by the advisor |
Example: Create a Consultation Service
mutation {
createOneService(
input: {
service: {
name: "Initial Tax Consultation"
description: "60-minute tax planning session"
price: 25000 # $250.00 (cents)
maletId: "m_luminara"
consultationType: INITIAL
meetingUrl: "https://zoom.us/j/123456789"
intakeFormRequired: true
requiresDeposit: true
depositPercentage: 25
}
}
) {
id
name
consultationType
meetingUrl
}
}
Workroom Steps
The Professional vertical ships with 4 default Workroom steps for engagement lifecycle management:
| Step | Type | Assignee | Description |
|---|---|---|---|
| Client Intake Form | FORM |
Client | Questionnaire to gather client needs before the consultation |
| Document Submission | UPLOAD |
Client | Upload required documents (contracts, financials, ID) |
| Consultation Notes | FORM |
Malet Owner | Record session notes, action items, and recommendations |
| Deliverables | UPLOAD |
Malet Owner | Upload final reports, signed documents, or recommendations |
These steps are automatically configured on new Professional Malets via the vertical seed.
Deferred Features
The following capabilities are planned for future phases using in-house, open-source solutions โ no third-party SaaS dependencies:
| Feature | Phase | Approach |
|---|---|---|
| E-Signatures | Phase 2 | Self-hosted DocSeal (MIT licensed) |
| Calendar Sync | Phase 2 | Standard CalDAV protocol (RFC 4791) + iCal .ics fallback |
| Retainer Billing | Phase 2 | Stripe Billing API + RetainerSubscription entity in murchases |
| Client Messaging | Phase 3 | Engagement-scoped channels via uChat Matrix bridge |
TIP
Integration points are already designed โ VaultDocument.signatureStatus for e-signatures, service availability engine for CalDAV, and uChat channel auto-creation for engagement-scoped messaging.
Related
- Entertainment & Experiences โ Sibling vertical in the shared
experiencessubgraph Feature Plane - Storefront Sections โ Configure
CLIENT_PORTAL,DOCUMENT_EXCHANGE, andCONSULTATION_CALENDARlayout slots - Teams & Sub-Groups โ Organize professional staff with Custom RBAC roles
- Edit History Audit Trail โ Cross-entity field-level change tracking complements the document vault access log
- Organization & Malet Management โ Frontend management dashboard where Malet Owners configure their storefronts
- Wellness & Beauty โ Sibling vertical with a similar client profile pattern (wellness profiles vs. client portals)
- Culture & Arts โ Sibling vertical with exhibition curation and artist profiles in the shared
experiencessubgraph