🎴 API de Carteirinhas - Documentação Completa

Sistema completo de gerenciamento de carteirinhas personalizáveis
Criação, atualização e personalização de carteirinhas com suporte a logos, cores, dimensões e verso customizável

📋 Visão Geral

O que é este sistema?

Um sistema completo de gerenciamento de carteirinhas que permite:

Por que você precisa disto?

Problema Solução Resultado
💥 Carteirinhas padronizadas Personalização completa 🎨 Carteirinhas únicas por instituição
🖼️ Gestão de logos complexa Upload via Blob Storage ⚡ Gerenciamento centralizado
📏 Dimensões fixas Configuração flexível 🔧 Adaptação a diferentes formatos
🔄 Sem verso Suporte a verso customizável 📄 Carteirinhas completas
📅 Sem controle de vencimento Dia de vencimento configurável ✅ Gestão de validade

🏗️ Arquitetura

┌─────────────────────────────────────────────────────────┐
│ Requisição HTTP                                         │
└─────────────────┬───────────────────────────────────────┘
                  │
┌─────────────────▼───────────────────────────────────────┐
│ CarteirinhasController                                   │
│ • GET    /api/Carteirinhas                               │
│ • GET    /api/Carteirinhas/{id}                          │
│ • POST   /api/Carteirinhas                               │
│ • PUT    /api/Carteirinhas/{id}                          │
│ • DELETE /api/Carteirinhas/{id}                          │
└─────────────────┬───────────────────────────────────────┘
                  │
┌─────────────────▼───────────────────────────────────────┐
│ CarteirinhaService                                       │
│ • Validações de negócio                                  │
│ • Integração com Anexos (Blob Storage)                  │
│ • Mapeamento AutoMapper                                  │
└─────────────────┬───────────────────────────────────────┘
                  │
        ┌─────────┴─────────┐
        │                   │
┌───────▼──────┐   ┌────────▼────────┐
│ AdminDbContext│   │ AnexoBlobService│
│ (Banco Dados)│   │ (Azure Blob)   │
└──────────────┘   └─────────────────┘

⚙️ Componentes

1️⃣ CarteirinhasController

🎯 Propósito: Endpoint RESTful para operações CRUD de carteirinhas

Endpoints Disponíveis:

Método Rota Descrição
GET /api/Carteirinhas Lista todas as carteirinhas ativas
GET /api/Carteirinhas/{id} Obtém uma carteirinha por ID
POST /api/Carteirinhas Cria uma nova carteirinha
PUT /api/Carteirinhas/{id} Atualiza uma carteirinha existente
DELETE /api/Carteirinhas/{id} Exclui uma carteirinha (soft delete)

Autenticação: Todos os endpoints requerem autenticação Bearer Token


2️⃣ CarteirinhaService

🎯 Propósito: Lógica de negócio e integração com serviços auxiliares

Funcionalidades Principais:


3️⃣ Estrutura de Dados

CarteirinhaEntity (Banco de Dados)

public class CarteirinhaEntity
{
    public int Id { get; set; }
    public string NomeCarteirinha { get; set; }
    public string? Titulo { get; set; }
    public bool LogoAtivo { get; set; }
    public string? CorFundo { get; set; }
    public string? CorTexto { get; set; }
    public int? PorcentagemTransparencia { get; set; }
    public decimal? Largura { get; set; }
    public decimal? Altura { get; set; }
    public string? BlobUrl { get; set; }
    public string? ThumbUrl { get; set; }
    public int? InstituicaoId { get; set; }
    public int? DiaVencimento { get; set; }
    public bool VersoCarteirinha { get; set; }
    public bool DadosAlunos { get; set; }
    public bool FotoAluno { get; set; }
    public bool Sublinhado { get; set; }
    public bool Ativo { get; set; }
    public DateTime? Criacao { get; set; }
    public DateTime? Atualizacao { get; set; }
    public string? UsuarioCriacao { get; set; }
    public string? UsuarioAtualizacao { get; set; }
}

CriarCarteirinhaRequest (POST)

{
  "nomeCarteirinha": "Carteirinha Padrão",
  "titulo": "Título da Carteirinha",
  "logoAtivo": true,
  "corFundo": "#5C6BC0",
  "corTexto": "#FFFFFF",
  "porcentagemTransparencia": 10,
  "largura": 10.70,
  "altura": 7.90,
  "instituicaoId": 1,
  "diaVencimento": 5,
  "versoCarteirinha": true,
  "dadosAlunos": true,
  "fotoAluno": true,
  "sublinhado": false
}

AtualizarCarteirinhaRequest (PUT)

