Comments render CommonMark, which leaves a pasted https://… as dead text —
students share links constantly and nobody writes [text](url) by hand. Add
remark-gfm so plain URLs, www hosts and emails become links (and tables and
strikethrough come along), plus table styling so a wide table scrolls inside
itself instead of stretching the page.
Sanitizing is unchanged: javascript: is neither linked nor autolinked, raw
HTML is still dropped, and third-party images are still rendered as plain
links by the img component.
Add an image button to the comment toolbar backed by a new upload route
(images only, 5 MB, stored under comments/<userId>/), inserted as Markdown.
Only images served from our own storage are rendered: a third-party src would
be fetched by every reader of the lesson, exposing their address. Such links
are shown as plain links instead — this also defuses the external images a few
existing comments already carry.
The custom `a` renderer spread react-markdown's internal `node` prop onto
the anchor, leaking node="[object Object]" into the DOM on every comment link.
Destructure it out.
Add a formatting toolbar + safe Markdown rendering (react-markdown +
rehype-sanitize), raise the length limit 2000 -> 10000, and let authors
edit their own comments (new editComment action + editedAt column shown
as an 'изменено' badge).
- Add parentId field to LessonComment (self-referential FK, SetNull on delete)
- Show replies indented under parent comment with left border visual
- Add reply button (visible to admin/curator only) with inline textarea
- Only root comments shown in main list; replies nested below their parent
- Update comment count to include replies
- Server-side validation: only admin/curator can reply, parent must belong to same lesson
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All admin and student Client Components were importing Server Actions
from paths with dynamic segments ([courseId], [moduleId], [lessonId], [slug]).
This caused "Cannot access toStringTag on the server" RSC crash.
Consolidated all Server Actions into static files under src/lib/actions/:
- course-actions.ts (modules + enrollment)
- module-actions.ts (lessons + reorder + move)
- user-actions.ts (bulk grant / revoke)
- student-actions.ts (progress + homework + comments)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>