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
Um sistema completo de gerenciamento de carteirinhas que permite:
| 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 |
┌─────────────────────────────────────────────────────────┐
│ 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) │
└──────────────┘ └─────────────────┘
🎯 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
🎯 Propósito: Lógica de negócio e integração com serviços auxiliares
Funcionalidades Principais:
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; }
}
{
"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
}
{
"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
}
{
"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
}
Para fazer upload da foto/logo da carteirinha, você DEVE usar o endpoint de Anexos Blob Storage com os seguintes parâmetros:
| 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.) |
POST /api/AnexosBlob/upload
Content-Type: multipart/form-data
Authorization: Bearer {token}
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>();
}
tipoContextoId = 16 para logos de carteirinhasBlobUrl e ThumbUrl são atualizados automaticamente na próxima consulta GET da carteirinha (via GET /api/Carteirinhas ou GET /api/Carteirinhas/{id})| Campo | Tipo | Validação |
|---|---|---|
nomeCarteirinha |
string |
Obrigatório, máximo 200 caracteres |
| 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 |
| 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 |
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
}
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
}
# 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/...",
...
}
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
GET /api/Carteirinhas HTTP/1.1
Authorization: Bearer {token}
Resposta:
[
{
"id": 1,
"nomeCarteirinha": "Carteirinha Padrão",
...
},
{
"id": 2,
"nomeCarteirinha": "Carteirinha Completa",
...
}
]
GET /api/Carteirinhas/1 HTTP/1.1
Authorization: Bearer {token}
Resposta: Retorna a carteirinha completa com todos os campos
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
O sistema busca automaticamente o logo da carteirinha no Blob Storage usando:
CARTEIRINHA_LOGO (ID: 16)BlobUrl e ThumbUrl são atualizados automaticamente na próxima consulta GET da carteirinha (via GET /api/Carteirinhas ou GET /api/Carteirinhas/{id})┌─────────────────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────────────┘
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");
}
}
Todos os campos de data/hora (Criacao, Atualizacao) são salvos no timezone do Brasil usando DateTimeHelper.AgoraBrasil().
| 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 |
/api/AnexosBlob/uploadtipoContextoId = 16entidade (como string)BlobUrl e ThumbUrl na próxima consulta GET da carteirinhaativo = false)null explicitamentenomeCarteirinha é obrigatórioporcentagemTransparencia deve estar entre 0 e 100largura e altura devem estar entre 0.1 e 100 cmdiaVencimento deve estar entre 1 e 31 (se fornecido)instituicaoId deve existir na tabela Instituicoes (se fornecido)versoCarteirinha: Indica se o verso está habilitadodiaVencimento: Dia do mês de vencimento (1-31, opcional)# 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}"
# 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}"
curl -X PUT "https://api.cordenaai.com/api/Carteirinhas/1" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"versoCarteirinha": true,
"diaVencimento": 5
}'
UsuarioCriacao: Registrado automaticamente no POSTUsuarioAtualizacao: Registrado automaticamente no PUTCriacao e Atualizacao: Timestamps em timezone Brasil| 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 |
/api/AnexosBlob/uploadtipoContextoId = 16entidade| 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 |
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