{
  "nomeCarteirinha": "Carteirinha Atualizada",
  "logoAtivo": false,
  "corFundo": "#FF6600",
  "corTexto": "#000000",
  "porcentagemTransparencia": 15,
  "largura": 10.60,
  "altura": 7.80,
  "instituicaoId": 2,
  "diaVencimento": 10,
  "versoCarteirinha": false,
  "dadosAlunos": false,
  "fotoAluno": false,
  "sublinhado": true
}

CarteirinhaResponse (GET)

{
  "id": 1,
  "nomeCarteirinha": "Carteirinha Padrão",
  "logoAtivo": true,
  "corFundo": "#5C6BC0",
  "corTexto": "#FFFFFF",
  "porcentagemTransparencia": 10,
  "largura": 10.70,
  "altura": 7.90,
  "blobUrl": "https://storage.azure.com/...",
  "thumbUrl": "https://storage.azure.com/...",
  "instituicaoId": 1,
  "diaVencimento": 5,
  "versoCarteirinha": true,
  "dadosAlunos": true,
  "fotoAluno": true,
  "sublinhado": false,
  "ativo": true,
  "criacao": "2025-12-29T13:21:00-03:00",
  "atualizacao": "2025-12-30T10:18:02-03:00",
  "usuarioCriacao": "bfd276d1-c038-46c3-b445-4b7475f88e5c",
  "usuarioAtualizacao": null
}

📤 Upload de Logo via Blob Storage

⚠️ Regra Importante

Para fazer upload da foto/logo da carteirinha, você DEVE usar o endpoint de Anexos Blob Storage com os seguintes parâmetros:

Configuração Obrigatória

Parâmetro Valor Descrição
tipoContextoId 16 ID do contexto CARTEIRINHA_LOGO
entidade {idDaCarteirinha} ID da carteirinha (convertido para string)
file [arquivo] Arquivo de imagem (JPG, PNG, etc.)

Endpoint de Upload

POST /api/AnexosBlob/upload
Content-Type: multipart/form-data
Authorization: Bearer {token}

Exemplo de Requisição

Exemplo com C# / .NET

public async Task<AnexoBlobResponse> UploadCarteirinhaLogoAsync(
    int carteirinhaId, 
    IFormFile file, 
    string usuarioId)
{
    using var formData = new MultipartFormDataContent();
    
    formData.Add(new StreamContent(file.OpenReadStream()), "file", file.FileName);
    formData.Add(new StringContent("16"), "tipoContextoId");
    formData.Add(new StringContent(carteirinhaId.ToString()), "entidade");
    formData.Add(new StringContent(usuarioId), "usuarioUpload");

    var response = await _httpClient.PostAsync("/api/AnexosBlob/upload", formData);
    response.EnsureSuccessStatusCode();

    return await response.Content.ReadFromJsonAsync<AnexoBlobResponse>();
}

⚠️ Observações Importantes

  1. Contexto ID 16: Sempre use tipoContextoId = 16 para logos de carteirinhas
  2. Campo Entidade: Deve conter o ID da carteirinha como string
  3. Atualização Automática: Os campos BlobUrl e ThumbUrl são atualizados automaticamente na próxima consulta GET da carteirinha (via GET /api/Carteirinhas ou GET /api/Carteirinhas/{id})
  4. Substituição: Se já existir um logo, ele será substituído automaticamente
  5. Formato de Imagem: Aceita JPG, PNG e outros formatos de imagem suportados

📊 Campos e Validações

Campos Obrigatórios

Campo Tipo Validação
nomeCarteirinha string Obrigatório, máximo 200 caracteres

Campos Opcionais

Campo Tipo Validação Padrão
titulo string? Máximo 200 caracteres null
logoAtivo bool - true
corFundo string? Máximo 50 caracteres null
corTexto string? Máximo 50 caracteres null
porcentagemTransparencia int? Entre 0 e 100 null
largura decimal? Entre 0.1 e 100 cm null
altura decimal? Entre 0.1 e 100 cm null
instituicaoId int? Deve existir na tabela Instituicoes null
diaVencimento int? Entre 1 e 31 null
versoCarteirinha bool - false
dadosAlunos bool - false
fotoAluno bool - false
sublinhado bool - false

Campos de Resposta (Read-Only)

Campo Tipo Descrição
id int ID único da carteirinha
blobUrl string? URL completa do logo no Blob Storage
thumbUrl string? URL da miniatura do logo
ativo bool Status ativo/inativo
criacao DateTime? Data de criação (timezone Brasil)
atualizacao DateTime? Data da última atualização (timezone Brasil)
usuarioCriacao string? ID do usuário que criou
usuarioAtualizacao string? ID do usuário que atualizou

🎯 Casos de Uso

Cenário 1: Criar Carteirinha Básica

POST /api/Carteirinhas HTTP/1.1
Content-Type: application/json
Authorization: Bearer {token}

