🌀 Estado global
Variáveis fora do escopo de request matam multi-user. current_user num módulo global = bug certo.
Anti-padrão
# BAD
current_user = None
async def handle(msg):
global current_user
current_user = msg.user_id # race condition garantidaPadrão certo
async def handle(msg):
# user vive só no escopo do request
user = await load_user(msg.user_id)
ctx = Session(user=user, request_id=uuid4())
await process(ctx, msg)🏃 Race conditions
2 users perguntando ao mesmo tempo. Cache global retorna resposta de A para B. Bug mais embaraçoso possível — vaza dado entre clientes.
🗂️ Memória vazada
Tabela memories sem coluna user_id. Busca retorna fatos de qualquer user. LGPD pune.
💸 Custo opaco
Sem atribuição de tokens por user, você não cobra, não detecta abuso, não precifica. Modelo de negócio fica impossível.
📞 Suporte impossível
"O agente respondeu errado ontem às 14h" sem audit log por user = você nunca reproduz. Retenção cai.
📋 Checklist de prontidão
6 perguntas antes de aceitar 2º user
- ☐ Toda função recebe user_id?
- ☐ Memória tem coluna user_id FK?
- ☐ Tokens são contados por user?
- ☐ Audit log inclui user_id e request_id?
- ☐ Existem testes com 2 users simulados?
- ☐ Kill switch por user específico funciona?
📝 Resumo
5 bugs nascem do mesmo problema: estado global + falta de user_id em tudo. Refatorar antes do 2º user é mais barato que depois.