Skip to main content

Family Center — Technical Reference

← Back to Family Center

Where this lives

Backend

Frontendapps/frontend-nextjs/src/page-components/settings/FamilyCenterPage.tsx, routed at Settings → Family Center (app/settings/family-center/page.tsx, linked from the "App and media" section of the settings nav). Uses @closegram/apollo-web/operations generated documents from packages/graphql/operations/Web/Family/*.graphqlrun npm run build -w @closegram/apollo-web after pulling if you see missing-export errors on these imports; that build step (which runs codegen) needs to be re-run any time new .graphql operation files are added, and isn't automatic.

Technical implementation checklist

  • requestFamilySupervision(targetUsername, requestingUserRole) — either user can invite; requestingUserRole ('parent' | 'child') is which role the caller wants to play. Rejects self-invites and a duplicate pending/active link between the same pair (checked in either direction). Sends a family_supervision_invite notification to the invited user.
  • respondToFamilySupervision(linkId, accept) — only the invited party (not the requester) may respond, and only while the link is still pending. Notifies the requester of the outcome.
  • endFamilySupervision(linkId) — either party may end an active link or cancel a pending one, at any time (a deliberate product decision — supervision is always revocable by both sides, not just the parent). Idempotent for an already-ended/declined link. Notifies the other party only when ending a link that was actually active.
  • mySupervisionAsParent / mySupervisionAsChild — links where the caller is the parent/child respectively, any status, newest first.
  • setChildTimeLimit(linkId, minutes) — caller must be the active parent on linkId; delegates to usage-tracking.manager.js#updateTimeManagementSettings. Pass minutes: null to clear the limit.
  • childUsageStats(linkId, days) — read-only, active-parent-only; merges usage-tracking.manager.js#getUsageStats with the current dailyLimitMinutes.

GraphQL reference

type FamilySupervision {
id: ID!
parent: User
child: User
status: String! # pending | active | declined | ended
requestedByUserId: ID!
respondedAt: DateTime
endedAt: DateTime
createdAt: DateTime!
updatedAt: DateTime
}

query MySupervision {
mySupervisionAsParent { id status child { id username } }
mySupervisionAsChild { id status parent { id username } }
}

mutation RequestSupervision($targetUsername: String!, $requestingUserRole: String!) {
requestFamilySupervision(targetUsername: $targetUsername, requestingUserRole: $requestingUserRole) {
id status
}
}

mutation RespondToSupervision($linkId: ID!, $accept: Boolean!) {
respondToFamilySupervision(linkId: $linkId, accept: $accept) { id status }
}

mutation EndSupervision($linkId: ID!) {
endFamilySupervision(linkId: $linkId) { id status endedAt }
}

mutation SetLimit($linkId: ID!, $minutes: Int) {
setChildTimeLimit(linkId: $linkId, minutes: $minutes) {
linkId childUserId dailyLimitMinutes
}
}

query ChildUsage($linkId: ID!, $days: Int) {
childUsageStats(linkId: $linkId, days: $days) {
linkId userId days dailyAverageSeconds todaySeconds dailyLimitMinutes
series { date totalSeconds }
}
}

Data model

The family_supervision table holds one row per link (mutual-consent, either direction):

ColumnTypeNotes
idUUID (PK)
parent_user_id, child_user_idUUIDwhich side is "the parent" is decided at invite time by requestSupervision, not fixed by who initiated
statusSTRING(20)pending (default) → active (accepted) / declined, or activeended
requested_by_user_idUUIDwhich of the two users sent the invite — the other one must respond
responded_at, ended_atDATEnullable
ended_by_user_idUUIDnullable
created_at, updated_atDATE

Indexed on parent_user_id, child_user_id, and (parent_user_id, child_user_id, status) (speeds up the duplicate-invite guard).

The screen-time limit itself is not stored on this table — it lives on the child's own user.settings.time_management JSONB (see the Time management feature), and this feature only adds the authorization check that gates the linked parent reading or writing it.