feat: quick polls in comments that end in a decision

«📊 Añadir una encuesta» adds 2 to 6 options to a new comment. Members,
viewers too, vote by clicking an option (one vote each, which they can
change or take back) and see each option's votes as a bar. Whoever
started it, or an admin, closes it with «Cerrar y decidir»: the most
voted wins (none on a tie) and a «Decidido: …» reply marked as a
decision shows above the ticket. Events of the comment (voted, closed).

API: addComment(…, poll), votePoll, closePoll, Comment.poll;
POST /api/comments/{id}/poll/vote and …/poll/close. MCP: add_comment
poll, vote_poll, close_poll.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-20 20:48:12 +02:00
parent 93d028e870
commit 3a46a236e4
41 changed files with 2144 additions and 77 deletions

View File

@@ -239,6 +239,12 @@ stateDiagram-v2
- **Reacciones**: 👍 👎 😄 🎉 😕 ❤️ 🚀 👀 en los comentarios (`reactToComment(commentId, emoji, on)`,
`POST /api/comments/{id}/reactions`); los miembros, también los lectores. Cada comentario da `reactions` con quién
eligió cada una. No generan actividad ni avisos.
- **Encuestas**: un comentario puede llevar una encuesta de 2 a 6 opciones (`addComment(…, poll)`, `poll` en
`POST …/comments`). Los miembros, también los lectores, votan una opción y pueden cambiarla o retirarla
(`votePoll(commentId, option)`, `POST /api/comments/{id}/poll/vote`; `CommentPollVotedEvent`). Quien la abrió, o un
admin, la cierra (`closePoll(commentId, decide)`, `POST …/poll/close`; `CommentPollClosedEvent`): gana la más votada
(con empate, ninguna) y, con `decide`, se añade una respuesta «Decidido: …» marcada como decisión. El comentario da
`poll { options { text voters } closed winner }`.
- **Conversaciones**: un comentario raíz y sus respuestas se resuelven (`resolveThread(commentId, resolved, conclusion)`,
`PUT/DELETE /api/comments/{id}/resolution`; evento `CommentThreadResolvedEvent`) por quien puede cambiar el ticket;
una respuesta no se resuelve sola. Si trae `conclusion`, antes de cerrarla se añade como respuesta marcada como
@@ -563,7 +569,7 @@ Todas devuelven `CommandResult { id, key, version }`.
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Proyectos | `createProject`, `updateProject`, `updateProjectSettings`, `deleteProject(confirmKey)`, `addProjectMember`, `changeProjectMemberRole`, `removeProjectMember` |
| Tickets | `createIssue`, `updateIssue`, `changeIssueStatus`, `assignIssue`, `linkIssues`, `unlinkIssues`, `setIssueRelease`, `setIssueParent`, `rankIssue`, `addChecklistItem`, `updateChecklistItem`, `removeChecklistItem`, `watchIssue`, `unwatchIssue`, `requestReview`, `answerReview`, `cancelReview`, `pinIssue`, `unpinIssue`, `followTree`, `unfollowTree`, `clearReminder`, `addToMyDay`, `removeFromMyDay` (devuelven `true`), `setReminder`, `removeAttachment` (subir: por REST), `duplicateIssue`, `voteIssue` |
| Comentarios | `addComment(replyTo)`, `editComment`, `deleteComment`, `reactToComment`, `markDecision(commentId, on)`, `resolveThread(commentId, resolved, conclusion)`, `typing(issueId, threadId)`; consulta `decisions(projectId, search)` |
| Comentarios | `addComment(replyTo, poll)`, `votePoll`, `closePoll`, `editComment`, `deleteComment`, `reactToComment`, `markDecision(commentId, on)`, `resolveThread(commentId, resolved, conclusion)`, `typing(issueId, threadId)`; consulta `decisions(projectId, search)` |
| Webhooks | `createWebhook` (devuelve el secreto), `updateWebhook`, `deleteWebhook`, `testWebhook` |
| Git | `addGitRepository` (devuelve su secreto), `rotateGitRepositorySecret`, `removeGitRepository` |
| Sprints | `createSprint`, `updateSprint`, `startSprint`, `closeSprint(carryOverToSprintId)`, `deleteSprint`, `setIssueSprint` |
@@ -772,7 +778,7 @@ Proyectos y tickets se pueden indicar por **id o por clave** (`WEB`, `WEB-12`).
| Usuarios | `GET /api/users/me`, `GET /api/users?search=`, `GET /api/users/{id}` |
| Proyectos | `GET/POST /api/projects`, `GET/PATCH/DELETE /api/projects/{project}` (`DELETE …?confirm=CLAVE`), `POST …/archive`, `POST …/unarchive`, `PUT …/settings`, `…/board`, `…/epics`, `…/stats`, `…/analytics?days=`, `…/insights`, `…/activity`, `…/members` (POST, PATCH, DELETE) |
| Tickets | `GET /api/me/home` (portada), `GET /api/me/portfolio` (cartera), `GET /api/me/issues` (mi trabajo; filtros `project`, `priority`, `bugsOnly`, `overdue`), `GET/POST /api/projects/{project}/issues`, `GET/PATCH /api/issues/{issue}`, `PUT …/status`, `PUT …/assignee`, `PUT …/release`, `PUT/DELETE …/watch`, `POST …/reviews`, `POST …/reviews/{id}/answer`, `DELETE …/reviews/{id}`, `PUT/DELETE …/follow-tree`, `PUT/DELETE …/reminder`, `GET /api/me/reminders`, `GET /api/me/day`, `PUT/DELETE /api/me/day/{issue}`, `GET /api/me/pins` y `PUT/DELETE …/pin` (fijados), `PUT/DELETE …/presence`, `PUT …/parent`, `PUT …/rank`, `POST …/checklist`, `PATCH/DELETE …/checklist/{item}`, `POST/DELETE …/links`, `GET/POST …/comments`, `GET …/history`, `POST /api/issues/{issue}/duplicate`, `PUT/DELETE …/vote` |
| Comentarios | `PATCH/DELETE /api/comments/{commentId}`, `POST …/reactions`, `PUT/DELETE …/decision`, `PUT/DELETE …/resolution`; `GET /api/issues/{issue}/decisions`, `GET /api/projects/{project}/decisions`, `GET /api/me/decisions` |
| Comentarios | `PATCH/DELETE /api/comments/{commentId}`, `POST …/reactions`, `PUT/DELETE …/decision`, `PUT/DELETE …/resolution`, `POST …/poll/vote`, `POST …/poll/close`; `GET /api/issues/{issue}/decisions`, `GET /api/projects/{project}/decisions`, `GET /api/me/decisions` |
| Sprints | `GET/POST /api/projects/{project}/sprints`, `GET/PATCH/DELETE /api/sprints/{sprint}`, `POST …/start`, `POST …/close`, `GET …/progress`, `…/burndown`, `…/issues`, `PUT /api/issues/{issue}/sprint` |
| Vistas | `GET/POST /api/projects/{project}/filters`, `DELETE /api/filters/{id}` |
| Avisos | `GET /api/me/notifications`, `POST /api/me/notifications/read`, `GET/PUT /api/me/notification-settings` |