Match Manual Profile API - Frontend Integration Pack
Información General
| Campo | Valor |
|---|---|
| Stack | STACK_BACKOFFICE |
| Servicio | match_manual_profile |
| Archivo | STACK_BACKOFFICE/services/match_manual_profile/get.py |
| Base URL (PROD) | https://backoffice.mas10.ar |
| Base URL (DEV) | https://backoffice-dev.liricus.com.ar |
| Autenticación | Cognito JWT (Bearer Token) |
| Fecha de creación | 2026-03-10 |
Descripción
Verifica si el usuario autenticado (Cognito) tiene un perfil manual (player_manual) cargado previamente en la base de datos. Funciona en dos modos según si el front envía o no el query param ?dni=.
Caso de uso principal: La app o la web le muestra al usuario si existe un perfil manual con sus estadísticas de partidos, permitiéndole luego confirmar la vinculación mediante el endpoint PUT /update_profile_admin.
Modo A — Discovery (sin ?dni=)
El front llama sin DNI. El servicio busca perfiles manuales que coincidan por first_name o last_name (LIKE, case-insensitive) y birth_date exacta. Solo se devuelven manuales que tengan DNI cargado (para que el siguiente paso sea posible). Puede devolver múltiples resultados.
| Campo | Condición |
|---|---|
birth_date | Exacta — del perfil Cognito autenticado |
first_name OR last_name | LIKE case-insensitive contra los campos del manual |
dni del manual | Debe estar cargado (no null) — el Cognito no necesita tener DNI |
Respuesta típica: partial_match_found
Acción sugerida en el front: Mostrar "¡Te encontramos en un equipo! Decinos tus últimos 4 dígitos para chequear tu identidad"
Modo B — Confirmación (con ?dni=<valor>)
El front manda el DNI que tipea el usuario. El servicio valida identidad comparando el DNI contra los manuales filtrados por birth_date.
| Campo | Condición |
|---|---|
birth_date | Exacta — del perfil Cognito autenticado |
?dni= (query param) | Si tiene 8+ dígitos: match exacto. Si tiene menos de 8: se comparan los últimos 4 dígitos contra RIGHT(m.dni, 4) |
Respuesta típica: match_found
Autenticación
Todas las solicitudes (excepto OPTIONS) requieren un token JWT de Cognito:
Authorization: Bearer <access_token>
Endpoint
GET /match_manual_profile
Busca un perfil manual que coincida con el usuario autenticado.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
dni | query string | No | DNI ingresado por el usuario. Activa el Modo B (confirmación). Omitir para Modo A (discovery). |
El usuario se identifica a través del token JWT.
Respuestas
Estructura base
{
"error": false,
"data": {
"message": "<código de resultado>",
"results": []
}
}
Caso 1 — Match parcial (partial_match_found) — Modo A
Se encontraron uno o más perfiles manuales que coinciden por nombre/apellido + birth_date. El front debe pedir los últimos 4 dígitos del DNI para confirmar identidad (Modo B).
HTTP 200
{
"error": false,
"data": {
"message": "partial_match_found",
"results": [
{
"cognito_user": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"first_name": "Luis",
"last_name": "Marin",
"birth_date": "1990-05-15",
"dni": null,
"username": "luismarin_42",
"avatar": "https://cdn.mas10.ar/profile_avatar/abc123.jpg",
"avatar_50": "https://cdn.mas10.ar/profile_avatar/abc123_50.jpg",
"avatar_100": "https://cdn.mas10.ar/profile_avatar/abc123_100.jpg",
"avatar_rembg": "https://cdn.mas10.ar/profile_avatar/abc123_rembg.png"
},
"manual_user": {
"id": 42,
"first_name": "L.",
"last_name": "Marin",
"birth_date": "1990-05-15",
"dni": "1234",
"username": null,
"avatar": "https://cdn.mas10.ar/profile_avatar/fileKWAKMFF7ZU.png",
"avatar_50": null,
"avatar_100": null,
"avatar_rembg": null,
"teams": [
{
"team_id": 7,
"team_name": "Los Cracks FC",
"team_avatar": "https://cdn.mas10.ar/team_avatar/team7.jpg",
"team_avatar_50": "https://cdn.mas10.ar/team_avatar/team7_50.jpg",
"team_avatar_100": "https://cdn.mas10.ar/team_avatar/team7_100.jpg",
"team_avatar_rembg": null,
"team_type": "player",
"team_status": "approved",
"team_position": "delantero"
}
]
}
}
]
}
}
Caso 2 — Match confirmado (match_found) — Modo B
Se envió ?dni= y se encontró exactamente 1 perfil manual que coincide con el dni + birth_date.
HTTP 200
{
"error": false,
"data": {
"message": "match_found",
"results": [
{
"cognito_user": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"first_name": "Luis",
"last_name": "Marin",
"birth_date": "1990-05-15",
"dni": null,
"username": "luismarin_42",
"avatar": "https://cdn.mas10.ar/profile_avatar/abc123.jpg",
"avatar_50": "https://cdn.mas10.ar/profile_avatar/abc123_50.jpg",
"avatar_100": "https://cdn.mas10.ar/profile_avatar/abc123_100.jpg",
"avatar_rembg": "https://cdn.mas10.ar/profile_avatar/abc123_rembg.png"
},
"manual_user": {
"id": 42,
"first_name": "L.",
"last_name": "Marin",
"birth_date": "1990-05-15",
"dni": "1234",
"username": null,
"avatar": "https://cdn.mas10.ar/profile_avatar/fileKWAKMFF7ZU.png",
"avatar_50": null,
"avatar_100": null,
"avatar_rembg": null,
"teams": [
{
"team_id": 7,
"team_name": "Los Cracks FC",
"team_avatar": "https://cdn.mas10.ar/team_avatar/team7.jpg",
"team_avatar_50": "https://cdn.mas10.ar/team_avatar/team7_50.jpg",
"team_avatar_100": "https://cdn.mas10.ar/team_avatar/team7_100.jpg",
"team_avatar_rembg": null,
"team_type": "player",
"team_status": "approved",
"team_position": "delantero"
}
]
}
}
]
}
}
Caso 3 — Sin match (no_match)
No existe ningún perfil manual que coincida. Aplica a ambos modos.
HTTP 200
{
"error": false,
"data": {
"message": "no_match",
"results": []
}
}
Caso 4 — Múltiples resultados (multiple_results) — solo Modo B
Se encontraron 2 o más perfiles manuales con el mismo ?dni= + birth_date. Se devuelve lista vacía y debe resolverse desde el backoffice.
HTTP 200
{
"error": false,
"data": {
"message": "multiple_results",
"results": []
}
}
Caso 5 — Perfil Cognito incompleto (cognito_profile_incomplete)
El usuario Cognito no tiene birth_date cargado en su perfil. No es posible realizar el matching en ningún modo.
HTTP 200
{
"error": false,
"data": {
"message": "cognito_profile_incomplete",
"results": []
}
}
Caso 6 — Perfil Cognito no encontrado
El email del token no existe en la base de datos.
HTTP 404
{
"error": true,
"data": "Cognito profile not found"
}
Caso 7 — Token inválido / sin autenticación
HTTP 401
{
"error": true,
"data": "User not found"
}
Referencia de campos
cognito_user
| Campo | Tipo | Nullable | Descripción |
|---|---|---|---|
id | string (UUID) | No | ID de Cognito en userprofile |
first_name | string | Sí | Nombre del usuario |
last_name | string | Sí | Apellido del usuario |
birth_date | string (YYYY-MM-DD) | No | Fecha de nacimiento |
dni | string | Sí | DNI del usuario (puede ser null si no lo cargó). En Modo B no se usa el del Cognito — se usa el ?dni= del request |
username | string | Sí | Username en la plataforma |
avatar | string (URL) | Sí | Avatar en resolución original |
avatar_50 | string (URL) | Sí | Avatar 50px |
avatar_100 | string (URL) | Sí | Avatar 100px |
avatar_rembg | string (URL) | Sí | Avatar con fondo removido |
manual_user
| Campo | Tipo | Nullable | Descripción |
|---|---|---|---|
id | integer | No | ID numérico del perfil manual en userprofile |
first_name | string | Sí | Nombre cargado manualmente |
last_name | string | Sí | Apellido cargado manualmente |
birth_date | string (YYYY-MM-DD) | No | Fecha de nacimiento |
dni | string | No | DNI (puede ser solo los últimos 4 dígitos) |
username | string | Sí | Generalmente null en manuales |
avatar | string (URL) | Sí | Avatar (suele ser el avatar por defecto) |
avatar_50 | string (URL) | Sí | Avatar 50px |
avatar_100 | string (URL) | Sí | Avatar 100px |
avatar_rembg | string (URL) | Sí | Avatar con fondo removido |
teams | array | No | Lista de equipos (puede ser []) |
teams[] (dentro de manual_user)
| Campo | Tipo | Nullable | Descripción |
|---|---|---|---|
team_id | integer | No | ID del equipo |
team_name | string | No | Nombre del equipo |
team_avatar | string (URL) | Sí | Avatar del equipo |
team_avatar_50 | string (URL) | Sí | Avatar 50px |
team_avatar_100 | string (URL) | Sí | Avatar 100px |
team_avatar_rembg | string (URL) | Sí | Avatar con fondo removido |
team_type | string | Sí | Tipo de relación (player, coach, etc.) |
team_status | string | Sí | Estado (approved, pending) — los equipos con canceled se excluyen |
team_position | string | Sí | Posición del jugador en el equipo |
Tabla de mensajes (message)
| Valor | Modo | Descripción | Acción sugerida en frontend |
|---|---|---|---|
partial_match_found | A | Uno o más manuales coinciden por nombre + fecha | Mostrar "¡Te encontramos en un equipo! Decinos tus últimos 4 dígitos para chequear tu identidad" y solicitar DNI |
match_found | B | Se encontró exactamente 1 manual con ese dni + fecha | Mostrar card de confirmación para vincular |
no_match | A y B | Sin coincidencias | No mostrar sección de vinculación |
multiple_results | B | Más de un manual con el mismo dni + fecha | Mostrar: "Hay un conflicto con tu perfil. Contactá al administrador." |
cognito_profile_incomplete | A y B | El usuario no tiene birth_date cargado | Pedirle que complete su perfil primero |
Flujo de integración sugerido
App/Web
│
├─ PASO 1: GET /match_manual_profile (sin ?dni — Modo A)
│
├─ message = "partial_match_found"
│ └─ Mostrar: "¡Te encontramos en un equipo!
│ Decinos tus últimos 4 dígitos para chequear tu identidad"
│ └─ Usuario ingresa DNI
│
│ └─ PASO 2: GET /match_manual_profile?dni=<valor> (Modo B)
│
│ ├─ message = "match_found"
│ │ └─ Mostrar datos de cognito_user y manual_user
│ │ Mostrar equipos del manual_user
│ │ Botón: "Sí, soy yo → vincular"
│ │ └─ PUT /update_profile_admin
│ │ { "id_manual": manual_user.id,
│ │ "id_cognito": cognito_user.id }
│ │
│ ├─ message = "no_match"
│ │ └─ Mostrar: "El DNI no coincide, revisá los datos"
│ │
│ └─ message = "multiple_results"
│ └─ Mostrar: "Hay un conflicto. Contactá al administrador."
│
├─ message = "no_match" (Modo A)
│ └─ No mostrar sección de vinculación
│
└─ message = "cognito_profile_incomplete"
└─ Redirigir a pantalla de completar perfil (birth_date mínimo)
CORS
El endpoint acepta solicitudes desde cualquier origen (habilitado via OPTIONS /match_manual_profile sin autenticación).
OPTIONS /match_manual_profile
→ 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type