feat(audit-log): dashboard audit log system with slideover UI#144
feat(audit-log): dashboard audit log system with slideover UI#144
Conversation
✅ Deploy Preview for wolfstar-rocks-et34281 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
- Add AuditLogChange and AuditLogEntry interfaces in shared/types/audit-log.ts - Add AuditLogQuerySchema valibot schema in shared/schemas/audit-log.ts - Add AuditLogChanges type to PrismaJson namespace - Export new modules from barrel files Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Add a composable for fetching guild audit log data from the API. Uses useRouteParams for guild ID and useLazyAsyncData for data fetching, with an optional immediate parameter to control fetch timing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
- Add DashboardAuditLog model to Prisma schema - Add shared types (AuditLogChange, AuditLogEntry) and valibot schemas - Create GET /api/guilds/[guild]/audit-logs endpoint - Modify PATCH settings endpoint to record audit log entries - Create useAuditLog composable - Create AuditLogSlideover Vue component - Integrate into manage.vue with Activity Log button Agent-Logs-Url: https://github.com/wolfstar-project/wolfstar.rocks/sessions/ece5c6cc-9c86-4ee6-895a-4df3200df49f Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Agent-Logs-Url: https://github.com/wolfstar-project/wolfstar.rocks/sessions/ece5c6cc-9c86-4ee6-895a-4df3200df49f Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #144 +/- ##
==========================================
- Coverage 67.17% 65.34% -1.83%
==========================================
Files 77 83 +6
Lines 1916 2037 +121
Branches 577 625 +48
==========================================
+ Hits 1287 1331 +44
- Misses 498 559 +61
- Partials 131 147 +16
🚀 New features to boost your workflow:
|
Contribution Guidelines ReviewThanks for this detailed PR — the audit log feature is well-described and the title follows Conventional Commits format correctly. ✅ There's one item from the contribution guidelines that needs attention before this can be marked ready: 📸 Missing screenshots for frontend changesThe guidelines state:
This PR introduces
✅ Everything else looks good
Once screenshots are added and the PR is marked ready for review, this should be good to go!
|
There was a problem hiding this comment.
Code Review — Audit Log System (draft)
This is a solid feature addition with a clean architecture. CI shows lint ✅ · unit tests ✅ · component tests ✅ — but 🧹 Unused code check ❌ is failing (needs investigation before merge). Browser tests, accessibility audits and benchmarks were still running at review time.
Since this is a draft I'm not blocking merge, but there are two runtime-breaking bugs that must be addressed before this is ready.
🐛 Must fix (runtime errors)
| # | File | Issue |
|---|---|---|
| 1 | server/database/schema.prisma |
Model named AuditLog generates prisma.auditLog, but all code calls prisma.dashboardAuditLog. Also @@Map("audit_log") disagrees with the migration's dashboard_audit_log table. Fix: rename model to DashboardAuditLog and change @@map`` to "dashboard_audit_log". |
| 2 | shared/schemas/audit-log.ts |
number() rejects string query params — every request to GET /audit-logs?limit=50 will return 400. Use coerce(number(), Number) (see inline comment). |
⚠️ Should address
| # | File | Issue |
|---|---|---|
| 3 | server/api/guilds/[guild]/settings.patch.ts |
deriveSection classifies the whole batch by keys[0] only — mixed-section saves are mislabelled. |
| 4 | app/composables/useAuditLog.ts |
Cache key is a static string evaluated once at setup — pass a getter () => \guild:...`` so Nuxt can react to guild navigation. |
| 5 | app/components/guild/AuditLogSlideover.vue |
Entries list lacks aria-live="polite" — screen reader users won't know when content refreshes. |
💡 Nice-to-have
| # | File | Suggestion |
|---|---|---|
| 6 | AuditLogSlideover.vue |
Replace hand-rolled formatRelativeTime with useTimeAgo from VueUse — it's already in the project and stays reactive as time passes. |
🧹 CI failure
The unused code check is failing — likely caused by the new AuditLogQuery type export or another export not yet consumed. Run pnpm knip locally and add any genuinely unused exports to the knip ignore list, or wire them up properly.
Generated by WolfStar Code Quality Reviewer for issue #144 · ● 778.1K
Contribution Guidelines Review 🔍Hi ✅ What looks good
🔧 A couple of things to address1. Missing before/after screenshotsThe guidelines require:
This PR adds a new 2. PR is still in draftThe PR is currently marked as a draft, which typically means it isn't ready for review or merge yet. When the implementation is complete and the checklist below is done, mark it as "Ready for review". 📋 Pre-submission checklistBefore marking ready for review, please confirm:
Once those are addressed, this will be in great shape! Feel free to ping when it's ready. 🚀
|
…ation and UI components
Contribution Guidelines Review 👋Thanks for this detailed PR! The implementation looks well-structured and the description clearly explains the changes across the database, server, shared, and frontend layers. A few contribution process items to address before this is ready for review: ❌ Missing screenshots for frontend changesThe contribution guidelines require:
This PR introduces a new
i️ PR is still in draftThe PR is currently marked as a draft. Once the implementation is complete and CI checks pass (build, lint, typecheck, tests), please mark it as ready for review. ✅ What looks good
Once screenshots are added and the draft status is removed, this will be much closer to ready. Let us know if you have any questions!
|
- Create reusable ActivitySection.vue component for section lifecycle - Migrate audit log and moderation cases sections in General.vue - Encapsulates heading, badge, refresh, loading, empty, list, and view-all
|
Hey I ran a quick check against the contribution guidelines. Here's where things stand: ✅ Looks good
⏳ Before marking ready This PR is currently in draft state, so I'm holding off on the
Once those are green and you mark the PR as ready, feel free to ping for another look and the label can be added then. 🚀
|
|
Thanks for this contribution! The implementation looks substantial and well thought-out. Before this PR can move forward, there are a few contribution process items to address. 👇 PR TemplateThe description doesn't follow the PR template. Please update it to include the required sections:
The technical detail in the current description is great — it just needs to be restructured into the template format. Own words, pleaseFrom CONTRIBUTING.md § Using AI:
The current description reads as AI-generated. Please rewrite it in your own voice — even a few plain sentences explaining what this does and why you built it is far more valuable than a detailed AI summary. Draft statusThis PR is currently marked as a draft. When it's ready for review, please mark it as ready and ensure CI checks pass (lint, typecheck, build, tests). Once those are addressed, re-request review and a maintainer will take a look. Thanks again for contributing! 🙌
|
|
@copilot apply changes based on the comments in this thread |
…refs, fix duplicate template, lazy fetch, squash migrations, clean types - Remove orphaned moderation cases section from General.vue (references deleted composables) - Fix AuditLogSlideover.vue: remove duplicate loading/empty blocks, use immediate: false + watch - Switch audit-logs.get.ts from defineWrappedCachedResponseHandler to defineWrappedResponseHandler - Clean up redundant imports/exports in types.ts - Squash two migrations into single audit_log migration Agent-Logs-Url: https://github.com/wolfstar-project/wolfstar.rocks/sessions/69b7b2a0-6ced-4466-bb1b-a712aef12174 Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Applied all review fixes in 0b5b4f2:
|
…pty state actions
- Extract audit-log helpers to app/utils/audit-log.ts (auto-imported) - Add member avatar and action description to General.vue entries - Widen entry spacing to match AuditLogSlideover rhythm - Fix badge overflow text to show '+N more' consistently - Left-align Server Info buttons on mobile
…ate value formatting
…nd update related logic
…e handling in general settings
…ate with audit log data Co-authored-by: Copilot <copilot@github.com>

