APIs · Serviço
AZ Media
O serviço que recebe toda foto e todo vídeo da plataforma, guarda os arquivos, decide o que pode ser publicado e é dono do AZ Play. Este documento descreve o caminho completo, do toque em “publicar” até o conteúdo aparecer no aplicativo.
O que ele é dono
O AZ Collections divide responsabilidades entre serviços, e cada dado tem um único dono. Quem é dono decide, guarda e avisa os outros — os demais mantêm cópias apenas para ler.
Fotos e vídeos
Todo arquivo enviado por usuário: foto de post, imagem de produto, avatar, capa e vídeo do AZ Play.
AZ Play
O vídeo em si e o engajamento dele — curtidas, comentários, respostas, salvamentos e visualizações.
Moderação de conteúdo
A decisão sobre publicar ou barrar cada mídia, e o registro do motivo.
Usuários e seguidores
Nome, avatar e quem segue quem. O AZ Media mantém uma cópia local, alimentada por eventos.
Os arquivos em si
Imagens ficam no R2; vídeos, no Stream, que também faz a conversão e a entrega.
Os arquivos nunca ficam no servidor. O aplicativo envia direto para a Cloudflare, e o AZ Media só guarda o registro — quem enviou, para quê, em que estado está e onde o arquivo mora. É por isso que o disco do servidor não cresce com o uso, por mais conteúdo que seja publicado.
O mapa em uma tela
Duas características do desenho explicam quase tudo o que vem a seguir: o arquivo não passa pelo servidor e os serviços não se chamam diretamente — eles trocam mensagens por uma fila, o que permite que um fique fora do ar sem derrubar o outro.
Fluxo 1 · Envio de imagem
PENDING UNDER_REVIEW READY REJECTED
-
Aplicativo → AZ Media Pedido de autorização
O aplicativo informa a finalidade da imagem, o tipo do arquivo e o tamanho. A finalidade é o que define as regras: uma foto de perfil e uma imagem de produto têm limites diferentes.
-
AZ Media Validação e reserva
O serviço recusa tipo não permitido e tamanho acima do limite antes de qualquer arquivo trafegar. Garante que o autor exista na cópia local de usuários, grava o registro em PENDING e devolve uma URL de envio assinada, com validade curta.
-
Aplicativo → Cloudflare R2 Envio do arquivo
O aplicativo envia os bytes diretamente para o R2, sem passar pelo servidor. Isso poupa banda e memória, e é o motivo de uma falha aqui não aparecer em nenhum registro do servidor — o tráfego acontece entre o aparelho e a Cloudflare.
-
Aplicativo → AZ Media Confirmação
Concluído o envio, o aplicativo avisa. Com a moderação desligada, a imagem vai direto para READY. Com ela ligada, fica em UNDER_REVIEW e uma mensagem de pedido de análise entra na fila.
-
AZ Media (consumindo a própria fila) Análise e veredito
A imagem passa pelas duas camadas de IA descritas adiante. Aprovada, vira READY; reprovada, REJECTED, com o motivo registrado. Nos dois casos, o resultado é publicado na fila para o servidor principal.
| Finalidade | Onde aparece | Limite |
|---|---|---|
| POST_IMAGE | Foto de publicação no feed | 15 MB |
| ITEM_IMAGE | Foto de produto anunciado | 15 MB |
| PROFILE_BANNER | Capa do perfil | 10 MB |
| GALLERY_COVER | Capa de coleção | 10 MB |
| JOURNAL_COVER | Capa de publicação editorial | 10 MB |
| SHOWCASE_IMAGE | Imagem de vitrine | 10 MB |
| PROFILE_IMAGE | Foto de perfil | 5 MB |
| AZPLAY_COVER | Capa personalizada de vídeo | 5 MB |
| AZPLAY | Vídeo do AZ Play | 512 MB |
Imagens aceitam JPEG, PNG e WebP; vídeos aceitam MP4, QuickTime e WebM.
Fluxo 2 · Envio de vídeo
O vídeo segue o mesmo início, mas com uma diferença importante: o AZ Media não sabe quando o vídeo ficou pronto. Quem avisa é a Cloudflare, depois de converter o arquivo.
PENDING PROCESSING UNDER_REVIEW READY REJECTED / FAILED
-
Aplicativo → AZ Media → Cloudflare Stream Reserva e envio
Igual à imagem, mas o destino é o Stream, que aceita arquivos de até 512 MB e cuida da conversão para os formatos de reprodução.
-
Cloudflare Stream → AZ Media Aviso de conclusão
O Stream chama o AZ Media de volta conforme o processamento avança. Enquanto não está pronto, o vídeo fica em PROCESSING. Só vira pronto quando o aviso traz, ao mesmo tempo, a confirmação de conclusão e o endereço de reprodução.
-
AZ Media Verificação de duração
A duração é conferida a partir do que a Cloudflare informa, não do que o aplicativo declarou — o número declarado pelo cliente é justamente o que alguém mal-intencionado controlaria. Vídeo acima do teto vai para FAILED, com o motivo registrado.
-
AZ Media Moderação sobre as capas
A análise de vídeo não examina o arquivo inteiro: usa as miniaturas geradas pelo Stream, cinco por padrão. Cada miniatura passa pelas duas camadas, como se fosse uma imagem. Qualquer uma reprovada reprova o vídeo.
A cópia de usuários
O AZ Media precisa saber o nome e o avatar de quem publicou para montar a tela do AZ Play, e precisa saber quem segue quem para a aba “Seguindo”. Nada disso é dele — pertence ao servidor principal. Em vez de perguntar a cada abertura de tela, ele mantém uma cópia local, atualizada por eventos.
Consultar o servidor principal a cada abertura do feed o colocaria no caminho mais quente do aplicativo: toda rolagem de vídeo viraria uma chamada extra. Com a cópia, o AZ Media responde sozinho, e uma indisponibilidade do servidor principal não derruba o AZ Play.
Como a cópia se mantém
| Evento | Efeito no AZ Media |
|---|---|
user.created | Cria a linha do usuário na cópia. |
user.updated | Atualiza nome e avatar. |
user.deleted | Anonimiza em vez de apagar — fotos, vídeos e reels apontam para essa linha. |
follow.created | Registra que alguém passou a seguir outra pessoa. |
follow.deleted | Remove o vínculo. |
O detalhe que evita um erro comum
A sincronização é assíncrona: o evento pode demorar, ou não chegar por diferença de ambiente. Se alguém enviasse uma foto antes de a cópia receber o usuário, a gravação falharia por referência inexistente.
Para evitar isso, o serviço cria um registro provisório do autor no momento do envio, usando a identidade do token — que é confiável, porque a chave de assinatura é compartilhada com o servidor principal. Quando o evento chega, nome e avatar são preenchidos por cima.
As duas sincronizações têm filas separadas, e isso é deliberado: uma falha ao gravar o grafo de seguidores não pode atrasar ou descartar o nome e o avatar de um usuário, que é o que toda tela exibe.
A conversa com o servidor principal
Os dois serviços nunca se chamam diretamente. Toda comunicação passa por uma fila de mensagens, com um endereço único por assunto. Quem publica não sabe quem escuta, e quem escuta não precisa que o outro esteja no ar naquele instante.
O que o AZ Media escuta
| Fila | Escuta | Para quê |
|---|---|---|
user-sync | criação, alteração e exclusão de usuário | Manter nome e avatar na cópia local. |
follow-sync | seguir e deixar de seguir | Alimentar a aba “Seguindo” do AZ Play. |
media-deleted | exclusão de mídia | Marcar a mídia como removida, iniciando a contagem da retenção. |
moderation | pedido de análise | Rodar a moderação. Publicada pelo próprio AZ Media — a fila serve para não travar a resposta ao aplicativo. |
O que o AZ Media anuncia
| Evento | Significa | O servidor principal usa para |
|---|---|---|
media.ready | Mídia aprovada e disponível | Liberar a publicação que dependia dela. |
media.rejected | Barrada pela moderação | Avisar o autor e não exibir o conteúdo. |
media.failed | Falhou no processamento | Mostrar o erro ao autor. |
azplay.published | Vídeo publicado | Alimentar a busca global, que mistura vídeos e publicações numa lista só. |
azplay.updated | Vídeo alterado | Atualizar essa mesma projeção. |
azplay.deleted | Vídeo removido | Retirar da busca. |
azplay.saved / unsaved | Salvo ou removido dos salvos | Montar a aba “Salvos” do perfil, misturando publicações e vídeos. |
azplay.metrics | Contadores de visualização | Ordenar a fileira de vídeos mais vistos. |
azplay.comment.created | Novo comentário | Notificar o autor do vídeo. |
azplay.reply.created | Resposta a comentário | Notificar o autor do comentário. |
mention.created | Alguém citou um @ em algum texto | Resolver o @ e notificar — a gramática dos nomes vive no servidor principal. |
Cada evento de vídeo carrega a informação completa, não apenas o que mudou. Assim, um evento perdido se corrige sozinho no próximo, e um evento repetido não causa dano — é o que permite reprocessar a fila quantas vezes for preciso, sem medo.
Não existe evento por curtida ou por visualização. Uma mensagem a cada visualização inundaria a fila só para manter um número atualizado. Os contadores viajam junto do próximo evento e podem ficar alguns minutos atrasados, o que é aceitável para o que representam.
Mensagens que falham repetidamente vão para uma fila de mensagens problemáticas, em vez de bloquear a fila principal. E cada evento processado fica registrado, de modo que receber a mesma mensagem duas vezes não produz efeito duplicado.
A filtragem por IA
Toda mídia enviada passa por uma análise automática antes de aparecer para alguém. O objetivo é barrar pornografia, violência explícita, drogas e armas — e o que a análise reprova nunca chega ao feed.
São duas camadas, com a mesma lógica de um filtro grosso seguido de um fino: uma análise barata resolve os casos evidentes, e só a zona de dúvida sobe para uma análise mais cara, que entende contexto.
Como calibrar
| Configuração | Padrão | O que faz |
|---|---|---|
MODERATION_UNCERTAIN_LOW |
0,35 | Abaixo disso, aprova direto. Menor = mais rígido, porque manda mais conteúdo para a segunda camada conferir. |
MODERATION_UNCERTAIN_HIGH |
0,7 | A partir disso, reprova direto na primeira camada. Menor = mais rígido, porque reprova com menos certeza. |
Combinações úteis:
- Tudo passa pela segunda camada: limite inferior em
0e superior em1. Nada é decidido localmente — mas a primeira camada continua rodando, como explicado abaixo. - Só a primeira camada: os dois limites iguais, por exemplo ambos em
0,5. A zona de dúvida desaparece e nada é enviado para fora. - Auditar antes de valer: manter a moderação desligada e observar os registros num ambiente de teste, calibrando as faixas com conteúdo real.
Os limites não podem ser invertidos
A verificação de reprovação acontece antes da de aprovação. Com o limite superior menor que o inferior, a zona de dúvida fica vazia e qualquer pontuação acima do superior é reprovada sem consulta à segunda camada — o oposto do pretendido.
Os dois valores precisam estar entre 0 e 1, e o inferior deve ser menor que o superior. Valores fora dessa faixa impedem o serviço de subir.
Onde cada camada roda — e por que isso importa
As duas camadas fazem trabalhos diferentes e, hoje, rodam em lugares diferentes:
Camada 1 · filtragem
Dois modelos carregados na memória do próprio serviço. Responde por 2,5 GB de memória e por um pico de 115% de processamento a cada análise.
Camada 2 · modelo de visão
Hospedado pela Cloudflare. Não consome memória nem processamento do servidor — para ele, é apenas uma chamada de rede e uma espera.
Ela não é uma exigência de qualidade — é uma economia. O modelo de visão custa entre 23 e 52 vezes mais por imagem analisada. A filtragem resolve localmente os casos evidentes e envia para fora apenas a zona de dúvida, mantendo o consumo do serviço de nuvem numa fração da cota gratuita.
Sem ela, toda imagem consultaria o modelo de visão. Isso funciona no volume atual, mas consome entre 34% e 54% da cota diária gratuita — e o teto fica próximo.
O que seria um classificador hospedado
A saída natural para o custo da camada 1 seria mantê-la, mas fora do servidor: em vez de carregar os modelos na própria memória, chamar um classificador hospedado — um modelo de classificação de imagem que roda na infraestrutura de um provedor, do mesmo jeito que a camada 2 já faz.
O funcionamento é o mesmo da camada atual: envia-se a imagem e recebe-se de volta uma lista de rótulos com pontuação de confiança. A diferença está apenas em onde a conta é feita — e o preço é irrisório: cerca de 0,23 unidade de consumo por imagem, contra 5 a 12 do modelo de visão. Com a cota diária gratuita seria possível classificar dezenas de milhares de imagens sem custo.
O classificador de imagem disponível no catálogo da Cloudflare é treinado para reconhecer objetos — cerca de mil categorias do tipo “revólver”, “faca”, “garrafa”. Ele identificaria armas, mas não detecta nudez, que é a categoria mais sensível das quatro que a moderação precisa cobrir.
Os modelos de segurança de conteúdo do mesmo catálogo analisam texto, não imagem. Não existe hoje, ali, equivalente hospedado do detector que roda localmente.
Restam, portanto, três caminhos com cobertura completa: manter a filtragem no servidor com os ajustes de contenção; movê-la para um contêiner sob demanda, que executa o mesmo modelo fora da máquina; ou contratar um serviço especializado em moderação de imagem, cujo produto é exatamente esta função. A comparação entre eles, com números, está na análise de infraestrutura.
Ampliar a zona de dúvida para que tudo seja encaminhado à segunda camada não elimina o processamento local: é a primeira camada que produz a pontuação usada para decidir o encaminhamento, e ela é executada antes de qualquer escalonamento. Nessa configuração somam-se os dois custos.
Executar apenas a camada remota exigiria um caminho no código que dispensasse a análise local — algo que hoje não existe. É o que dá peso a esse serviço na análise de infraestrutura.
Armazenamento e retenção
Cloudflare R2
Armazenamento de objetos. O caminho do arquivo é organizado por finalidade, e o envio acontece por URL assinada de validade curta.
Cloudflare Stream
Recebe, converte para os formatos de reprodução, gera as miniaturas e entrega ao aplicativo.
Registros
Quem enviou, para quê, em que estado está, onde o arquivo mora e o histórico da moderação. Nenhum byte de mídia.
Exclusão em duas etapas
Apagar mídia é feito em dois tempos, e isso é proposital — dá margem para desfazer engano e para atender pedido de suporte.
-
Marcação
Ao receber o aviso de exclusão, a mídia é marcada como removida e some do aplicativo. O arquivo continua onde está.
-
Exclusão definitiva
Uma rotina diária, às 03:00, apaga em definitivo o que foi marcado há mais tempo que o período de retenção — o arquivo na Cloudflare e o registro no banco. É a única rotina agendada do serviço, e ela apaga de verdade: vale conhecer antes de mexer no horário ou no prazo.
Por que o serviço roda em instância única
A rotina diária e o consumo das filas acontecem dentro do mesmo processo que atende as requisições — não há um processo trabalhador separado.
Duas cópias do serviço significariam duas exclusões definitivas às 03:00 e dois consumidores disputando a mesma fila. É por isso que ele precisa rodar em uma instância só, e é uma das razões pelas quais não se encaixa em modelos de execução que criam e destroem cópias livremente.
Autenticação
O AZ Media não emite credencial nenhuma. Quem autentica é o servidor principal: ele assina o token, e o AZ Media apenas confere a assinatura com a mesma chave, sem precisar consultá-lo.
Se a chave dos dois serviços divergir, toda requisição ao AZ Media é recusada — e a mensagem que chega ao aplicativo é apenas “não foi possível conectar”, que não aponta para a causa. A esteira de publicação exige que a chave esteja definida, mas não tem como verificar se o valor é o mesmo dos dois lados.