Protected User Management

This guide covers the complete lifecycle of protected user management in ChatMinder, including guardian relationships, protection levels, and administrative workflows.

Overview

Protected users are individuals who require supervision and approval workflows for their communications. This includes minors, individuals with special needs, or anyone requiring guided communication oversight.

Key Concepts

  • Protected User: An individual whose communications require supervision
  • Guardian: An authorized adult who manages and supervises protected users
  • Owner: The primary guardian who created the protected user account (has full administrative rights)
  • Shared Guardian: Additional guardians with approval permissions (no administrative rights)
  • Protection Level: The supervision intensity applied to the protected user

Protection Levels

ChatMinder supports three distinct protection levels that determine the scope of supervision required.

GuardianFullyManaged

Most Restrictive: Complete guardian control over all communication activities.

Characteristics:

  • Channel Creation: Protected user cannot create channels
  • Channel Invitations: Protected user cannot invite others or accept invitations
  • Direct Communication: All messages require guardian approval before delivery
  • 🎯 Guardian Role: Creates channels and manages all communication on behalf of the protected user

Implementation:

// Guardian creates channel for protected user
const channel = await fetch('/api/guardian/channels/create-direct', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${guardianToken}` },
    body: JSON.stringify({
        fromUserId: protectedUserId,
        targetUserId: contactUserId
    })
});

// All messages require approval
const messageResponse = await fetch(`/api/messages/channel/${channelId}`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${protectedUserToken}` },
    body: JSON.stringify({ content: 'Hello!', messageType: 'text' })
});

// Response contains pendingMessageId for guardian approval
if (messageResponse.pendingMessageId) {
    // Guardian must approve via:
    await fetch(`/api/guardian/pending-messages/${messageResponse.pendingMessageId}/approve`, {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${guardianToken}` }
    });
}

GuardianFullyModerated

Collaborative Supervision: Shared control between guardian and protected user.

Characteristics:

  • Channel Creation: Protected user can create channels (with guardian approval for invitations)
  • ⚠️ Channel Invitations: Protected user can send invitations, but recipient's guardian must approve
  • Direct Communication: All messages require guardian approval before delivery
  • 🎯 Guardian Role: Approves communications but allows protected user initiative

Implementation:

// Protected user creates channel
const channel = await fetch('/api/channels/direct/${targetUserId}', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${protectedUserToken}` }
});

// Channel invitation requires guardian approval
if (channel.channelInvite) {
    // Recipient's guardian approves invitation
    await fetch(`/api/guardian/channels/invite/${channel.channelInvite.id}/approve`, {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${recipientGuardianToken}` }
    });
    
    // Then recipient can accept
    await fetch(`/api/channels/invite/${channel.channelInvite.id}/accept`, {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${recipientToken}` }
    });
}

Trusted

Minimal Supervision: Independent communication with monitoring.

Characteristics:

  • Channel Creation: Protected user can create channels independently
  • Channel Invitations: Protected user can invite others and accept invitations
  • Direct Communication: Messages are delivered immediately
  • 🎯 Guardian Role: Monitors communications but does not block them

Implementation:

// Trusted users operate like regular users
const channel = await fetch('/api/channels/direct/${targetUserId}', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${trustedUserToken}` }
});

// Messages are delivered immediately
const message = await fetch(`/api/messages/channel/${channelId}`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${trustedUserToken}` },
    body: JSON.stringify({ content: 'Hello!', messageType: 'text' })
});

// Guardian can monitor via dashboard but messages are not blocked

Guardian Management

Guardian Roles and Responsibilities

Owner Guardian:

  • Creates and configures the protected user account
  • Manages protection level settings
  • Can share guardianship with other adults
  • Can transfer ownership to another guardian
  • Has full administrative control

Shared Guardian:

  • Can approve/reject pending communications
  • Can monitor protected user activities
  • Cannot modify protection level or administrative settings
  • Cannot delete or transfer the protected user