{
  "nomeCarteirinha": "Carteirinha Padrão",
  "titulo": "Título da Carteirinha",
  "logoAtivo": true,
  "corFundo": "#5C6BC0",
  "corTexto": "#FFFFFF",
  "porcentagemTransparencia": 10,
  "largura": 10.70,
  "altura": 7.90,
  "dadosAlunos": true,
  "fotoAluno": true,
  "sublinhado": false
}

Resposta:

{
  "id": 1,
  "nomeCarteirinha": "Carteirinha Padrão",
  "logoAtivo": true,
  "corFundo": "#5C6BC0",
  "corTexto": "#FFFFFF",
  "porcentagemTransparencia": 10,
  "largura": 10.70,
  "altura": 7.90,
  "blobUrl": null,
  "thumbUrl": null,
  "instituicaoId": null,
  "diaVencimento": null,
  "versoCarteirinha": false,
  "ativo": true,
  "criacao": "2025-12-30T10:18:02-03:00",
  "atualizacao": "2025-12-30T10:18:02-03:00",
  "usuarioCriacao": "bfd276d1-c038-46c3-b445-4b7475f88e5c",
  "usuarioAtualizacao": null
}

Cenário 2: Criar Carteirinha Completa com Verso

POST /api/Carteirinhas HTTP/1.1
Content-Type: application/json
Authorization: Bearer {token}

{
  "nomeCarteirinha": "Carteirinha Completa",
  "titulo": "Carteirinha Completa",
  "logoAtivo": true,
  "corFundo": "#00AA00",
  "corTexto": "#FFFFFF",
  "porcentagemTransparencia": 5,
  "largura": 10.60,
  "altura": 7.80,
  "instituicaoId": 1,
  "diaVencimento": 5,
  "versoCarteirinha": true,
  "dadosAlunos": true,
  "fotoAluno": true,
  "sublinhado": false
}

Cenário 3: Upload de Logo Após Criação

# 1. Criar carteirinha (retorna id = 1)
# 2. Fazer upload do logo
curl -X POST "https://api.cordenaai.com/api/AnexosBlob/upload" \
  -H "Authorization: Bearer {token}" \
  -F "file=@logo.png" \
  -F "tipoContextoId=16" \
  -F "entidade=1" \
  -F "usuarioUpload=bfd276d1-c038-46c3-b445-4b7475f88e5c"

Resposta do Upload:

{
  "id": 123,
  "nomeDoArquivo": "logo.png",
  "blobUrl": "https://cordenaaistg13344.blob.core.windows.net/images/...",
  "thumbUrl": "https://cordenaaistg13344.blob.core.windows.net/thumbs/...",
  "contexto": "CARTEIRINHA_LOGO",
  "entidade": "1",
  "dataUpload": "2025-12-30T10:20:00-03:00"
}

Após o upload, ao consultar a carteirinha novamente:

{
  "id": 1,
  "nomeCarteirinha": "Carteirinha Padrão",
  ...
  "blobUrl": "https://cordenaaistg13344.blob.core.windows.net/images/...",
  "thumbUrl": "https://cordenaaistg13344.blob.core.windows.net/thumbs/...",
  ...
}

Cenário 4: Atualizar Carteirinha (Atualização Parcial)

PUT /api/Carteirinhas/1 HTTP/1.1
Content-Type: application/json
Authorization: Bearer {token}

{
  "corFundo": "#FF6600",
  "versoCarteirinha": true,
  "diaVencimento": 10
}

Resposta: Retorna a carteirinha atualizada com apenas os campos modificados

Cenário 5: Listar Todas as Carteirinhas Ativas

GET /api/Carteirinhas HTTP/1.1
Authorization: Bearer {token}

Resposta:

[
  {
    "id": 1,
    "nomeCarteirinha": "Carteirinha Padrão",
    ...
  },
  {
    "id": 2,
    "nomeCarteirinha": "Carteirinha Completa",
    ...
  }
]

Cenário 6: Obter Carteirinha por ID

GET /api/Carteirinhas/1 HTTP/1.1
Authorization: Bearer {token}

Resposta: Retorna a carteirinha completa com todos os campos

Cenário 7: Excluir Carteirinha (Soft Delete)

DELETE /api/Carteirinhas/1 HTTP/1.1
Authorization: Bearer {token}

Resposta:

{
  "message": "Carteirinha excluída com sucesso"
}

Observação: A carteirinha não é removida do banco, apenas marcada como ativo = false


🔍 Detalhes Técnicos

Integração com Blob Storage

O sistema busca automaticamente o logo da carteirinha no Blob Storage usando:

Fluxo de Atualização de Logo

┌─────────────────────────────────────────────────────────┐
│ 1. Upload via /api/AnexosBlob/upload                    │
│    └─► tipoContextoId = 16                              │
│    └─► entidade = {idCarteirinha}                       │
└─────────────────┬───────────────────────────────────────┘
                  │