Adds a persistent audit trail for guild settings changes — tracks who modified what, when, with before/after values. Surfaces this via an Activity Log slideover in the dashboard (based on the Nuxt UI dashboard NotificationsSlideover pattern).
Database
AuditLogPrisma model with composite index on(guild_id, created_at DESC)and FK toguildsaudit_logtable directlyServer
GET /api/guilds/[guild]/audit-logs— paginated, auth-gated (defineWrappedResponseHandler, no caching to enforce auth on every request), rate-limitedPATCH /api/guilds/[guild]/settings— now records audit entries on write, capturing old/new values per key via pre-mutation snapshot. Section derived from key prefix using majority-vote across all changed keys (permissions*,selfmod*/noMentionSpam*→ moderation,channels*,roles*, etc.). Audit write is fire-and-forget to avoid blocking the settings response.Shared
AuditLogChange/AuditLogEntrytypes,AuditLogQuerySchema(valibot withunknown() → transform(Number)coercion for query string params),PrismaJson.AuditLogChangesFrontend
useAuditLogcomposable — lazy fetch with reactive function-based cache key, returnsentries+totalAuditLogSlideover.vue— section-specific icons, relative timestamps, member name + avatar display, change key badges (capped at 3 + overflow), loading/empty states, lazy fetch (immediate: false) with auto-refresh on slideover open viawatchGeneral.vueshowing last 5 audit log entries inline (audit log only, no moderation cases)manage.vuenavbar (bell icon,Nshortcut)