-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add announcements system and improve user dashboard layout #205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add announcements system and improve user dashboard layout #205
Conversation
Code Review - PR #205: Announcements SystemOverviewThis PR adds a comprehensive announcements management system with admin controls and user-facing display. The implementation is solid overall with good adherence to project conventions. Below are detailed findings organized by severity. 🔴 Critical Issues1. Missing Database MigrationLocation: The Action Required: npm run db:migrateMake sure to commit the generated migration file. 🟡 Important Improvements2. Missing XSS Protection for Markdown RenderingLocation: The component uses Recommendation: <ReactMarkdown
components={{
// Disable HTML in markdown to prevent XSS
html: () => null
}}
>
{announcement.content}
</ReactMarkdown>Or use npm install rehype-sanitize3. Race Condition in Toggle OperationLocation: The Fix: // Use atomic update with Prisma's increment/decrement pattern
await prisma.$executeRaw`
UPDATE "Announcement"
SET "isActive" = NOT "isActive"
WHERE id = ${id}
`Or retrieve the updated value: const updated = await prisma.announcement.update({
where: { id },
data: { isActive: { not: true } },
select: { isActive: true }
})4. No Test Coverage for New FeaturesLocation: Entire feature The PR adds 1,474 lines of code but no dedicated tests for the announcements functionality. Only existing tests were updated for navigation changes. Recommendation: Add tests for:
5. Missing Error Handling for Date ParsingLocation: The code converts strings to dates without validation: expiresAt: expiresAt ? new Date(expiresAt) : null,If an invalid date string is passed, this creates an Invalid Date object that will cause downstream issues. Fix: const validateDate = (dateStr: string | null | undefined): Date | null => {
if (!dateStr) return null
const date = new Date(dateStr)
if (isNaN(date.getTime())) {
throw new Error('Invalid date format')
}
return date
}
// Usage:
expiresAt: validateDate(expiresAt)Or add Zod validation: expiresAt: z.string().datetime().nullable().optional()🟢 Minor Suggestions6. Component SizeLocation: At 443 lines, this component is approaching the recommended 200-300 line limit mentioned in CLAUDE.md. Consider extracting:
7. Hardcoded Content Length LimitsLocation: <p className="mt-2 text-slate-300 text-sm whitespace-pre-wrap line-clamp-3">The 8. Missing data-testid AttributesLocation: Per CLAUDE.md E2E testing best practices, interactive elements should have Recommendation: <motion.article
key={announcement.id}
data-testid={`user-announcement-${announcement.id}`}
// ...
>9. Inconsistent Priority SortingLocation: orderBy: [
{ priority: "desc" },
{ createdAt: "desc" },
],Announcements with the same priority will be sorted by creation date (newest first), but this might not be intuitive. Consider documenting this behavior or adding an explicit 10. No Audit LoggingLocation: The code logs operations but doesn't use the audit log system mentioned in CLAUDE.md security section. For admin actions like creating/deleting announcements, audit logs are recommended. Recommendation: import { auditLog } from '@/lib/security/audit-log'
// After successful creation:
await auditLog({
userId: session.user.id,
action: 'announcement.create',
resourceType: 'announcement',
resourceId: announcement.id,
metadata: { title }
})✅ Strengths
📋 SummaryOverall Assessment: Good implementation with solid architecture. The main concern is the missing migration and potential XSS vulnerability in markdown rendering. Before Merge:
Post-Merge:
Security: |
Code Review: Announcements SystemI've thoroughly reviewed this PR and the implementation looks solid overall. Here's my detailed feedback: ✅ Strengths
🐛 Potential Issues1. Date Validation Vulnerability (actions/announcements.ts:142, 205)Issue: expiresAt: expiresAt ? new Date(expiresAt) : null,Risk: Invalid date strings (e.g., Fix: Add Zod date validation: expiresAt: z.string().datetime().nullable().optional()
// or
expiresAt: z.string().refine((val) => !val || !isNaN(Date.parse(val)), {
message: "Invalid date format"
}).nullable().optional()2. Race Condition in Toggle (actions/announcements.ts:247-262)Issue: const announcement = await prisma.announcement.findUnique({ where: { id } })
// ...
await prisma.announcement.update({
where: { id },
data: { isActive: !announcement.isActive },
})Risk: If two admins toggle simultaneously, both read the same initial state and write the same final state instead of toggling twice. Fix: Use atomic update: const announcement = await prisma.announcement.update({
where: { id },
data: { isActive: { set: undefined } }, // read current value
})
await prisma.announcement.update({
where: { id },
data: { isActive: !announcement.isActive },
})Or simpler - combine into one operation if you don't need the return value synchronously. Impact: Low severity (admin-only, rare scenario), but worth fixing for correctness. 3. Missing Error Case Handling (actions/announcements.ts:229, 197)Issue: await prisma.announcement.delete({ where: { id } }) // Throws if not foundRisk: Generic "Failed to delete announcement" error doesn't tell admin if the announcement doesn't exist vs. actual error. Fix: Check existence first or catch specific Prisma errors: try {
await prisma.announcement.delete({ where: { id } })
} catch (error) {
if (error.code === 'P2025') {
return { success: false, error: "Announcement not found" }
}
throw error
}
|
Code Review - PR #205: Announcements SystemOverall AssessmentThis is a well-implemented feature that follows the project's conventions and best practices. The announcements system is cleanly designed with proper separation of concerns, good security practices, and excellent UX. The dashboard refactoring improves modularity significantly. ✅ Strengths1. Architecture & Code Quality
2. Security
3. Data Layer
4. UX & Accessibility
5. UI Consistency
|
Code Review SummaryThis is a solid implementation. Code follows project conventions well. Strengths
Critical Issues (before merge)
Medium Issues
Minor Issues
RecommendationApprove with changes. Fix critical issues before merge. Great work on the modular refactoring! |
Code Review: Announcements System and Dashboard ImprovementsOverviewThis PR successfully adds an announcements management system and refactors the user dashboard into modular components. The implementation follows the project's conventions and demonstrates good engineering practices overall. ✅ StrengthsArchitecture & Design
Database Design
Security
User Experience
|
Code Review SummaryThis PR adds a comprehensive announcements system and refactors the user dashboard. The implementation is generally solid with good adherence to project conventions. Below are my findings: ✅ StrengthsArchitecture & Design
Security & Validation
Database Design
Code Quality
|
| Metric | Status | Notes |
|---|---|---|
| TypeScript Safety | ✅ Excellent | No 'any' types, proper typing throughout |
| Security | ✅ Excellent | Auth checks, validation, SQL injection protection |
| Architecture | ✅ Excellent | Follows Next.js best practices, proper Server/Client split |
| Test Coverage | ❌ Missing | 0% coverage for new code |
| UI Consistency | Should use existing UI components | |
| Documentation | ✅ Good | Clear function comments, proper JSDoc where needed |
🎯 Recommendations for Merge
Must Fix Before Merge:
- Add comprehensive test coverage for all new functionality
- Replace raw HTML inputs with existing UI components
Should Fix:
- Add foreign key constraint to
createdByfield - Improve skeleton loading dimensions
Nice to Have:
- Code style improvements (optional)
📝 Overall Assessment
Rating: 7/10 - Good implementation with solid architecture and security, but missing critical test coverage.
The code quality is high and follows project conventions well. The main blocker is the lack of tests, which is essential per the project's comprehensive testing strategy (CLAUDE.md). Once tests are added and UI components are used consistently, this will be ready to merge.
Great work on the refactoring and clean separation of concerns! 🎉
Code Review - PR #205: Announcements SystemOverall AssessmentThis is a well-implemented feature that follows the project's architectural patterns and coding standards. The code quality is high, with proper validation, error handling, and security checks. StrengthsArchitecture & Patterns
Security
Code Quality
Database Design
UI/UX
Issues FoundCRITICAL - Missing Test Coverage (HIGH) The announcements feature has ZERO test coverage. CLAUDE.md requires comprehensive tests. Missing:
This is a user-facing feature with admin privileges - tests are essential before merging. MEDIUM - Database Race Condition Location: actions/announcements.ts:247-262 toggleAnnouncementActive uses read-then-write pattern causing race conditions. Recommended fix: Let client pass desired state explicitly rather than toggling server-side. LOW - Missing Date Validation Location: actions/announcements.ts:114 expiresAt accepts string but doesn't validate ISO date format. Add .datetime() validation. LOW - Performance Consideration Location: announcements-page-client.tsx:46-56 Refetches all announcements after every mutation. Consider optimistic updates (not critical). Code Metrics
Dashboard Refactoring ExcellenceThe dashboard refactoring is excellent:
SummaryExcellent engineering practices and valuable functionality. Well-structured, secure, follows conventions. Main blocker: missing test coverage. Recommendation: Request changes for test coverage, then approve. Great work overall! |
- Add announcements management for admins (create, edit, delete)
- Show announcements on user dashboard (at top, hidden if none)
- Refactor user dashboard into modular card components
- Update Plex card to show server name ("Access {serverName}")
- Add Announcements nav item to admin sidebar
- Update tests for new navigation order
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <[email protected]>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Just server name and sign in button, nothing else. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
…ests - Fix race condition in toggle by using explicit setAnnouncementActive function with isActive parameter instead of read-modify-write pattern - Add Zod date validation for expiresAt field (validates ISO date strings) - Add Prisma P2025 error handling for non-existent announcements - Add aria-labels to icon-only buttons for accessibility - Add comprehensive unit tests for all announcements server actions (23 tests) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
6e5df98 to
8244e03
Compare
Pull Request Review: Announcements SystemSummaryThis PR adds a comprehensive announcements management system with admin CRUD operations and user-facing display. The implementation is well-structured with good separation of concerns, excellent test coverage, and follows the project's architecture patterns. ✅ Strengths1. Excellent Test Coverage
2. Strong Security
3. Architecture Adherence
4. Good UX Design
5. Database Design
🔧 Issues & RecommendationsCritical Issues1. Missing Foreign Key Constraint (
|
| Aspect | Rating | Notes |
|---|---|---|
| Architecture | ⭐⭐⭐⭐⭐ | Follows CLAUDE.md patterns perfectly |
| Test Coverage | ⭐⭐⭐⭐⭐ | Comprehensive unit tests (377 lines) |
| Security | ⭐⭐⭐⭐ | Good auth, missing FK constraint & XSS hardening |
| Type Safety | ⭐⭐⭐⭐⭐ | Full TypeScript, Zod validation |
| Performance | ⭐⭐⭐⭐ | Good indexes, minor optimization opportunities |
| Accessibility | ⭐⭐⭐⭐ | Good ARIA, missing focus trap |
| UX | ⭐⭐⭐⭐⭐ | Clean, intuitive, responsive |
🎯 Recommended Action Items
Before Merge:
- ✅ Fix foreign key constraint (critical for data integrity)
- ✅ Add markdown sanitization (security)
- ✅ Improve date validation (use
z.datetime())
Post-Merge:
- Consider migrating to TanStack Query for client state
- Add E2E test coverage
- Add escape key handler for modal
- Verify landing page simplification is intentional
🏆 Overall Assessment
Verdict: Approve with Minor Changes Required
This is a high-quality PR that demonstrates strong understanding of the project's architecture and conventions. The implementation is clean, well-tested, and follows best practices. The issues identified are mostly minor refinements rather than fundamental flaws.
The feature itself is valuable and well-designed. Once the critical security/integrity issues are addressed, this will be a solid addition to the codebase.
Estimated effort to address critical items: ~30 minutes
Great work! 🎉
Summary
Test plan
🤖 Generated with Claude Code