fix: remove duplicacao de comentario na troca de responsavel e corrige avatar
- Remove criacao automatica de comentario ao trocar responsavel (ja aparece na timeline) - Adiciona migration removeAssigneeChangeComments para limpar comentarios antigos - Adiciona campos description, type, options, answer ao schema de checklist no mapper - Cria mutation updateAvatar no Convex para sincronizar avatar com snapshots - Atualiza rota /api/profile/avatar para sincronizar com Convex ao adicionar/remover foto 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
59e9298d61
commit
9d1908a5aa
6 changed files with 193 additions and 78 deletions
|
|
@ -872,23 +872,6 @@ async function ensureTicketFormDefaultsForTenant(ctx: MutationCtx, tenantId: str
|
|||
}
|
||||
}
|
||||
|
||||
export function buildAssigneeChangeComment(
|
||||
reason: string,
|
||||
context: { previousName: string; nextName: string },
|
||||
): string {
|
||||
const normalized = reason.replace(/\r\n/g, "\n").trim();
|
||||
const lines = normalized
|
||||
.split("\n")
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line.length > 0);
|
||||
const previous = escapeHtml(context.previousName || "Não atribuído");
|
||||
const next = escapeHtml(context.nextName || "Não atribuído");
|
||||
const reasonHtml = lines.length
|
||||
? lines.map((line) => `<p>${escapeHtml(line)}</p>`).join("")
|
||||
: `<p>—</p>`;
|
||||
return `<p><strong>Responsável atualizado:</strong> ${previous} → ${next}</p><p><strong>Motivo da troca:</strong></p>${reasonHtml}`;
|
||||
}
|
||||
|
||||
function truncateSubject(subject: string) {
|
||||
if (subject.length <= 60) return subject
|
||||
return `${subject.slice(0, 57)}…`
|
||||
|
|
@ -3475,38 +3458,6 @@ export const changeAssignee = mutation({
|
|||
createdAt: now,
|
||||
});
|
||||
|
||||
if (normalizedReason.length > 0) {
|
||||
const commentBody = buildAssigneeChangeComment(normalizedReason, {
|
||||
previousName: previousAssigneeName,
|
||||
nextName: nextAssigneeName,
|
||||
})
|
||||
const commentPlainLength = plainTextLength(commentBody)
|
||||
if (commentPlainLength > MAX_COMMENT_CHARS) {
|
||||
throw new ConvexError(`Comentário muito longo (máx. ${MAX_COMMENT_CHARS} caracteres)`)
|
||||
}
|
||||
const authorSnapshot: CommentAuthorSnapshot = {
|
||||
name: viewerUser.name,
|
||||
email: viewerUser.email,
|
||||
avatarUrl: viewerUser.avatarUrl ?? undefined,
|
||||
teams: viewerUser.teams ?? undefined,
|
||||
}
|
||||
await ctx.db.insert("ticketComments", {
|
||||
ticketId,
|
||||
authorId: actorId,
|
||||
visibility: "INTERNAL",
|
||||
body: commentBody,
|
||||
authorSnapshot,
|
||||
attachments: [],
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
})
|
||||
await ctx.db.insert("ticketEvents", {
|
||||
ticketId,
|
||||
type: "COMMENT_ADDED",
|
||||
payload: { authorId: actorId, authorName: viewerUser.name, authorAvatar: viewerUser.avatarUrl },
|
||||
createdAt: now,
|
||||
})
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue