Skip to content

fix(db): rotas de canvas sem transacao + feat(chat): bastidores da resposta - #235

Merged
actus7 merged 6 commits into
mainfrom
actus7/feat-canvas-projects-phase2
Aug 19, 2026
Merged

fix(db): rotas de canvas sem transacao + feat(chat): bastidores da resposta#235
actus7 merged 6 commits into
mainfrom
actus7/feat-canvas-projects-phase2

Conversation

@actus7

@actus7 actus7 commented Aug 18, 2026

Copy link
Copy Markdown
Owner

fix(db): rotas de canvas/artefato sem $transaction nem nested writes

O adapter PrismaNeonHttp nao suporta transacoes nem writes aninhados
($transaction interno), quebrando com "Transactions are not supported in
HTTP mode" (HTTP 500) na criacao/versao/pin de canvas em producao e local.

  • POST /conversations/:id/canvases: canvas + versao 1 sequenciais com
    compensacao (delete do canvas se a versao falhar)
  • PATCH /canvas/:id e restore: versao + update sequenciais com compensacao
    (remove a versao orfa se o update falhar)
  • POST /canvas/:id/pin: artefato + versao 1 sequenciais com compensacao
  • POST /projects/:id/artifacts/:id/refresh: versao + update sequenciais
  • Resposta serializa versoes via findMany explicito (sem include)
  • Testes unitarios atualizados (12/12); validado contra adapter Neon HTTP
    real com banco Neon (todos os shapes pos-fix funcionam)

feat(chat): bastidores da resposta (roteamento, fallback, TTFT, tokens/s) + nota no feedback

Painel "Bastidores" por mensagem do assistente: provider/modelo efetivo,
tier e motivo do roteamento automatico, tentativas de fallback entre
provedores, TTFT, tokens/s e custo — visivel na linha de timestamp e num
dialogo detalhado.

Feedback: thumbs-down agora aceita uma nota curta opcional
(MessageReaction.note).

Corrige dois bugs que impediam os bastidores de aparecer:

  • O id gerado no cliente para a mensagem do assistente nunca era usado
    como Message.id persistido (o servidor sempre gerava um cuid novo),
    entao o UsageLog nunca encontrava a mensagem certa via join.
  • UsageLog.messageId era @unique, mas o roteamento automatico pode
    tentar varios provedores (fallback) para a mesma mensagem, cada um
    gravando sua propria linha — a constraint descartava silenciosamente
    a tentativa bem-sucedida quando uma tentativa anterior ja tinha
    ocupado o messageId. Agora messageId nao e mais unico e
    GET /conversations/:id/messages agrupa todas as tentativas por
    messageId, escolhendo a bem-sucedida como resumo e as demais como
    "attempts" (fallback cross-provider).

Tokens/s: providers sem chave de API (Duck.ai, Pollinations, Quillbot etc.)
nao reportam uso real de tokens no upstream. Quando outputTokens vem null,
estima a partir do tamanho da resposta (4 caracteres/token), sempre
marcado com "
" para nao parecer um valor exato.

