O fluxo completo envolve 2 atores principais:
POST /api/CoResponsavel/criar-convite — envia atletaIds, email/telefone/CPF do corresponsável, diasExpiracao (opcional)linkConvite (link web) e tokenConvitehttps://cordenaai-dev-app.azurewebsites.net/registro-corresponsavel/409FD5F2FBC04E2F/registro-corresponsavel/{token})GET /api/autenticacao/verificar-token-convite/{token}POST /api/autenticacao/registrar-com-convitecorresponsavel = true)Endpoint para obter dados do responsável ou corresponsável (nome, email, atletas vinculados e foto de perfil):
GET /api/Atletas/responsavel/{identificador}
O {identificador} pode ser o ID do usuário (GUID), CPF, email ou nome de usuário. A resposta inclui a lista de atletas vinculados e o objeto responsavel com id, nome, email, foto e thumbUrl.
A foto do responsável/corresponsável é obtida por um sistema de fallback em duas etapas:
anexos, onde Entidade = ID do usuário e Contexto = FOTO_PERFIL (foto armazenada no Blob Storage).Foto da tabela usuarios (URL legada), quando preenchido.Assim, a foto é exibida corretamente tanto para quem fez upload recente (registro em anexos) quanto para perfis que ainda usam apenas o campo usuarios.Foto. O cache de fotos é invalidado automaticamente quando uma nova foto de perfil é enviada (criação ou atualização em anexos).
Atualmente o sistema gera um link web para o convite. O corresponsável clica no link e é levado à página de registro (app web ou WebView). O token do convite fica no path da URL.
https://cordenaai-dev-app.azurewebsites.net/registro-corresponsavel/409FD5F2FBC04E2F
O último segmento da URL é o tokenConvite. A aplicação (web ou app com WebView) extrai esse token e chama a API para verificar e pré-preencher o cadastro.
POST /api/CoResponsavel/criar-convite
{
"atletaIds": ["uuid-atleta-1"],
"email": "[email protected]",
"telefone": "11999999999",
"cpf": "12345678901"
}
Response:
{
"success": true,
"data": {
"tokenConvite": "409FD5F2FBC04E2F",
"linkConvite": "https://cordenaai-dev-app.azurewebsites.net/registro-corresponsavel/409FD5F2FBC04E2F"
}
}
https://cordenaai-dev-app.azurewebsites.net/registro-corresponsavel/409FD5F2FBC04E2FQuando o corresponsável clica no link:
/registro-corresponsavel/{token})GET /api/autenticacao/verificar-token-convite/{token}O deep link (ex.: cordenaai://convite/{token}) será implementado quando o app for publicado na App Store e na Play Store. Com o deep link, ao clicar no link o sistema operacional abrirá o app nativo diretamente (se instalado), em vez da página web. Até lá, o link web atende ao fluxo de convite do corresponsável.
/registro-corresponsavel/{token})GET /api/autenticacao/verificar-token-convite/ABC123DEF456GHI789
Response:
{
"success": true,
"data": {
"temConvitePendente": true,
"atletaNome": "João Silva",
"responsavelPrincipalNome": "Maria Silva",
"emailPreenchido": "[email protected]",
"telefonePreenchido": "11999999999",
"cpfPreenchido": "12345678901"
}
}
[email protected]1199999999912345678901POST /api/autenticacao/registrar-com-convite
{
"userName": "corresponsavel123",
"email": "[email protected]",
"password": "MinhaSenh@123",
"nome": "João Corresponsável",
"tokenConvite": "ABC123DEF456GHI789"
}
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="cordenaai" android:host="convite" />
</intent-filter>
</activity>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>cordenaai</string>
<key>CFBundleURLSchemes</key>
<array>
<string>cordenaai</string>
</array>
</dict>
</array>
1. API 1: POST /api/CoResponsavel/criar-convite
↓
2. Sistema gera: https://cordenaai-dev-app.azurewebsites.net/registro-corresponsavel/409FD5F2FBC04E2F
↓
3. Responsável compartilha link via WhatsApp/Email
↓
4. Corresponsável clica no link
↓
5. Navegador ou app (WebView) abre a página
↓
6. Aplicação extrai token do path: 409FD5F2FBC04E2F
↓
7. API 2: GET /api/autenticacao/verificar-token-convite/409FD5F2FBC04E2F
↓
8. App/página pré-preenche campos
↓
9. Usuário completa cadastro
↓
10. API 3: POST /api/autenticacao/registrar-com-convite
↓
11. Sistema vincula como corresponsável
POST /api/CoResponsavel/criar-convite
{
"atletaIds": ["37b109a5-ba6a-463e-bd99-6b59fed9f487"],
"email": "[email protected]",
"telefone": "11999999999",
"cpf": "12345678901",
"observacoes": "Convite para ser corresponsável do João",
"diasExpiracao": 7
}
Response:
{
"success": true,
"data": {
"tokenConvite": "409FD5F2FBC04E2F",
"linkConvite": "https://cordenaai-dev-app.azurewebsites.net/registro-corresponsavel/409FD5F2FBC04E2F",
"dataExpiracao": "2025-01-30T10:30:00-03:00"
}
}
https://cordenaai-dev-app.azurewebsites.net/registro-corresponsavel/409FD5F2FBC04E2F// App ou página web extrai o token do link (web ou deep link futuro)
void _handleLinkConvite(String link) {
// link = "https://cordenaai-dev-app.azurewebsites.net/registro-corresponsavel/409FD5F2FBC04E2F"
final uri = Uri.parse(link);
final token = uri.pathSegments.last; // "409FD5F2FBC04E2F"
// Salvar token
SharedPreferences.getInstance().then((prefs) {
prefs.setString('tokenConvite', token);
});
// Navegar para cadastro
Navigator.pushNamed(context, '/cadastro');
}
GET /api/autenticacao/verificar-token-convite/ABC123DEF456GHI789
Response:
{
"success": true,
"data": {
"temConvitePendente": true,
"atletaNome": "João Silva",
"responsavelPrincipalNome": "Maria Silva",
"emailPreenchido": "[email protected]",
"telefonePreenchido": "11999999999",
"cpfPreenchido": "12345678901"
}
}
[email protected] (pré-preenchido)11999999999 (pré-preenchido)12345678901 (pré-preenchido)POST /api/autenticacao/registrar-com-convite
{
"userName": "joao.corresponsavel",
"email": "[email protected]",
"password": "MinhaSenh@123",
"nome": "João Corresponsável",
"cpf": "12345678901",
"celular": "11999999999",
"genero": "M",
"dataNascimento": "1990-01-15T00:00:00Z",
"aceiteReceberComunicado": true,
"aceiteTermosLgpd": true,
"status": true,
"tokenConvite": "ABC123DEF456GHI789"
}
Response:
{
"success": true,
"message": "Usuário registrado e vinculado como corresponsável",
"data": {
"usuario": {
"id": "usuario-uuid-456",
"nome": "João Corresponsável",
"email": "[email protected]",
"corresponsavel": true
},
"atletasVinculados": [
{
"id": "37b109a5-ba6a-463e-bd99-6b59fed9f487",
"nome": "João Silva"
}
],
"mensagem": "Convite aceito com sucesso! Você agora é corresponsável pelos atletas vinculados."
}
}
Endpoint: POST /api/CoResponsavel/criar-convite
Autenticação: Bearer Token (usuário logado como responsável)
{
"atletaIds": ["uuid-atleta-1", "uuid-atleta-2"],
"email": "[email protected]",
"telefone": "11999999999",
"cpf": "12345678901",
"observacoes": "Convite para ser corresponsável dos atletas João e Maria",
"diasExpiracao": 2
}
{
"success": true,
"message": "Convite criado com sucesso",
"data": {
"id": "convite-uuid-123",
"tokenConvite": "ABC123DEF456GHI789",
"linkConvite": "https://cordenaai-dev-app.azurewebsites.net/registro-corresponsavel/409FD5F2FBC04E2F",
"dataExpiracao": "2024-01-15T10:30:00Z",
"atletaIds": ["uuid-atleta-1", "uuid-atleta-2"],
"emailCorresponsavel": "[email protected]",
"telefoneCorresponsavel": "11999999999",
"cpfCorresponsavel": "12345678901",
"status": "Pendente",
"mensagem": "Convite criado com sucesso"
}
}
Endpoint: GET /api/autenticacao/verificar-token-convite/{tokenConvite}
Autenticação: Não requerida (AllowAnonymous)
GET /api/autenticacao/verificar-token-convite/ABC123DEF456GHI789
{
"success": true,
"data": {
"temConvitePendente": true,
"convites": [
{
"id": "convite-uuid-123",
"atletaId": "uuid-atleta-1",
"atletaNome": "João Silva",
"responsavelPrincipalNome": "Maria Silva",
"dataExpiracao": "2024-01-15T10:30:00Z",
"observacoes": "Convite para ser corresponsável dos atletas João e Maria"
},
{
"id": "convite-uuid-456",
"atletaId": "uuid-atleta-2",
"atletaNome": "Maria Santos",
"responsavelPrincipalNome": "Maria Silva",
"dataExpiracao": "2024-01-15T10:30:00Z",
"observacoes": "Convite para ser corresponsável dos atletas João e Maria"
}
],
"emailPreenchido": "[email protected]",
"telefonePreenchido": "11999999999",
"cpfPreenchido": "12345678901"
}
}
{
"success": true,
"data": {
"temConvitePendente": false,
"convites": [],
"mensagem": "Convite expirado"
}
}
Endpoint: POST /api/autenticacao/registrar-com-convite
Autenticação: Não requerida (AllowAnonymous)
{
"userName": "corresponsavel123",
"email": "[email protected]",
"password": "MinhaSenh@123",
"nome": "João Corresponsável",
"nomeSocial": "João",
"cpf": "12345678901",
"celular": "11999999999",
"genero": "M",
"dataNascimento": "1990-01-15T00:00:00Z",
"aceiteReceberComunicado": true,
"aceiteTermosLgpd": true,
"status": true,
"tokenConvite": "ABC123DEF456GHI789"
}
{
"success": true,
"message": "Usuário registrado e vinculado como corresponsável",
"data": {
"id": "usuario-uuid-456",
"nome": "João Corresponsável",
"email": "[email protected]",
"cpf": "12345678901",
"celular": "11999999999",
"corresponsavel": true,
"dataCadastro": "2024-01-08T10:30:00Z"
}
}
{
"success": true,
"message": "Usuário registrado com sucesso",
"data": {
"id": "usuario-uuid-456",
"nome": "João Corresponsável",
"email": "[email protected]",
"cpf": "12345678901",
"celular": "11999999999",
"corresponsavel": false,
"dataCadastro": "2024-01-08T10:30:00Z"
}
}
class CadastroCorresponsavelScreen extends StatefulWidget {
🎯 PONTOS IMPORTANTES
Automatização:
- ✅ O corresponsável NÃO precisa fazer nada além de se cadastrar
- ✅ A vinculação acontece automaticamente durante o registro
- ✅ Campos são pré-preenchidos quando possível
Flexibilidade:
- ✅ Convite pode ser feito por email, telefone ou CPF
- ✅ Suporta múltiplos atletas por convite
- ✅ Deep link abre o app automaticamente
Segurança:
- ✅ Tokens únicos para cada convite (obrigatório)
- ✅ Expiração automática dos convites (2 dias padrão)
- ✅ Validação rigorosa de dados antes da vinculação
- ✅ Verificação específica por token (não por identificadores)
- ✅ Auditoria completa de todas as tentativas
Limpeza Automática:
- ✅ Remoção automática de convites expirados
- ✅ Limpeza diária via serviço em background
- ✅ Event Scheduler MySQL para limpeza dupla
- ✅ Remoção de convites recusados e aceitos antigos
- ✅ Logs completos de todas as operações
Este é o fluxo completo e detalhado da funcionalidade de co-responsabilidade!
Versão: 1.0
Última Atualização: Outubro de 2025
Responsável: Equipe de Desenvolvimento CordenaAi