Protected User Lifecycle

1. Creation

Create a new protected user account under your guardianship:

POST /api/protected-user
Authorization: Bearer {guardian-token}
Content-Type: application/json

{
    "name": "Emma Johnson",
    "protectionLevel": "GuardianFullyManaged",
    "dateOfBirth": "2010-05-15",
    "notes": "Needs supervision for online safety"
}

Response:

{
    "success": true,
    "data": {
        "userId": "user_abc123",
        "name": "Emma Johnson",
        "protectionLevel": "GuardianFullyManaged",
        "dateOfBirth": "2010-05-15",
        "createdAt": "2025-09-20T10:00:00Z",
        "isOwner": true
    }
}

2. Management

List Your Protected Users:

GET /api/protected-user
Authorization: Bearer {guardian-token}

Get Specific Protected User:

GET /api/protected-user/{userId}
Authorization: Bearer {guardian-token}

Update Protected User:

PUT /api/protected-user/{userId}
Authorization: Bearer {guardian-token}
Content-Type: application/json

{
    "name": "Emma Johnson-Smith",
    "protectionLevel": "GuardianFullyModerated",
    "dateOfBirth": "2010-05-15",
    "notes": "Upgraded to collaborative supervision"
}

3. Guardian Access Control

Authenticate as Protected User:

Guardians can sign in as their protected users to manage their communications:

POST /api/auth/login-protected-user/{protectedUserId}
Authorization: Bearer {guardian-token}

This switches the session to act as the protected user while maintaining guardian oversight.

Share Guardianship:

Allow another adult to become a guardian:

POST /api/protected-user/{userId}/share
Authorization: Bearer {owner-guardian-token}
Content-Type: application/json

{
    "email": "co-guardian@example.com"
}

Transfer Ownership:

Transfer primary ownership to another guardian:

POST /api/protected-user/{userId}/transfer-ownership
Authorization: Bearer {owner-guardian-token}
Content-Type: application/json

{
    "newOwnerId": "guardian_xyz789"
}

View Guardian Team:

GET /api/protected-user/{userId}/guardians
Authorization: Bearer {guardian-token}

4. Deletion and Data Management

Delete Protected User:

DELETE /api/protected-user/{userId}
Authorization: Bearer {owner-guardian-token}

Note: Deletion preserves chat history but anonymizes the user as "Deleted User" to maintain conversation context for other participants.

Communication Workflows

Guardian Approval Process

Pending Message Management

Get Overview of Pending Approvals:

GET /api/guardian/pending-messages
Authorization: Bearer {guardian-token}

Response:

{
    "totalPendingMessages": 5,
    "protectedUsers": [
        {
            "userId": "user_abc123",
            "name": "Emma Johnson",
            "pendingMessageCount": 3
        }
    ],
    "channelSummaries": [
        {
            "channelId": 42,
            "channelName": "Emma & Sarah",
            "pendingMessageCount": 2
        }
    ]
}

Get Channel-Specific Pending Messages:

GET /api/guardian/pending-messages/{channelId}
Authorization: Bearer {guardian-token}

Approve Message:

POST /api/guardian/pending-messages/{pendingMessageId}/approve
Authorization: Bearer {guardian-token}

Reject Message:

POST /api/guardian/pending-messages/{pendingMessageId}/reject
Authorization: Bearer {guardian-token}
Content-Type: application/json

{
    "reason": "Inappropriate language"
}

Channel Management for Protected Users

Create Channel on Behalf of Protected User:

POST /api/guardian/channels/create-direct
Authorization: Bearer {guardian-token}
Content-Type: application/json

{
    "fromUserId": "protected_user_id",
    "targetUserId": "contact_user_id"
}

Get Protected User's Channels:

GET /api/guardian/channels/protected-user/{protectedUserId}
Authorization: Bearer {guardian-token}

Get Pending Channel Invitations:

GET /api/guardian/channels/pending
Authorization: Bearer {guardian-token}