Validado ao vivo: typecheck/lint/test (417 passando) + build limpos, e
testado manualmente no navegador (sign-up, envio de mensagem via Auto,
confirmacao visual do diagnostico "Auto · Default (quillbot/quillbot-ai)
TTFT 1521ms" na linha da mensagem).

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

O adapter PrismaNeonHttp nao suporta transacoes nem writes aninhados
($transaction interno), quebrando com "Transactions are not supported in
HTTP mode" (HTTP 500) na criacao/versao/pin de canvas em producao e local.

- POST /conversations/:id/canvases: canvas + versao 1 sequenciais com
  compensacao (delete do canvas se a versao falhar)
- PATCH /canvas/:id e restore: versao + update sequenciais com compensacao
  (remove a versao orfa se o update falhar)
- POST /canvas/:id/pin: artefato + versao 1 sequenciais com compensacao
- POST /projects/:id/artifacts/:id/refresh: versao + update sequenciais
- Resposta serializa versoes via findMany explicito (sem include)
- Testes unitarios atualizados (12/12); validado contra adapter Neon HTTP
  real com banco Neon (todos os shapes pos-fix funcionam)
Copilot AI lite review requested due to automatic review settings August 18, 2026 19:12
@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
modelhub Error Error Aug 18, 2026 11:58pm

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

…a no feedback

Painel "Bastidores" por mensagem do assistente: provider/modelo efetivo, tier e
motivo do roteamento automático, tentativas de fallback entre provedores, TTFT
e custo — visível na linha de timestamp e num dialogo detalhado (Dialog/Table
reaproveitados de components/ui).

Feedback: thumbs-down agora aceita uma nota curta opcional (MessageReaction.note).

Corrige dois bugs que impediam os bastidores de aparecer:
- O id gerado no cliente para a mensagem do assistente nunca era usado como
  Message.id persistido (o servidor sempre gerava um cuid novo), entao o
  UsageLog nunca encontrava a mensagem certa via join.
- UsageLog.messageId era @unique, mas o roteamento automatico pode tentar
  varios provedores (fallback) para a mesma mensagem, cada um gravando sua
  propria linha - a constraint descartava silenciosamente a tentativa
  bem-sucedida quando uma tentativa anterior ja tinha ocupado o messageId.
  Agora messageId nao e mais unico e GET /conversations/:id/messages agrupa
  todas as tentativas por messageId, escolhendo a bem-sucedida como resumo e
  as demais como "attempts" (fallback cross-provider).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation frontend Frontend changes database Database changes labels Aug 18, 2026
@actus7 actus7 changed the title fix(db): rotas de canvas/artefato sem $transaction nem nested writes fix(db): rotas de canvas sem transacao + feat(chat): bastidores da resposta Aug 18, 2026
Providers sem chave de API (Duck.ai, Pollinations, Quillbot etc.) nao expoem
contagem de tokens no upstream - o roteamento automatico cai neles com
frequencia, entao tokens/s ficava sempre vazio nesses casos.

Quando outputTokens vem null do UsageLog, estima a partir do tamanho da
resposta (~4 caracteres por token) tanto na linha inline quanto no dialogo
de bastidores, sempre marcado com "~" para nao parecer um valor exato.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… pagina

POST /conversations/:id/messages nunca consultava UsageLog - so o GET
seguinte fazia isso. Na pratica isso significava que so as mensagens ja
presentes no ultimo carregamento da pagina mostravam bastidores; qualquer
mensagem enviada depois, na mesma sessao ao vivo, ficava sem os dados ate
recarregar/trocar de conversa.

persistMessages agora roda a mesma consulta/agregacao de UsageLog usada no
GET (reaproveitando buildBackstageByMessageId), entao a resposta do POST
ja vem com os bastidores da mensagem recem-criada.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@actus7

actus7 commented Aug 18, 2026

Copy link
Copy Markdown
Owner Author

Mais um fix na mesma linha: o POST de mensagens nunca olhava pro UsageLog — só o GET seguinte fazia isso. Na prática, só as mensagens já presentes no último carregamento da página mostravam bastidores; qualquer coisa enviada depois na mesma sessão ficava sem os dados até recarregar. persistMessages agora roda a mesma agregação usada no GET, então a resposta do POST já vem com os bastidores da mensagem recém-criada.

…w/codigo

O servidor ja devolvia `backstage` na resposta do POST de mensagens, mas o
cliente descartava: ao reconciliar a mensagem otimista com a persistida ele
copiava apenas `content` e `id`. Resultado: nenhuma mensagem enviada ao vivo
mostrava TTFT/tokens-por-segundo ate recarregar a pagina.

Canvas: html, react e mermaid so tinham o resultado renderizado, sem forma de
inspecionar a fonte. Novo botao alterna entre preview e codigo-fonte (CodeMirror
somente-leitura, com a linguagem certa por tipo). Nao aparece para canvas do
tipo "code", que ja e o proprio fonte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions github-actions Bot added dependencies Dependency changes ci-cd CI/CD changes labels Aug 18, 2026
@actus7
actus7 merged commit 8f148c5 into main Aug 19, 2026
11 of 12 checks passed
@actus7
actus7 deleted the actus7/feat-canvas-projects-phase2 branch August 19, 2026 00:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Backend changes ci-cd CI/CD changes database Database changes dependencies Dependency changes documentation Improvements or additions to documentation frontend Frontend changes tests Test changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants