Conversation
## New files - AGENTS.md: Comprehensive guidelines for AI coding assistants - Project structure, conventions, patterns - Mongoose conventions (foreign keys, aliases, encryption) - Error handling pattern (http-errors, ERROR_CODES, asyncHandler) - Route protection (guard middleware) - Logging rules, utility libraries - Code review guidelines with severity levels - CLAUDE.md: Claude Code specific configuration - References AGENTS.md for main guidelines - Documents available subagents and slash commands ## Claude Code integration - .claude/agents/code-reviewer.md: Critical code review subagent - .claude/agents/architect.md: Architecture analysis subagent - .claude/agents/security-auditor.md: Security audit subagent - .claude/commands/review.md: /review slash command - .claude/commands/architecture-review.md: /architecture-review command - .claude/commands/security-review.md: /security-review command ## Code review workflow After developing a feature: - /review for general code review - /architecture-review for design analysis - /security-review for security audit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## New modules - Comment: schema, service, controller, routes, tests - Notification: schema, service, controller, routes ## Comment features - CRUD operations with soft delete - Block-level comments with snapshot (position, type) - Threading (parent/child comments) - Categories (design, content, general) - Severities (info, important, blocking) - Resolution status with resolver tracking - User mentions with validation - Cascade delete (parent + replies) - Permissions: author can edit/delete, admin can delete any ## Notification features - Types: mention, reply, resolved - In-app notifications with read status - 90-day TTL auto-cleanup - Denormalized data for quick display ## API Endpoints Comments: - GET/POST /api/mailings/:mailingId/comments - GET /api/mailings/:mailingId/comments/counts - GET /api/mailings/:mailingId/comments/unresolved-count - GET/PATCH/DELETE /api/comments/:commentId - PATCH /api/comments/:commentId/resolve Notifications: - GET /api/notifications - GET /api/notifications/unread-count - PATCH /api/notifications/:notificationId/read - PATCH /api/notifications/read-all ## Tests - 25 unit tests with Jest mocks (all passing) - Coverage: schema 99%, service 89.7% 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
## New extension - badsender-comments.js: Full Knockout.js extension for comments ## Features - Sidebar panel with comments list and form - Toolbar toggle button with unresolved count badge - CRUD operations (create, edit, delete, resolve) - Reply threading support - Category selector (general, design, content) - Severity selector (info, important, blocking) - Block filtering capability - Lazy loading on first panel open ## UI Components - Comments panel in toolbox.tmpl.html - Toggle button in main.tmpl.html toolbar - 250+ lines of CSS styles in badsender-editor.less ## Translations - French (35 keys in badsender-fr.js) - English (35 keys in badsender-en.js) ## API Integration - GET /api/mailings/:mailingId/comments - GET /api/mailings/:mailingId/comments/counts - POST /api/mailings/:mailingId/comments - PATCH /api/comments/:commentId - DELETE /api/comments/:commentId - PATCH /api/comments/:commentId/resolve 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
## Phase 3 - UI Integration - Mailings table: add comments column with unresolved count badge - unresolvedCommentsCount added to mailings API via MongoDB aggregation - Click on comment icon opens editor with ?comments=1 parameter - Translations FR/EN for notifications and comments ## Phase 4 - Notifications - NotificationBell component with dropdown and polling (60s) - Vuex notification store with actions (fetch, markRead, markAllRead) - Relative time display (just now, X min ago, etc.) - Integration in default layout header ## Editor enhancements - Block toolbar: comment button with badge counter - Navigate to block from comment (click on block badge) - Block highlight animation when navigating - ?comments=1 URL parameter auto-opens comments panel - Styled mentions with formatCommentText() and CSS ## Bug fixes - Fix user._id vs user.id in insertMention (was showing undefined) - Fix populated _company object in mention validation query - Route order: comments routes before mailings (catch-all issue) ## Documentation - Testing checklist for manual QA (docs/comments-testing-checklist.md) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
## Design System - Create docs/design-system.md documenting colors, typography, components - Primary Dark #0d2b3e, Accent Teal #2dd4bf, Accent Coral #f04e23 - Work Sans font family ## Comments Panel Redesign - Replace dropdowns with clickable chips for category/severity - Replace text actions with icon buttons (reply, resolve, edit, delete) - Modern card styling with shadows and severity-based left border - Relative date formatting (À l'instant, X min, Xh, Xj, date) - Replace technical block ID with "Aller au bloc" link - Smooth transitions and hover states ## Translations - Add new keys: comments-count-label, comments-date-now, comments-go-to-block - Fix syntax error in French translation (escaped quotes) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
## UI Improvements - Flat design: remove shadows, use thin borders on cards and chips - Chips without borders, gray background, dark fill when selected - Badges with pill shape (border-radius: 12px) - Toolbar badge: horizontal alignment, tight to icon, clickable - Floating indicator: fixed bottom-right pill with pulse animation loads unresolved count on init via lightweight API call ## Resolved Comments - Collapsed by default (header only: author, date, badge, category) - Chevron icon to indicate expand/collapse - Sorted below unresolved comments - Click to expand/collapse ## Layout Changes - Category badge moved from meta section to comment header - "Aller au bloc" link moved to actions row, aligned right - Design system documentation updated to v1.1 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
## HIGH - Use .slice().sort() instead of .sort() to avoid mutating ko.computed source - Restore i18n on "Aller au bloc" text (was hardcoded French) - Add clickBubble: false on all action buttons inside resolved comments ## MEDIUM - Move expandedResolvedIds to OBSERVABLES section - Remove dead .comment-meta CSS rule (no longer in HTML) ## LOW - Rename 'Option B' comment to descriptive text - Add comment explaining position:fixed inside overflow:hidden parent 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
There was a problem hiding this comment.
-
PR could be at least separated in two : 1 for Comment, 1 for notification so that it would be easier to review.
-
Agents files where not necessary in this PR as they are in another PR
-
Globally, the code seems well written and helped gained lots of time (not sure i could have write this and certainly not in a day -> more like 10 days)
-
Also convention for branch name could be added in agents instructions.
-
It seems that instructions of file no longer than 300 lignes is not always respsected and we have huge files
-
Add AI policies file
-
The CI is failing, one test is failling
UX :
-
Add a comment button looks like a add a badge -> see to write add comment instead
-
The comment panel on the left hide the blocks -> needs to close and reopen to check comments and improve mail and blocks -> check if it is okay
-
If the comment icon is on the top right, the panel should be on the right. On the contrary if the panel is left, ths-e button should be on the left with the others blocks, style etc.
-
the panel top should not mask the other tab options to open other panels.
-
the filtered options is not clear : how to activate/ deactivate it to see only block comment or all : should be a toggle ?
-
the red number icon in the top bar is overlapping with the rest
-
Add a number icon of unresolved comments by block ?
-
Notification should be cleared and stored some where else to see historic -> i mark one as read and it is still in the pop up
Problems while testing :
-
cannot update my own comment as a user
-
cannot delete my own comment as a user
-
no notification on new comments on my email
-
not sure if the interface should display the user id when mentioning them in text edition area and in the notification note
-
error 500 when clicking on a notification
-
not related to this PR but to check the workspace loading pb : infinite workspace toggle when connecting
| --- | ||
|
|
||
| ## Code Review Guidelines | ||
|
|
There was a problem hiding this comment.
We can add here or int the command section to use yarn code:lint or yarn code:fix to detect and fix linter warnings and errors and also run prettier formatting
| ``` | ||
|
|
||
| ## Available Subagents | ||
|
|
There was a problem hiding this comment.
See to add a UX agent file that verify that component and theme are reused -> use the design-system.md file
| @@ -0,0 +1,167 @@ | |||
| # Checklist de Tests - Feature Commentaires MVP | |||
There was a problem hiding this comment.
Not sure that we should keep this file.
It should be put somewhere else like a /test folder inside the documentation folder (if just a /test folder it could be confused with unit and integration test that runs with a CI).
| @@ -0,0 +1,669 @@ | |||
| 'use strict'; | |||
There was a problem hiding this comment.
to put in a /test folder and see if it is run by the CI
| }, | ||
|
|
||
| // Denormalized data for quick display without joins | ||
| actorName: { |
There was a problem hiding this comment.
Add comment that actor =
Someaone that mentionned others
Someone that answered
Someone that resolved a comment
| /** | ||
| * Mark a comment as resolved | ||
| */ | ||
| async function resolveComment({ commentId, user }) { |
There was a problem hiding this comment.
Not possible to Unresolved a comment ?
| viewModel.commentsStatus('loading'); | ||
|
|
||
| $.ajax({ | ||
| url: apiBaseUrl + '/mailings/' + mailingId + '/comments', |
There was a problem hiding this comment.
Used 2 times, may be extract in a const
| viewModel.formatCommentDate = function (dateString) { | ||
| if (!dateString) return ''; | ||
| const date = new Date(dateString); | ||
| const now = new Date(); | ||
| const diffMs = now - date; | ||
| const diffMins = Math.floor(diffMs / 60000); | ||
| const diffHours = Math.floor(diffMs / 3600000); | ||
| const diffDays = Math.floor(diffMs / 86400000); | ||
|
|
||
| if (diffMins < 1) { | ||
| return viewModel.t('comments-date-now'); | ||
| } else if (diffMins < 60) { | ||
| return diffMins + ' min'; | ||
| } else if (diffHours < 24) { | ||
| return diffHours + 'h'; | ||
| } else if (diffDays < 7) { | ||
| return diffDays + 'j'; | ||
| } else { | ||
| // Format: "12 jan." or "12 jan. 2025" | ||
| const months = ['jan.', 'fév.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.']; | ||
| const day = date.getDate(); | ||
| const month = months[date.getMonth()]; | ||
| const year = date.getFullYear(); | ||
| const currentYear = now.getFullYear(); | ||
| if (year === currentYear) { | ||
| return day + ' ' + month; | ||
| } | ||
| return day + ' ' + month + ' ' + year; | ||
| } |
There was a problem hiding this comment.
Partially duplicated with notification-bell.vue.
Extract this code in a utils file, or use a lib such as date-fns or dayjs
| COMMENT_MENTION: 'comment_mention', | ||
| COMMENT_REPLY: 'comment_reply', | ||
| COMMENT_RESOLVED: 'comment_resolved', | ||
| COMMENT_NEW: 'comment_new', |
There was a problem hiding this comment.
Not used in code, to verify if it is working
| const notifications = await notificationService.findByUser({ | ||
| userId, | ||
| limit: limit ? parseInt(limit, 10) : 20, | ||
| skip: skip ? parseInt(skip, 10) : 0, |
There was a problem hiding this comment.
To check :
- is skip parameter really used ?
- is skip parmaeter the one to use ? is it a pagination system ?




No description provided.