Approve Channel Invitation:

POST /api/guardian/channels/invite/{inviteId}/approve
Authorization: Bearer {guardian-token}

Cross-Guardian Coordination

When protected users with different guardians communicate, both guardians may need to approve various actions:

Scenario: GuardianFullyManaged ↔ GuardianFullyModerated

  1. Guardian A creates channel for Emma (GuardianFullyManaged)
  2. Guardian B approves channel invitation for Jake (GuardianFullyModerated)
  3. Jake accepts the invitation (user-level approval required)
  4. Guardian A approves Emma's messages
  5. Guardian B approves Jake's messages
// Complete cross-guardian workflow
async function crossGuardianCommunication() {
    // Step 1: Guardian A creates channel
    const channel = await fetch('/api/guardian/channels/create-direct', {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${guardianAToken}` },
        body: JSON.stringify({
            fromUserId: 'emma_id',
            targetUserId: 'jake_id'
        })
    });
    
    // Step 2: Guardian B approves invitation
    const pendingInvites = await fetch('/api/guardian/channels/pending', {
        headers: { 'Authorization': `Bearer ${guardianBToken}` }
    });
    
    await fetch(`/api/guardian/channels/invite/${inviteId}/approve`, {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${guardianBToken}` }
    });
    
    // Step 3: Jake accepts invitation
    await fetch(`/api/channels/invite/${inviteId}/accept`, {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${jakeToken}` }
    });
    
    // Step 4 & 5: Message approval workflow continues...
}

Best Practices

Security Considerations

  1. Guardian Verification: Always verify guardian authority before allowing protected user access
  2. Session Management: Properly handle session switching between guardian and protected user contexts
  3. Data Privacy: Limit data exposure to necessary guardian oversight functions
  4. Audit Trails: Maintain logs of guardian actions for accountability

User Experience Guidelines

  1. Clear Status Indicators: Show approval status prominently in guardian dashboards
  2. Bulk Operations: Provide bulk approval options for efficiency
  3. Real-time Updates: Use SignalR to notify guardians of pending approvals
  4. Mobile Optimization: Ensure guardian tools work well on mobile devices

Implementation Patterns

class ProtectedUserManager {
    constructor(apiClient, authService) {
        this.api = apiClient;
        this.auth = authService;
    }
    
    async createProtectedUser(userData) {
        try {
            const response = await this.api.post('/api/protected-user', {
                ...userData,
                headers: { 'Authorization': `Bearer ${this.auth.getGuardianToken()}` }
            });
            
            return {
                success: true,
                protectedUser: response.data
            };
        } catch (error) {
            return this.handleProtectedUserError(error);
        }
    }
    
    async switchToProtectedUser(protectedUserId) {
        try {
            const response = await this.api.post(`/api/auth/login-protected-user/${protectedUserId}`, {
                headers: { 'Authorization': `Bearer ${this.auth.getGuardianToken()}` }
            });
            
            // Update session to protected user context
            this.auth.setProtectedUserToken(response.token);
            this.auth.setCurrentContext('protected-user', protectedUserId);
            
            return { success: true };
        } catch (error) {
            if (error.status === 403) {
                throw new Error('Guardian does not have access to this protected user');
            }
            throw error;
        }
    }
    
    async approvePendingMessage(pendingMessageId) {
        try {
            await this.api.post(`/api/guardian/pending-messages/${pendingMessageId}/approve`, {
                headers: { 'Authorization': `Bearer ${this.auth.getGuardianToken()}` }
            });
            
            // Emit event for real-time UI updates
            this.eventBus.emit('message-approved', { pendingMessageId });
            
            return { success: true };
        } catch (error) {
            return this.handleApprovalError(error);
        }
    }
    
    handleProtectedUserError(error) {
        switch (error.response?.data?.errorCode) {
            case 'UNAUTHORIZED_GUARDIAN_ACTION':
                return { success: false, message: 'You do not have permission to manage this user' };
            case 'INVALID_PROTECTION_LEVEL':
                return { success: false, message: 'Invalid protection level specified' };
            default:
                return { success: false, message: 'Failed to manage protected user' };
        }
    }
}

Performance Optimization

  1. Caching: Cache protection level information to reduce API calls
  2. Batch Processing: Group multiple approvals when possible
  3. Real-time Updates: Use SignalR for instant approval notifications
  4. Lazy Loading: Load protected user details on demand

Data Models

ProtectedUserDto

{
    "userId": "string",
    "name": "string",
    "protectionLevel": "GuardianFullyManaged | GuardianFullyModerated | Trusted",
    "dateOfBirth": "2010-05-15",
    "notes": "string",
    "createdAt": "2025-09-20T10:00:00Z",
    "isOwner": true,
    "guardianCount": 2
}

ProtectedUserGuardianDto

{
    "guardianId": "string",
    "guardianName": "string",
    "guardianEmail": "string",
    "isOwner": true,
    "sharedAt": "2025-09-20T10:00:00Z",
    "status": "Active | Pending | Expired"
}

GuardianPendingMessagesOverview

{
    "totalPendingMessages": 5,
    "protectedUsers": [
        {
            "userId": "string",
            "name": "string",
            "pendingMessageCount": 3
        }
    ],
    "channelSummaries": [
        {
            "channelId": 42,
            "channelName": "string",
            "pendingMessageCount": 2
        }
    ]
}

Common Integration Scenarios

1. Guardian Dashboard

// Complete guardian dashboard data loading
async function loadGuardianDashboard() {
    const [protectedUsers, pendingMessages, pendingChannels] = await Promise.all([
        fetch('/api/protected-user'),
        fetch('/api/guardian/pending-messages'),
        fetch('/api/guardian/channels/pending')
    ]);
    
    return {
        protectedUsers: await protectedUsers.json(),
        pendingApprovals: await pendingMessages.json(),
        pendingChannelInvites: await pendingChannels.json()
    };
}

2. Protected User Communication Interface

// Interface for protected user with approval indicators
class ProtectedUserChat {
    async sendMessage(channelId, content) {
        const response = await fetch(`/api/messages/channel/${channelId}`, {
            method: 'POST',
            body: JSON.stringify({ content, messageType: 'text' }),
            headers: { 'Authorization': `Bearer ${this.protectedUserToken}` }
        });
        
        const result = await response.json();
        
        if (result.pendingMessageId) {
            this.showApprovalRequiredMessage('Your message is awaiting guardian approval');
            this.notifyGuardian(result.pendingMessageId);
        } else {
            this.showMessageSent();
        }
        
        return result;
    }
    
    showApprovalRequiredMessage(message) {
        // Show pending approval UI
        this.ui.showStatus(message, 'pending');
    }
    
    notifyGuardian(pendingMessageId) {
        // Send real-time notification to guardian
        this.signalR.invoke('NotifyGuardianOfPendingMessage', pendingMessageId);
    }
}

3. Multi-Guardian Coordination

// Coordinate approvals across multiple guardians
class CrossGuardianWorkflow {
    async createCrossGuardianChannel(fromUserId, targetUserId) {
        // Guardian A creates channel for their protected user
        const channel = await this.createDelegatedChannel(fromUserId, targetUserId);
        
        if (channel.channelInvite) {
            // Guardian B needs to approve the invitation
            await this.notifyTargetGuardian(channel.channelInvite);
            
            // Wait for guardian approval via webhook or polling
            return this.waitForChannelApproval(channel.channelInvite.id);
        }
        
        return channel;
    }
    
    async notifyTargetGuardian(channelInvite) {
        // Real-time notification to target user's guardian
        await this.signalR.invoke('NotifyGuardianOfChannelInvite', {
            inviteId: channelInvite.id,
            fromUserName: channelInvite.fromUserName,
            targetUserId: channelInvite.targetUserId
        });
    }
}