┌─────────────────▼───────────────────────────────────────┐
│ 2. AnexoBlobService salva no Blob Storage               │
│    └─► Gera BlobUrl e ThumbUrl                          │
│    └─► Salva metadados na tabela Anexos                 │
└─────────────────┬───────────────────────────────────────┘
                  │
┌─────────────────▼───────────────────────────────────────┐
│ 3. Próxima consulta GET /api/Carteirinhas/{id}          │
│    └─► CarteirinhaService busca anexo                   │
│    └─► Atualiza BlobUrl e ThumbUrl na carteirinha       │
│    └─► Salva atualização no banco                       │
└─────────────────────────────────────────────────────────┘

Validação de Instituição

Se instituicaoId for fornecido, o sistema valida se a instituição existe:

// Validação automática no Service
if (request.InstituicaoId.HasValue)
{
    var instituicaoExiste = await ValidarInstituicaoExisteAsync(request.InstituicaoId);
    if (!instituicaoExiste)
    {
        return Erro("Instituição não encontrada");
    }
}

Timezone do Brasil (UTC-3)

Todos os campos de data/hora (Criacao, Atualizacao) são salvos no timezone do Brasil usando DateTimeHelper.AgoraBrasil().


📝 Códigos de Resposta HTTP

Código Descrição Quando Ocorre
200 OK Sucesso GET, PUT, DELETE bem-sucedidos
201 Created Criado POST bem-sucedido
400 Bad Request Erro de validação Dados inválidos ou erro no processamento
403 Forbidden Não autenticado Token ausente ou inválido
404 Not Found Não encontrado Carteirinha não existe
422 Unprocessable Entity Erro de validação Validações de modelo falharam

⚠️ Regras de Negócio Importantes

1. Upload de Logo

2. Soft Delete

3. Atualização Parcial

4. Validações

5. Campos de Verso


🧪 Exemplos de Teste

Teste 1: Criar e Consultar Carteirinha

# 1. Criar carteirinha
curl -X POST "https://api.cordenaai.com/api/Carteirinhas" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "nomeCarteirinha": "Carteirinha Teste",
    "corFundo": "#5C6BC0",
    "corTexto": "#FFFFFF",
    "largura": 10.70,
    "altura": 7.90
  }'

# 2. Consultar carteirinha criada (assumindo id = 1)
curl -X GET "https://api.cordenaai.com/api/Carteirinhas/1" \
  -H "Authorization: Bearer {token}"

Teste 2: Upload de Logo

# Upload do logo (assumindo carteirinha id = 1)
curl -X POST "https://api.cordenaai.com/api/AnexosBlob/upload" \
  -H "Authorization: Bearer {token}" \
  -F "file=@logo.png" \
  -F "tipoContextoId=16" \
  -F "entidade=1" \
  -F "usuarioUpload=user-id-here"

# Consultar novamente para ver BlobUrl atualizado
curl -X GET "https://api.cordenaai.com/api/Carteirinhas/1" \
  -H "Authorization: Bearer {token}"

Teste 3: Atualização Parcial

curl -X PUT "https://api.cordenaai.com/api/Carteirinhas/1" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "versoCarteirinha": true,
    "diaVencimento": 5
  }'

🔐 Segurança

Autenticação

Auditoria


📚 Glossário

Termo Definição
Carteirinha Documento personalizável com informações do usuário
BlobUrl URL completa da imagem no Azure Blob Storage
ThumbUrl URL da miniatura (thumbnail) da imagem
VersoCarteirinha Indica se o verso da carteirinha está habilitado
DiaVencimento Dia do mês em que a carteirinha vence (1-31)
Soft Delete Exclusão lógica (marca como inativo, não remove)
Contexto Tipo de anexo no sistema (CARTEIRINHA_LOGO = 16)
Entidade ID do registro relacionado ao anexo

🎯 Checklist de Implementação

Fase 1: Configuração Inicial

Fase 2: Criação de Carteirinha

Fase 3: Upload de Logo

Fase 4: Consulta e Atualização


🚀 Benefícios do Sistema

Para o Desenvolvimento

Para o Negócio

Para os Usuários


📞 Suporte e Contato

Documentação Adicional

Troubleshooting

Problema Possível Causa Solução
🐌 Logo não aparece Upload não realizado ou contexto errado Verificar se upload foi feito com tipoContextoId=16
🚫 Carteirinha não encontrada ID inválido ou soft deleted Verificar se ID existe e se está ativa
💾 Erro ao criar Validação falhou Verificar campos obrigatórios e validações
🔐 403 Forbidden Token inválido ou expirado Renovar token de autenticação

📄 Conclusão

Este sistema oferece uma solução completa e robusta para gerenciamento de carteirinhas, permitindo:

Versão: 1.0
Última Atualização: Dezembro de 2025
Responsável: Equipe de Desenvolvimento CordenaAi