Saltar al contenido principal

Centro de familias — Referencia técnica

← Volver a Centro de familias

Dónde vive esto

Backend

Frontendapps/frontend-nextjs/src/page-components/settings/FamilyCenterPage.tsx, enrutado en Configuración → Centro de familias (app/settings/family-center/page.tsx, enlazado desde la sección "Aplicación y contenido multimedia" del menú de configuración). Usa los documentos generados de @closegram/apollo-web/operations a partir de packages/graphql/operations/Web/Family/*.graphqlejecuta npm run build -w @closegram/apollo-web después de actualizar el código si ves errores de exportación faltante en estos imports; ese paso de build (que ejecuta codegen) debe volver a ejecutarse cada vez que se agregan archivos .graphql nuevos, y no es automático.

Checklist de implementación técnica

  • requestFamilySupervision(targetUsername, requestingUserRole) — cualquiera de los dos usuarios puede invitar; requestingUserRole ('parent' | 'child') es el rol que quien llama quiere jugar. Rechaza auto-invitaciones y un vínculo pendiente/activo duplicado entre el mismo par (verificado en ambas direcciones). Envía una notificación family_supervision_invite al usuario invitado.
  • respondToFamilySupervision(linkId, accept) — solo la parte invitada (no quien invitó) puede responder, y solo mientras el vínculo siga pending. Notifica a quien invitó del resultado.
  • endFamilySupervision(linkId) — cualquiera de las dos partes puede terminar un vínculo activo o cancelar uno pendiente, en cualquier momento (una decisión de producto deliberada — la supervisión siempre es revocable por ambos lados, no solo por el padre). Es idempotente para un vínculo ya terminado/rechazado. Notifica a la otra parte solo cuando termina un vínculo que estaba realmente active.
  • mySupervisionAsParent / mySupervisionAsChild — vínculos donde quien llama es el padre/hijo respectivamente, cualquier estado, más recientes primero.
  • setChildTimeLimit(linkId, minutes) — quien llama debe ser el padre activo del linkId; delega en usage-tracking.manager.js#updateTimeManagementSettings. Pasa minutes: null para borrar el límite.
  • childUsageStats(linkId, days) — de solo lectura, solo para el padre activo; combina usage-tracking.manager.js#getUsageStats con el dailyLimitMinutes actual.

Referencia de GraphQL

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 }
}
}

Modelo de datos

La tabla family_supervision guarda una fila por vínculo (consentimiento mutuo, en cualquier dirección):

ColumnaTipoNotas
idUUID (PK)
parent_user_id, child_user_idUUIDqué lado es "el padre" se decide en el momento de la invitación por requestSupervision, no está fijado por quién inició
statusSTRING(20)pending (por defecto) → active (aceptado) / declined, o activeended
requested_by_user_idUUIDcuál de los dos usuarios envió la invitación — el otro debe responder
responded_at, ended_atDATEanulable
ended_by_user_idUUIDanulable
created_at, updated_atDATE

Indexada por parent_user_id, child_user_id, y (parent_user_id, child_user_id, status) (acelera la verificación de invitación duplicada).

El límite de tiempo en pantalla en sí no se guarda en esta tabla — vive en el propio JSONB user.settings.time_management del hijo (ver la funcionalidad de Gestión del tiempo), y esta funcionalidad solo agrega la verificación de autorización que controla que el padre vinculado pueda leerlo o escribirlo.