Ponto Inteligente
Gestão de jornada com geolocalização e visão computacional
Problema
Construído para uma indústria de alimentos com vendedores e trabalhadores externos, atuando em múltiplos locais e turnos. Prova de presença por digital falha com trabalho manual, crachá pode ser emprestado, e papel não resiste a uma disputa trabalhista. O sistema confirma, na mesma batida, que a pessoa está fisicamente no local certo e que é ela mesma — com cada tentativa, aprovada ou não, registrada e armazenada de forma segura.
Stack
- React
- TanStack Start
- Supabase
- PostgreSQL
- Row Level Security
- face-api.js
- Python
Planejamento de produto
Da descoberta em chão de fábrica ao MVP
O trabalho começou antes de qualquer linha de código, acompanhando um turno completo numa planta para entender onde o processo de ponto até então falhava — digitais desgastadas por trabalho manual, filas na catraca no início do turno, e colegas batendo ponto uns pelos outros.
Escopo do MVP
Geofencing + reconhecimento facial (não NFC ou digital) foi decisão direta da descoberta: digital tem alta rejeição em mãos de trabalho manual, e um crachá pode ser emprestado.
Onboarding com consentimento
Cadastro pelo admin → magic link → troca de senha (bloqueante) → aceite explícito do termo de geolocalização (bloqueante, sem ele o app não libera) → vínculo do dispositivo ao usuário.
Alinhamento jurídico
O formato do dossiê de auditoria foi desenhado com o time jurídico do cliente, pensando em como esse histórico serviria de evidência numa disputa trabalhista.
Rollout faseado
Implantado numa planta-piloto por 30 dias, com coleta ativa de feedback dos supervisores sobre falsos negativos, antes de expandir para as demais plantas.
Visão computacional
Reconhecimento facial embarcado, em 3 estágios
Todo o pipeline roda no navegador do funcionário — nenhuma imagem biométrica sai do dispositivo até a decisão já estar tomada.
| Estágio | Modelo | Tamanho | O que faz |
|---|---|---|---|
| 1 | TinyFaceDetector | ~190 KB | Detecta o rosto e define a bounding box, com score de confiança |
| 2 | FaceLandmark68Net | ~350 KB | Marca 68 pontos anatômicos e alinha o rosto |
| 3 | FaceRecognitionNet | ~6,2 MB | Converte o rosto alinhado num vetor de 128 números (embedding) |
Custo — cenário de referência (~20 colaboradores, ~80 batidas/dia)
| Serviço | Cobrança | Custo mensal |
|---|---|---|
| AWS Rekognition CompareFaces | US$ 1,00 / 1.000 chamadas | ~R$ 132/mês |
| Azure Face API | US$ 1,00 / 1.000 chamadas | ~R$ 132/mês |
| Google Cloud Vision | US$ 1,50 / 1.000 chamadas | ~R$ 198/mês |
| face-api local (este projeto) | sem chamadas de API | R$ 0,00/mês |
Demo
Experimente o pipeline acima, ao vivo
Envie uma foto de referência e tire outra pela câmera — os mesmos 3 modelos da tabela acima rodam de verdade no seu navegador. O limiar de decisão usado aqui não é o número simulado da seção de validação estatística abaixo — é o padrão real de mercado para este modelo (distância euclidiana ≤ 0.6). Explico o porquê logo ali embaixo. Código em src/lib/face-match-live.ts.
Demo ao vivo
Reconhecimento facial rodando no seu navegador, agora
Envie uma foto de referência e tire outra pela câmera — o mesmo pipeline de 3 estágios (detecção → landmarks → descritor) documentado no showcase roda aqui de verdade, 100% no seu navegador. Nenhuma imagem é enviada a um servidor. Isso baixa ~6,7 MB de modelos na primeira vez.
Validação estatística
Como os limiares de decisão foram calibrados
A parte mais fácil de fazer errado num sistema biométrico é escolher um número redondo para o limiar de decisão sem justificar por quê. Os dois limiares centrais deste projeto foram calibrados com metodologia estatística, sobre dados simulados (nenhum dado biométrico ou de localização real de funcionário é usado).
FaceMatch: FAR, FRR e Equal Error Rate
Para cada limiar candidato: FAR (fração de impostores aprovados) e FRR (fração de genuínos reprovados). O EER é onde as duas se cruzam — métrica padrão de sistemas biométricos.
Geofence: percentil empírico de erro de GPS
Mesma técnica usada para SLOs de latência em SRE, aplicada a erro de posicionamento: o raio recomendado é um percentil da distribuição de distâncias observadas, não uma regra de desvio-padrão.
EER: threshold=0.680 far=0.014 frr=0.012
Limiar recomendado (FAR <= 2%): threshold=0.655 far=0.020 frr=0.004Raio para aceitar 50% das leituras legítimas: 28.8 m
Raio para aceitar 90% das leituras legítimas: 55.8 m
Raio para aceitar 95% das leituras legítimas: 61.3 m
Raio para aceitar 99% das leituras legítimas: 74.3 mCorreção registrada em produção
A calibração acima roda sobre uma distribuição simulada, criada só para ensinar o método FAR/FRR/EER de forma abstrata — nunca foi uma medição real do @vladmandic/face-api. A demo ao vivo inicialmente reaproveitou o número que saiu dali (0.65), e isso causou falsos negativos reais: a mesma pessoa sendo reprovada com similaridade ~0.50. O limiar em produção foi corrigido para 0.4 (distância euclidiana ≤ 0.6), a referência real adotada pela comunidade dlib/face-api.js para descritores de 128 dimensões — bem mais permissiva que a calibração simulada. Para contexto de mercado: sistemas bancários miram FAR de 0,001%–0,1% com modelos proprietários multi-modais (infravermelho, prova de vida); um descritor de 128 números rodando no navegador é classe controle-de-acesso/ponto, não classe bancária — e isso é documentado aqui, não escondido.
Biometria
Checagem de qualidade e segurança em camadas
Checagem de qualidade
Rejeitado antes de extrair o descritor, com mensagem específica:
- Nenhum rosto detectado
- Mais de um rosto no quadro
- Confiança de detecção baixa
- Rosto pequeno demais no enquadramento
Otimização de UX
Os modelos e shaders WebGL são pré-aquecidos antes da primeira captura, reduzindo a latência percebida no momento da batida de ponto.
Segurança em camadas
Defesa em profundidade, não só uma checagem:
- RLS com função SECURITY DEFINER anti-recursão
- Middleware server-side validando JWT em toda escrita administrativa
- Checagem de papel repetida na aplicação
Vínculo de dispositivo
Um fingerprint do dispositivo é salvo e associado ao usuário no onboarding — dificulta um funcionário bater ponto de um aparelho que não é o seu.
Arquitetura
Da selfie ao registro auditado
Tecnologias
- React
- TanStack Start
- Supabase
- PostgreSQL
- Row Level Security
- face-api.js
- Python
Próximo projeto
PitaIA
Inteligência pessoal de saúde com IA