Faz POST /api/login (usuário/senha) e guarda o token Sanctum usado por todos os outros pedidos. A API resolve a config de storage por usuário (tabela system_configs): cada token vê o seu driver, bucket e regras.
POST /api/info — mostra a config ativa do usuário: driver (local/s3), storage_path, bucket e use_presigned. Útil para confirmar como a API vai responder antes de testar download/upload.
[INTELIGENTE — usado por Moov/GED] Decide sozinho: arquivo até o threshold vai por upload único (POST /api/upload, gravado por stream); acima disso, parte em chunks automaticamente (/api/upload/chunk, mesclagem por stream). O cliente não escolhe o método — é o que o Moov e o GED fazem.
[INTELIGENTE — usado por Moov/GED] GET /api/download — a API decide pela config do usuário: local → transmite o arquivo do disco por stream (BinaryFileResponse, não carrega em memória); s3 + use_presigned → responde 302 para a presigned URL (o browser baixa direto do S3); s3 sem presigned → stream do S3 pela API (readStream, sem bufferizar). O cliente só segue a resposta.
POST /api/upload — envia o arquivo num único pedido (multipart). A API grava por stream (writeStream): lê em blocos e escreve direto no disco/S3, sem carregar o arquivo inteiro em memória. Valida hash SHA-256 (opcional, verificado pós-gravação, também por stream) e recusa se o path já existir. Para arquivos muito grandes ou conexões instáveis, prefira Upload em chunks (envio retomável em partes).
POST /api/upload/chunk (repetido por pedaço) — para arquivos grandes. Cada chunk é guardado num temporário; na última parte a API mescla via stream (fopen + stream_copy_to_stream, sem carregar tudo em memória) e valida o hash final. Tem set_time_limit(0) na mesclagem. DELETE /api/upload/chunk/{id} cancela.
Força o stream pela API (GET /api/download/stream), ignorando presigned — mesmo em s3 + use_presigned.
POST /api/cleanup — remove restos de uploads chunked que ficaram incompletos (temporários órfãos). Manutenção; não afeta arquivos já finalizados.
[AVULSO — só S3] POST /api/presigned/upload/url devolve uma URL assinada; o navegador faz PUT direto no S3, sem os bytes passarem pela API (mais rápido, tira a API do meio). Exige storage_driver = s3 (senão a API recusa, via requireS3). Para arquivos grandes, use o multipart.
[AVULSO — só S3] POST /api/presigned/download/url devolve uma URL assinada com validade configurável; o navegador baixa direto do S3. É o mesmo mecanismo que a porta inteligente /api/download usa internamente quando use_presigned está ligado — aqui você o exercita isolado. Exige storage_driver = s3.