Family Collaboration

Manage family members, roles, and permissions in your application.

Note: This is mock/placeholder content for demonstration purposes.

Enable families to collaborate effectively with built-in family management features.

Families

The application supports multi-tenant families where multiple users can collaborate.

Creating a Family

Users can create new families:

import { createFamily } from '~/lib/families/create-family';

const family = await createFamily({
  name: 'Acme Corp',
  slug: 'acme-corp',
  ownerId: currentUser.id,
});

Family Workspace

Each family has its own workspace with isolated data:

  • Projects and resources
  • Family-specific settings
  • Billing and subscription
  • Activity logs

Inviting Members

Send Invitations

Invite new members to your family:

import { inviteFamilyMember } from '~/lib/families/invitations';

await inviteFamilyMember({
  familyId: family.id,
  email: 'member@example.com',
  role: 'member',
});

Invitation Flow

  1. Owner sends invitation via email
  2. Recipient receives email with invitation link
  3. Recipient accepts invitation
  4. Member gains access to family workspace

Managing Invitations

import { PendingInvitations } from '~/components/families/pending-invitations';

<PendingInvitations familyId={family.id} />

Roles and Permissions

Default Roles

Owner

  • Full access to family and settings
  • Manage billing and subscriptions
  • Invite and remove members
  • Delete family

Admin

  • Manage family members
  • Manage family resources
  • Cannot access billing
  • Cannot delete family

Member

  • View family resources
  • Create and edit own content
  • Limited family settings access

Custom Roles

Define custom roles with specific permissions:

const customRole = {
  name: 'Editor',
  permissions: [
    'read:projects',
    'write:projects',
    'read:members',
  ],
};

Checking Permissions

import { checkPermission } from '~/lib/families/permissions';

const canEdit = await checkPermission(userId, familyId, 'write:projects');

if (!canEdit) {
  throw new Error('Insufficient permissions');
}

Member Management

Listing Members

import { getFamilyMembers } from '~/lib/families/members';

const members = await getFamilyMembers(familyId);

Updating Member Role

import { updateMemberRole } from '~/lib/families/members';

await updateMemberRole({
  memberId: member.id,
  role: 'admin',
});

Removing Members

import { removeMember } from '~/lib/families/members';

await removeMember(memberId);

Family Settings

Updating Family Info

'use client';

import { useForm } from 'react-hook-form';
import { updateFamilyAction } from '../_lib/server/actions';

export function FamilySettingsForm({ family }) {
  const { register, handleSubmit } = useForm({
    defaultValues: {
      name: family.name,
      description: family.description,
    },
  });

  const onSubmit = async (data) => {
    await updateFamilyAction({ familyId: family.id, ...data });
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('name')} placeholder="Family name" />
      <textarea {...register('description')} placeholder="Description" />
      <button type="submit">Save Changes</button>
    </form>
  );
}

Family Avatar

import { uploadFamilyAvatar } from '~/lib/families/avatar';

const avatarUrl = await uploadFamilyAvatar({
  familyId: family.id,
  file: avatarFile,
});

Activity Log

Track family activity for transparency:

import { logActivity } from '~/lib/families/activity';

await logActivity({
  familyId: family.id,
  userId: user.id,
  action: 'member_invited',
  metadata: {
    invitedEmail: 'new@example.com',
  },
});

Viewing Activity

import { getFamilyActivity } from '~/lib/families/activity';

const activities = await getFamilyActivity(familyId, {
  limit: 50,
  offset: 0,
});

Family Switching

Allow users to switch between their families:

'use client';

import { useFamilyWorkspace } from '@kit/families/hooks/use-family-workspace';

export function FamilySwitcher() {
  const { accounts, account } = useFamilyWorkspace();

  return (
    <select
      value={account.id}
      onChange={(e) => switchFamily(e.target.value)}
    >
      {accounts.map((family) => (
        <option key={family.id} value={family.id}>
          {family.name}
        </option>
      ))}
    </select>
  );
}

Notifications

Member Joined

await createNotification({
  familyId: family.id,
  title: 'New Member',
  message: `${user.name} joined the family`,
  type: 'info',
});

Role Changed

await createNotification({
  userId: member.userId,
  title: 'Role Updated',
  message: `Your role was changed to ${newRole}`,
  type: 'info',
});

Best Practices

  1. Clear role hierarchy - Define roles that make sense for your use case
  2. Principle of least privilege - Give minimum required permissions
  3. Audit trail - Log important family actions
  4. Easy onboarding - Simple invitation process
  5. Self-service - Let members manage their own settings
  6. Transparent billing - Show usage and costs clearly