feat: steadier live updates and notices for public proposals
- The web pings the live connection, reconnects when it goes quiet and reloads what each screen shows after reconnecting. - Dropping a card on a column it cannot go to puts it back. - Owners and admins get a notice when a proposal arrives. - The proposal limit lives in Redis, so it holds across instances. - REST tells whether I voted; pasted images leave the attachment list. - Deleting a project removes its Git integration; no lint warnings left. - Reactions and the blocked badge are components of their own. - Docs: what is done and what is left (chapter 10), Word and PDF. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,10 +10,13 @@ import {
|
||||
mentionedUserIds,
|
||||
NotificationKind,
|
||||
ProjectMemberAddedEvent,
|
||||
ProjectRole,
|
||||
StatusCategory,
|
||||
SYSTEM_ACTOR_ID,
|
||||
TrackerEvent,
|
||||
withoutMentionMarkup,
|
||||
} from '@task-stream/api/tracker/domain';
|
||||
import { PROPOSAL_LABEL } from '../commands/submit-proposal.command-handler';
|
||||
import { FindCommentsRepository } from '../ports/find-comments.repository';
|
||||
import { FindIssuesRepository } from '../ports/find-issues.repository';
|
||||
import { FindProjectsRepository } from '../ports/find-projects.repository';
|
||||
@@ -117,6 +120,25 @@ export class NotificationsEventHandler implements IEventHandler<TrackerEvent> {
|
||||
const memberIds = new Set(project.members.map((m) => m.user.id));
|
||||
|
||||
const drafts: NotificationDraft[] = [];
|
||||
// A proposal from the public form: whoever runs the project should know.
|
||||
if (
|
||||
event instanceof IssueCreatedEvent &&
|
||||
event.actorId === SYSTEM_ACTOR_ID &&
|
||||
event.issue.labels?.includes(PROPOSAL_LABEL)
|
||||
) {
|
||||
for (const member of project.members) {
|
||||
if (
|
||||
member.role !== ProjectRole.OWNER &&
|
||||
member.role !== ProjectRole.ADMIN
|
||||
)
|
||||
continue;
|
||||
drafts.push({
|
||||
userId: member.user.id,
|
||||
kind: NotificationKind.PROPOSED,
|
||||
summary: `Nueva propuesta en ${project.key}: ${ticket}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (event instanceof IssueCreatedEvent && assigneeId) {
|
||||
drafts.push({
|
||||
userId: assigneeId,
|
||||
|
||||
Reference in New Issue
Block a user