Skip to content

feat: add AuditLogManager for dashboard settings audit logging#188

Open
RedStar071 wants to merge 37 commits into
mainfrom
feat/audit-log-manager
Open

feat: add AuditLogManager for dashboard settings audit logging#188
RedStar071 wants to merge 37 commits into
mainfrom
feat/audit-log-manager

Conversation

@RedStar071
Copy link
Copy Markdown
Member

Summary

Adds an AuditLogManager to track dashboard settings changes, adapted from wolfstar.rocks PR #144 and following the same conventions as `PermissionNodeManager` and other existing managers.

Changes

Database

  • Prisma model: `AuditLog` with `@@Map("audit_log")`, indexed on `(guildId, createdAt DESC)`
  • Migration: `20260416120000_add_dashboard_audit_log`

Core

  • `AuditLogManager`: `constructor(settings)`, `onPatch(settings)`, `update/add/remove/write` methods, static helpers (`deriveSection`, `classifyKey`, `serializeValue`)
  • `AuditLogChange` type in `types.ts` with optional `oldValue`/`newValue`
  • `AuditLogChanges` PrismaJson augmentation in `Augments.d.ts`
  • SettingsContext integration with constructor/onPatch pattern
  • `readSettingsAuditLog()` exported from `functions.ts`

Routes

  • `GET /guilds/:guild/audit-logs`: Paginated endpoint with ratelimit, returns `{ entries, total }`
  • `PATCH /guilds/:guild/settings`: Fire-and-forget audit log entry on settings mutation using `structuredClone` snapshot

Tests

  • 18 unit tests covering constructor, onPatch, update, add, remove, deriveSection, classifyKey, serializeValue

- Add AuditLog Prisma model with migration
- Add AuditLogManager following PermissionNodeManager conventions
- Add AuditLogChange type and PrismaJson augmentation
- Integrate into SettingsContext with constructor/onPatch pattern
- Wire audit logging into settings.patch.ts with structuredClone snapshot
- Add GET /guilds/:guild/audit-logs endpoint with pagination
- Add 18 unit tests for AuditLogManager
Copilot AI review requested due to automatic review settings April 16, 2026 11:51
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 16, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Implements audit logging for guild settings and command execution: deterministic envelope canonicalisation and SHA‑256 hashing, hash‑chained storage in Postgres via Prisma, an AuditLogManager for serialised writes and channel emits, API retrieval, embed builders, listener hooks, tests, and a verification script.

Changes

Guild Settings Audit Logging System

Layer / File(s) Summary
Database schema and Prisma models
prisma/migrations/20260416120000_add_dashboard_audit_log/migration.sql, prisma/migrations/20260516000000_add_channels_logs_command_settings/migration.sql, prisma/schema.prisma, src/lib/database/settings/constants.ts
Creates audit_event and audit_chain_head tables with unique hash constraint and composite indexes. Adds Guild fields channelsLogsCommand and channelsLogsSettings. Defaults new settings to null.
Audit types and action constants
src/lib/database/settings/types.ts, src/lib/database/settings/auditActions.ts, src/lib/types/Augments.d.ts
Defines DashboardAuditAction, AuditOutcome, DashboardAuditChanges, DashboardAuditEntry unions and interfaces. Exports guildCommandExecute constant. Augments PrismaJson.AuditEventChanges.
Envelope canonicalisation and hashing
src/lib/database/settings/structures/AuditLogEnvelope.ts, tests/lib/database/settings/structures/AuditLogEnvelope.test.ts
Implements AuditEnvelopeInput type, deterministic canonicalize() (stable key order, bigint→string), and hashEnvelope() SHA‑256 hashing. Tests verify determinism and correct field mutations.
AuditLogManager implementation
src/lib/database/settings/structures/AuditLogManager.ts, tests/lib/database/settings/structures/AuditLogManager.test.ts
Records audit events for settings (update/add/remove/accessDenied) and commands. Acquires PostgreSQL advisory lock, reads chain head, canonicalises envelope, writes event with hash linkage, upserts chain head. Emits GuildMessageLog asynchronously. Tests cover operations, chain integrity, locks, and channel fan‑out.
SettingsContext integration and helpers
src/lib/database/settings/context/SettingsContext.ts, src/lib/database/settings/functions.ts, src/lib/database/settings/index.ts
Adds AuditLogManager private field and auditLog getter to SettingsContext. Forwards onPatch updates. Exports readSettingsAuditLog() helper and barrel re‑exports.
Audit logs API endpoint
src/routes/guilds/[guild]/audit-logs.get.ts
Implements paginated GET endpoint. Queries audit_event by tenant and allowed actions. Resolves actors to APIGuildMember, converts JSON patch to DashboardAuditChanges, returns entries and total count.
Settings PATCH route integration
src/routes/guilds/[guild]/settings.patch.ts
Clones pre/post settings state around transaction. Initialises audit log before write, applies settings within transaction, updates audit log asynchronously with before/after snapshots.
Guild log embed builders
src/lib/util/functions/auditLogEmbeds.ts, src/lib/util/functions/index.ts
Implements buildCommandExecuteEmbed() (blue, user/command/type/channel fields) and buildSettingsChangeEmbed() (colour/title by action, reason description, up to 10 diff fields). Includes value formatting and path resolution helpers.
Command listener audit logging
src/listeners/commands/chatInputCommandSuccessLogger.ts, src/listeners/commands/contextMenuCommandSuccessLogger.ts, src/listeners/commands/messageCommandSuccessLogger.ts
Records chat‑input, context‑menu, and message command execution asynchronously via AuditLogManager.command() when guild settings are cached. Errors suppressed.
Internationalization and defaults
src/languages/en-US/events/guilds-logs.json, src/lib/i18n/languageKeys/keys/events/guilds/Logs.ts
Adds English template keys for command execution and settings titles plus log field labels. Extends default guild settings with new channel keys.
Comprehensive test coverage
tests/lib/database/settings/structures/AuditLogEnvelope.test.ts, tests/lib/database/settings/structures/AuditLogManager.test.ts, tests/lib/database/settings/functions.test.ts, tests/lib/util/functions/auditLogEmbeds.test.ts, tests/lib/database/settings/structures/PermissionNodeManager.test.ts
Tests canonicalisation, hashing determinism, AuditLogManager operations, bigint normalisation, chain integrity, advisory locks, channel emit fan‑out, helpers, and embeds. Adds expect(...).toBeDefined() checks in PermissionNodeManager tests.
Audit chain verification script
scripts/audit-verify.mjs
Standalone Node.js tool that loads .env, connects to Postgres, reads all audit_event rows, recomputes envelope hashes, detects chain forks/cycles/mismatches, and reports integrity violations with non‑zero exit code.
Dependencies and configuration
package.json, .oxlintrc.json
Adds evlog and bumps Prisma, discord.js, TypeScript, and build tool versions. Updates packageManager to pnpm@10.33.3. Adds src/languages/** to oxlint ignore patterns.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main feature addition: an AuditLogManager for dashboard settings audit logging.
Description check ✅ Passed The description is directly related to the changeset, providing clear details about database changes, core implementation, routes, and tests for audit logging.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/audit-log-manager

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces dashboard settings audit logging by adding a new AuditLog Prisma model plus a settings-side AuditLogManager, wiring it into the settings PATCH flow, and exposing a paginated API endpoint to read audit log entries.

Changes:

  • Add AuditLog Prisma model + migration (table audit_log, index on (guild_id, created_at DESC)).
  • Add AuditLogManager and integrate it into SettingsContext, plus exported readSettingsAuditLog() helper.
  • Add GET /guilds/:guild/audit-logs endpoint and add audit-log writes to PATCH /guilds/:guild/settings, plus unit tests for AuditLogManager.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/lib/database/settings/structures/AuditLogManager.test.ts Adds unit tests for audit log manager behavior (constructor/onPatch/update/add/remove + section/value derivation).
src/routes/guilds/[guild]/settings.patch.ts Adds fire-and-forget audit logging on settings mutation (currently has a snapshot correctness issue).
src/routes/guilds/[guild]/audit-logs.get.ts Adds paginated endpoint to fetch audit logs for a guild (minor consistency issue vs other routes).
src/lib/types/Augments.d.ts Adds PrismaJson augmentation type AuditLogChanges.
src/lib/database/settings/types.ts Introduces AuditLogChange type.
src/lib/database/settings/structures/AuditLogManager.ts Implements AuditLogManager with update/add/remove/write + section/value helpers.
src/lib/database/settings/index.ts Re-exports AuditLogManager.
src/lib/database/settings/functions.ts Adds readSettingsAuditLog() helper (currently returns cached manager, affecting snapshot use-cases).
src/lib/database/settings/context/SettingsContext.ts Adds auditLog manager to SettingsContext and updates it on patch.
prisma/schema.prisma Adds AuditLog model and Guild.auditLogs relation.
prisma/migrations/20260416120000_add_dashboard_audit_log/migration.sql Creates audit_log table, index, and FK to guilds.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/routes/guilds/[guild]/settings.patch.ts Outdated
Comment thread src/lib/database/settings/functions.ts
Comment thread src/routes/guilds/[guild]/audit-logs.get.ts
Comment thread tests/lib/database/settings/structures/AuditLogManager.test.ts Outdated
RedStar071 added 5 commits May 9, 2026 19:18
- Replace AuditChainHead per-tenant design with singleton id=default
- Rewrite migration.sql: UUID PK on audit_event, actorType/targetType
  columns, hash as UNIQUE (not PK), no requestId/traceId columns
- Remove sequence: bigint from AuditEnvelopeInput (no lastSequence)
- Rewrite AuditLogManager#write: global advisory lock, findUnique by
  id=default, correct auditEvent column set (actorType, no requestId)
- Regenerate Prisma client (singleton AuditChainHead shape)
- Fix tests: makeHead singleton shape, drop lastSequence assertions
- Replace auditLog.findMany with auditEvent.findMany filtered by
  tenantId + action IN DASHBOARD_AUDIT_ACTIONS
- Rename take/skip -> limit/offset (parseInt, clamped to [1,100])
- Add patchToChanges helper: auditDiff {before,after} -> {added,removed,changed}
- Parallel member resolution with fallback for unresolved actors
- Return DashboardAuditEntry[] with id=UUID, guildId from route param
- settings.patch: capture before/after snapshots around submit() and
  pass both to auditLog.update(actorId, before, after)
@RedStar071
Copy link
Copy Markdown
Member Author

@copilot resolve the merge conflicts in this pull request

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (4)
prisma/schema.prisma (2)

246-252: Operational consideration: Global chain head serialization.

The singleton chain head (id='default') means all audit writes across all guilds serialize through one advisory lock. For low-frequency dashboard settings changes, this is acceptable. If audit logging expands to high-frequency events, consider per-tenant chain heads to reduce lock contention.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@prisma/schema.prisma` around lines 246 - 252, The AuditChainHead model uses a
singleton id ("default") which serializes all tenants through one chain head;
update the model to support per-tenant chain heads by adding a tenant identifier
(e.g., guildId or tenantId String field), make the primary key include that
tenant identifier (either by replacing the single id with guildId as `@id` or by
introducing a composite @@id([guildId, id]) ), and ensure hash/updatedAt remain
and map stays @@map("audit_chain_head"); adjust any code that references
AuditChainHead.id to use the tenant-aware key
(AuditChainHead.guildId/AuditChainHead.tenantId) so advisory locks can be taken
per-tenant.

227-228: ⚡ Quick win

Consider aligning ID column types with Guild model.

actorId and tenantId use unbounded TEXT, whilst Guild.id uses VARCHAR(19) (Discord snowflake size). Using consistent types would improve index efficiency and make the schema more self-documenting.

♻️ Suggested schema alignment
-  actorId    String   `@map`("actor_id")
+  actorId    String   `@map`("actor_id") `@db.VarChar`(19)
...
-  targetId   String?  `@map`("target_id")
+  targetId   String?  `@map`("target_id") `@db.VarChar`(19)
...
-  tenantId   String?  `@map`("tenant_id")
+  tenantId   String?  `@map`("tenant_id") `@db.VarChar`(19)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@prisma/schema.prisma` around lines 227 - 228, actorId and tenantId are
currently mapped to unbounded TEXT while Guild.id uses VARCHAR(19); change the
Prisma field definitions for actorId and tenantId to use the same fixed-length
DB type as Guild.id (e.g., String with `@db.VarChar`(19)) so index size and
semantics match; update the fields actorId and tenantId in the relevant model(s)
to use the VarChar(19) mapping and keep existing `@map` annotations intact to
preserve column names.
src/lib/database/settings/structures/AuditLogManager.ts (1)

125-133: 💤 Low value

Consider defensive handling of non-JSON-safe values.

#toJsonSafe handles bigint, arrays, and plain objects, but edge cases like Date objects, functions, or symbols would either serialize incorrectly or fail silently. For guild settings data, these edge cases are unlikely, but adding explicit guards would improve robustness.

♻️ More defensive implementation
 `#toJsonSafe`(value: unknown): unknown {
+	if (value === undefined) return null;
 	if (typeof value === 'bigint') return value.toString();
+	if (value instanceof Date) return value.toISOString();
 	if (Array.isArray(value)) return value.map((v) => this.#toJsonSafe(v));
 	if (value !== null && typeof value === 'object') {
+		if (Object.getPrototypeOf(value) !== Object.prototype) {
+			throw new TypeError(`Cannot serialize non-plain object: ${value.constructor.name}`);
+		}
 		return Object.fromEntries(Object.entries(value as Record<string, unknown>).map(([k, v]) => [k, this.#toJsonSafe(v)]));
 	}
 	return value;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/database/settings/structures/AuditLogManager.ts` around lines 125 -
133, The `#toJsonSafe` method currently only handles bigint, arrays, and plain
objects; update it to defensively handle Date (convert to ISO string), Map/Set
(convert to plain object/array), symbol (convert to string via
Symbol.prototype.toString or fallback), functions (replace with a descriptive
placeholder like "[Function]"), and undefined (convert to null), and ensure it
falls back to a safe serializable representation for any other non-plain object
types to avoid silent failures when AuditLogManager serializes guild settings;
keep the recursive structure and use Object.entries for objects and Array.from
for iterables so existing callers of `#toJsonSafe` continue to work.
prisma/migrations/20260416120000_add_dashboard_audit_log/migration.sql (1)

1-1: Migration data loss consideration.

DROP TABLE ... CASCADE destroys existing audit_log data and dependent objects. For development iterations, this is acceptable. Before production deployment, ensure appropriate data migration or archival strategy if preserving audit history is required.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@prisma/migrations/20260416120000_add_dashboard_audit_log/migration.sql` at
line 1, The migration currently issues a destructive DROP TABLE IF EXISTS
"audit_log" CASCADE which will erase all audit_log rows and dependent objects;
update the migration in migration.sql to preserve production data by replacing
the unconditional DROP with a safe upgrade path: either (a) create a new table
(or ALTER the existing one) and migrate rows from "audit_log" into it, or (b)
RENAME the existing "audit_log" to an archival table before creating the new
schema, and include an explicit data-copy/transform step and/or a backup table
creation so dependent objects are preserved; ensure all steps reference
"audit_log" and the DROP is removed or guarded for dev-only runs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/database/settings/structures/AuditLogEnvelope.ts`:
- Around line 21-27: The canonicalize function fails to return a string for
undefined (JSON.stringify(undefined) yields undefined), breaking its return
contract and array joining; update canonicalize to explicitly handle undefined
(e.g., return JSON.stringify(null) or another stable string) before the
typeof/object checks so calls to canonicalize (and Array.map + join) always
yield strings; reference the canonicalize function and ensure the undefined
branch is placed before the "typeof value !== 'object'" check.

In `@src/routes/guilds/`[guild]/audit-logs.get.ts:
- Around line 100-103: The current code builds uniqueActorIds then calls
guild.members.fetch for every id (resolvedMembers) which hits the API even for
cached members; change to a cache-first approach: for each id in uniqueActorIds
check guild.members.cache.get(id) and use serializeMember on cached ones,
collect only the ids missing from cache, call guild.members.fetch only for those
missing ids (Promise.all), then merge fetch results with cached results into the
same memberMap (keep keys as id and values from serializeMember) so you avoid
unnecessary API fetches while preserving existing memberMap construction.

In `@src/routes/guilds/`[guild]/settings.patch.ts:
- Line 49: The call to auditLog.update(request.auth!.id, before, after)
currently swallows all errors; update this to preserve async behavior but
surface failures by attaching a .catch handler that logs the error along with
the guild and user context (use request.auth!.id and the guild identifier and/or
before/after summary) instead of returning null, so failures to write audit
entries are recorded for troubleshooting while keeping the call non-blocking.

---

Nitpick comments:
In `@prisma/migrations/20260416120000_add_dashboard_audit_log/migration.sql`:
- Line 1: The migration currently issues a destructive DROP TABLE IF EXISTS
"audit_log" CASCADE which will erase all audit_log rows and dependent objects;
update the migration in migration.sql to preserve production data by replacing
the unconditional DROP with a safe upgrade path: either (a) create a new table
(or ALTER the existing one) and migrate rows from "audit_log" into it, or (b)
RENAME the existing "audit_log" to an archival table before creating the new
schema, and include an explicit data-copy/transform step and/or a backup table
creation so dependent objects are preserved; ensure all steps reference
"audit_log" and the DROP is removed or guarded for dev-only runs.

In `@prisma/schema.prisma`:
- Around line 246-252: The AuditChainHead model uses a singleton id ("default")
which serializes all tenants through one chain head; update the model to support
per-tenant chain heads by adding a tenant identifier (e.g., guildId or tenantId
String field), make the primary key include that tenant identifier (either by
replacing the single id with guildId as `@id` or by introducing a composite
@@id([guildId, id]) ), and ensure hash/updatedAt remain and map stays
@@map("audit_chain_head"); adjust any code that references AuditChainHead.id to
use the tenant-aware key (AuditChainHead.guildId/AuditChainHead.tenantId) so
advisory locks can be taken per-tenant.
- Around line 227-228: actorId and tenantId are currently mapped to unbounded
TEXT while Guild.id uses VARCHAR(19); change the Prisma field definitions for
actorId and tenantId to use the same fixed-length DB type as Guild.id (e.g.,
String with `@db.VarChar`(19)) so index size and semantics match; update the
fields actorId and tenantId in the relevant model(s) to use the VarChar(19)
mapping and keep existing `@map` annotations intact to preserve column names.

In `@src/lib/database/settings/structures/AuditLogManager.ts`:
- Around line 125-133: The `#toJsonSafe` method currently only handles bigint,
arrays, and plain objects; update it to defensively handle Date (convert to ISO
string), Map/Set (convert to plain object/array), symbol (convert to string via
Symbol.prototype.toString or fallback), functions (replace with a descriptive
placeholder like "[Function]"), and undefined (convert to null), and ensure it
falls back to a safe serializable representation for any other non-plain object
types to avoid silent failures when AuditLogManager serializes guild settings;
keep the recursive structure and use Object.entries for objects and Array.from
for iterables so existing callers of `#toJsonSafe` continue to work.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 8e1d5469-57e2-4218-900b-a36b253772b2

📥 Commits

Reviewing files that changed from the base of the PR and between 5ae1cf2 and d3ce051.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (15)
  • package.json
  • prisma/migrations/20260416120000_add_dashboard_audit_log/migration.sql
  • prisma/schema.prisma
  • src/lib/database/settings/auditActions.ts
  • src/lib/database/settings/context/SettingsContext.ts
  • src/lib/database/settings/functions.ts
  • src/lib/database/settings/index.ts
  • src/lib/database/settings/structures/AuditLogEnvelope.ts
  • src/lib/database/settings/structures/AuditLogManager.ts
  • src/lib/database/settings/types.ts
  • src/lib/types/Augments.d.ts
  • src/routes/guilds/[guild]/audit-logs.get.ts
  • src/routes/guilds/[guild]/settings.patch.ts
  • tests/lib/database/settings/structures/AuditLogEnvelope.test.ts
  • tests/lib/database/settings/structures/AuditLogManager.test.ts

Comment thread src/lib/database/settings/structures/AuditLogEnvelope.ts
Comment thread src/routes/guilds/[guild]/audit-logs.get.ts
Comment thread src/routes/guilds/[guild]/settings.patch.ts Outdated
Copy link
Copy Markdown
Contributor

Copilot AI commented May 9, 2026

@copilot resolve the merge conflicts in this pull request

Resolved in f7bf803. I merged in the current main-branch changes, fixed the package.json/pnpm-lock.yaml conflicts, and validated the result with lint, build, targeted settings-manager tests, and final review/security checks.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • checkpoint.prisma.io
    • Triggering command: /opt/hostedtoolcache/node/24.14.1/x64/bin/node /opt/hostedtoolcache/node/24.14.1/x64/bin/node /home/REDACTED/work/wolfstar/wolfstar/node_modules/.pnpm/prisma@7.8.0_@types&#43;react@19.2.14_magicast@0.5.2_react-dom@19.2.5_react@19.2.5_typescript@6.0.3/node_modules/prisma/build/child {&#34;product&#34;:&#34;prisma&#34;,&#34;version&#34;:&#34;7.8.0&#34;,&#34;cli_install_type&#34;:&#34;local&#34;,&#34;information&#34;:&#34;&#34;,&#34;local_timestamp&#34;:&#34;2026-05-09T18:58:30Z&#34;,&#34;project_hash&#34;:&#34;fc198bae&#34;,&#34;cli_path&#34;:&#34;/home/REDACTED/work/wolfstar/wolfstar/node_modules/prisma/build/index.js&#34;,&#34;cli_path_hash&#34;:&#34;62ada (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
.coderabbit.yml (1)

21-23: 💤 Low value

Verify the slop detection label value.

The label '007' is valid but unconventional for slop detection. Typically, labels such as "slop", "spam", or "low-quality" are used. Please confirm this is intentional.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.coderabbit.yml around lines 21 - 23, The slop_detection label currently
uses the unconventional value '007'; verify whether this was intentional and if
not change the slop_detection.label value to a more conventional identifier
(e.g., "slop", "spam", or "low-quality") or document why '007' is required;
update the slop_detection block (symbol: slop_detection.label) accordingly and
ensure any downstream code or rules that reference this label are adjusted to
match.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/continuous-integration.yml:
- Line 90: Ensure the workflow only upgrades to codecov/codecov-action@v6 after
verifying runner environments support Node.js 24: check your GitHub Enterprise /
self-hosted runner images for Node 24 or add a conditional that uses the current
v5 (codecov/codecov-action@v5) when Node 24 is unavailable; keep all existing
input parameters passed to the action (the same outputs/with keys) to maintain
compatibility; and for security/stability consider pinning the action to a
specific commit SHA (e.g., codecov/codecov-action@<sha>) instead of the loose v6
tag.

In `@tests/lib/database/settings/structures/PermissionNodeManager.test.ts`:
- Line 154: The test mistakenly uses createGuildMember to create a GuildMember
instead of a Role, so replace the line that creates the wrong entity with
creation of a Role (use the existing helper used elsewhere, e.g., createRole or
createGuildRole, or construct a Role for tests) so the test exercises
PermissionNodeManager.reset behaviour for a Role; update the variable name if
needed and ensure the created Role is passed into the reset/assertion calls that
currently reference role.
- Around line 119-131: The test doesn't assert that reset(user) actually threw,
so add a guard: either assert caughtError is defined before casting (e.g.,
expect(caughtError).toBeDefined()) or replace the try/catch with Vitest's
expect(() => reset(user)).toThrow() pattern; when using toThrow, assert the
thrown is an instance of UserError and that its identifier equals
LanguageKeys.Commands.Management.PermissionNodesNodeNotExists and context.target
equals user. Target symbols: reset, UserError,
LanguageKeys.Commands.Management.PermissionNodesNodeNotExists.

---

Nitpick comments:
In @.coderabbit.yml:
- Around line 21-23: The slop_detection label currently uses the unconventional
value '007'; verify whether this was intentional and if not change the
slop_detection.label value to a more conventional identifier (e.g., "slop",
"spam", or "low-quality") or document why '007' is required; update the
slop_detection block (symbol: slop_detection.label) accordingly and ensure any
downstream code or rules that reference this label are adjusted to match.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: ab87d86b-09d2-42b2-a833-6ba8c6e2590c

📥 Commits

Reviewing files that changed from the base of the PR and between d3ce051 and f7bf803.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (15)
  • .coderabbit.yml
  • .github/workflows/autofix.yml
  • .github/workflows/continuous-integration.yml
  • .github/workflows/update-tlds.yml
  • .vscode/settings.json
  • compose.dev.yaml
  • package.json
  • pnpm-workspace.yaml
  • src/lib/database/settings/index.ts
  • src/lib/moderation/workers/WorkerHandler.ts
  • tests/lib/database/settings/structures/PermissionNodeManager.test.ts
  • tests/lib/moderation/workers/WorkerHandler.test.ts
  • tests/lib/moderation/workers/WorkerManager.test.ts
  • tests/lib/util/functions/emojis/getEmojiTextFormat.test.ts
  • tsdown.config.ts
✅ Files skipped from review due to trivial changes (6)
  • .github/workflows/update-tlds.yml
  • compose.dev.yaml
  • .github/workflows/autofix.yml
  • .vscode/settings.json
  • pnpm-workspace.yaml
  • src/lib/database/settings/index.ts

Comment thread .github/workflows/continuous-integration.yml
RedStar071 added 2 commits May 9, 2026 21:07
Standalone Node ESM script that verifies the audit_event chain
without depending on a TypeScript build:
- Walks chain via prevHash links (timestamp-independent)
- Detects HASH MISMATCH, CHAIN FORK, CYCLE, ORPHAN
- Reports all rows as orphaned when no root exists
- Uses raw pg pool + inline canonicalize/hashEnvelope
- Reads DATABASE_URL from src/.env or environment
- Exits 1 on any violation, 0 on clean chain
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
scripts/audit-verify.mjs (1)

93-158: Consider memory usage for large audit tables.

The script loads all audit_event rows into memory (line 85). For guilds with extensive audit histories, this could consume significant memory. If you anticipate tables with hundreds of thousands of rows, consider streaming the verification or processing in batches.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: ce138f7d-6d4c-43f2-811b-6b516330d21f

📥 Commits

Reviewing files that changed from the base of the PR and between f7bf803 and 890248a.

📒 Files selected for processing (2)
  • package.json
  • scripts/audit-verify.mjs
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json

@RedStar071
Copy link
Copy Markdown
Member Author

@copilot apply changes based on this thread

Agent-Logs-Url: https://github.com/wolfstar-project/wolfstar/sessions/166db01e-8382-45f7-9a41-45933e67f964

Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
@RedStar071
Copy link
Copy Markdown
Member Author

@copilot resolve the merge conflicts in this pull request

Agent-Logs-Url: https://github.com/wolfstar-project/wolfstar/sessions/166db01e-8382-45f7-9a41-45933e67f964

Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented May 10, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • checkpoint.prisma.io
    • Triggering command: /opt/hostedtoolcache/node/24.14.1/x64/bin/node /opt/hostedtoolcache/node/24.14.1/x64/bin/node /home/REDACTED/work/wolfstar/wolfstar/node_modules/.pnpm/prisma@7.8.0_@types&#43;react@19.2.14_magicast@0.5.2_react-dom@19.2.5_react@19.2.5_typescript@6.0.3/node_modules/prisma/build/child {&#34;product&#34;:&#34;prisma&#34;,&#34;version&#34;:&#34;7.8.0&#34;,&#34;cli_install_type&#34;:&#34;local&#34;,&#34;information&#34;:&#34;&#34;,&#34;local_timestamp&#34;:&#34;2026-05-10T17:48:26Z&#34;,&#34;project_hash&#34;:&#34;fc198bae&#34;,&#34;cli_path&#34;:&#34;/home/REDACTED/work/wolfstar/wolfstar/node_modules/prisma/build/index.js&#34;,&#34;cli_path_hash&#34;:&#34;62ada (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Co-authored-by: RedStar071 <76824516+RedStar071@users.noreply.github.com>
- Add channelsLogsCommand and channelsLogsSettings guild settings fields
- Add guild.command.execute action to audit action allowlist
- Add AuditLogManager.command() method and channel emit fan-out
- Add buildCommandExecuteEmbed and buildSettingsChangeEmbed helpers
- Wire fan-out to chat-input, context-menu, and message command success listeners
- Add en-US locale strings for audit log embeds
@sentry
Copy link
Copy Markdown

sentry Bot commented May 16, 2026

Codecov Report

❌ Patch coverage is 82.53968% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.21%. Comparing base (dd8c536) to head (65b619e).

Files with missing lines Patch % Lines
src/lib/util/functions/auditLogEmbeds.ts 77.55% 4 Missing and 7 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #188      +/-   ##
==========================================
+ Coverage   78.08%   78.21%   +0.12%     
==========================================
  Files          81       82       +1     
  Lines        2154     2217      +63     
  Branches      211      229      +18     
==========================================
+ Hits         1682     1734      +52     
- Misses        449      453       +4     
- Partials       23       30       +7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/listeners/commands/chatInputCommandSuccessLogger.ts (1)

16-31: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Audit logging is effectively disabled when debug logging is off.

The new audit write path is inside a listener that is only enabled in debug mode (Line 29). In non-debug environments, command audit events from this listener will never be recorded.

✅ Suggested fix
 	public run({ interaction }: ChatInputCommandSuccessPayload) {
 		const shard = `[${cyan('0')}]`;
 		const commandName = cyan(`/${interaction.commandName}`);
 		const author = this.author(interaction.user);
 		const sentAt = interaction.guildId ? `${interaction.guild?.name ?? 'Unknown'}[${cyan(interaction.guildId)}]` : cyan('Direct Messages');
-		this.container.logger.debug(`${shard} - ${commandName} ${author} ${sentAt}`);
+		if (this.container.logger.has(LogLevel.Debug)) {
+			this.container.logger.debug(`${shard} - ${commandName} ${author} ${sentAt}`);
+		}
@@
 	public override onLoad() {
-		this.enabled = this.container.logger.has(LogLevel.Debug);
+		this.enabled = true;
 		return super.onLoad();
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/listeners/commands/chatInputCommandSuccessLogger.ts` around lines 16 -
31, The audit write is gated by the listener being enabled only in debug mode
via onLoad() (this.enabled = this.container.logger.has(LogLevel.Debug)), so move
the audit logging out of that debug-only gate: remove or change the onLoad
override so the listener (or at least the readSettingsAuditLog(...).command(...)
call inside the handler using readSettingsCached and readSettingsAuditLog) runs
regardless of LogLevel.Debug; alternatively extract the audit write into a
separate always-enabled function/listener that calls
readSettingsCached(interaction.guildId) and
readSettingsAuditLog(...).command(...) so audit events are recorded even when
container.logger.has(LogLevel.Debug) is false. Ensure references: onLoad,
this.enabled, container.logger.has(LogLevel.Debug), readSettingsCached,
readSettingsAuditLog, and the .command(...) call are updated accordingly.
src/listeners/commands/messageCommandSuccessLogger.ts (1)

16-31: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Message-command audit logging is tied to debug-only listener enablement.

Because onLoad() disables this listener when debug is off, the new audit write path won’t execute in non-debug deployments.

✅ Suggested fix
 	public run({ message, command }: MessageCommandSuccessPayload) {
@@
-		this.container.logger.debug(`${shard} - ${commandName} ${author} ${sentAt}`);
+		if (this.container.logger.has(LogLevel.Debug)) {
+			this.container.logger.debug(`${shard} - ${commandName} ${author} ${sentAt}`);
+		}
@@
 	public override onLoad() {
-		this.enabled = this.container.logger.has(LogLevel.Debug);
+		this.enabled = true;
 		return super.onLoad();
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/listeners/commands/messageCommandSuccessLogger.ts` around lines 16 - 31,
The listener's onLoad() currently disables the listener when LogLevel.Debug is
not present, preventing the message-command audit writes; update onLoad() in
messageCommandSuccessLogger (or remove the override) so the listener remains
enabled in non-debug deployments (e.g., set this.enabled = true or simply call
and return super.onLoad() without changing enabled) so the
readSettingsAuditLog(...) call can run regardless of logger debug level while
still calling super.onLoad().
src/listeners/commands/contextMenuCommandSuccessLogger.ts (1)

16-31: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

This listener also drops audit writes outside debug mode.

run() now performs command audit logging, but onLoad() still disables the entire listener unless debug logging is enabled. That prevents audit records in normal runtime configs.

✅ Suggested fix
 	public run({ interaction }: ContextMenuCommandSuccessPayload) {
@@
-		this.container.logger.debug(`${shard} - ${commandName} ${author} ${sentAt}`);
+		if (this.container.logger.has(LogLevel.Debug)) {
+			this.container.logger.debug(`${shard} - ${commandName} ${author} ${sentAt}`);
+		}
@@
 	public override onLoad() {
-		this.enabled = this.container.logger.has(LogLevel.Debug);
+		this.enabled = true;
 		return super.onLoad();
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/listeners/commands/contextMenuCommandSuccessLogger.ts` around lines 16 -
31, The listener's onLoad currently gates the whole listener behind
container.logger.has(LogLevel.Debug), causing run()'s audit writes
(readSettingsAuditLog / command audit) to be skipped outside debug mode; change
onLoad so the listener remains enabled (e.g. set this.enabled = true or remove
the LogLevel.Debug gating) and, if you still need debug-only behavior for
verbose logging, check container.logger.has(LogLevel.Debug) inside run() or a
separate flag rather than disabling the listener itself; update the onLoad
method accordingly so audit logging always runs while keeping any debug-only
logging conditional.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.oxlintrc.json:
- Line 139: The ignore pattern "src/languages/**" in the ignorePatterns entry is
too broad and excludes TypeScript handler files; update the ignorePatterns to
only exclude translation JSONs (e.g. replace the "src/languages/**" entry with a
narrower pattern such as "src/languages/**/*.json") so that files like index.ts
and the various Handler-extending constants files are linted; ensure you modify
the ignorePatterns array entry (the string "src/languages/**") accordingly.

In `@src/lib/util/functions/auditLogEmbeds.ts`:
- Around line 34-35: The log embed always prefixes commandName with "/" even for
non-slash commands; update the field construction in auditLogEmbeds.ts (the
object using LanguageKeys.Events.Guilds.Logs.LogFieldCommand) to only prefix
with "/" when commandType indicates a slash command (e.g., commandType ===
'slash' or whatever enum/string you use for slash commands), otherwise render
commandName as-is (no leading slash); adjust the value expression so it
conditionally formats `\`/${commandName}\`` vs ``\`${commandName}\`` depending
on commandType.

In `@tests/lib/database/settings/structures/AuditLogManager.test.ts`:
- Around line 257-263: Replace the loose "no emit" assertions that use
not.toHaveBeenCalledWith(...) with strict zero-call assertions so we assert that
emit was never called; specifically change the assertions referencing emitSpy
and Events.GuildMessageLog (the block around the test using emitSpy and
'channelsLogsCommand') to use expect(emitSpy).not.toHaveBeenCalled() and do the
same for the second occurrence noted (the other block around lines 271-277) so
the test verifies no emits happened at all.

---

Outside diff comments:
In `@src/listeners/commands/chatInputCommandSuccessLogger.ts`:
- Around line 16-31: The audit write is gated by the listener being enabled only
in debug mode via onLoad() (this.enabled =
this.container.logger.has(LogLevel.Debug)), so move the audit logging out of
that debug-only gate: remove or change the onLoad override so the listener (or
at least the readSettingsAuditLog(...).command(...) call inside the handler
using readSettingsCached and readSettingsAuditLog) runs regardless of
LogLevel.Debug; alternatively extract the audit write into a separate
always-enabled function/listener that calls
readSettingsCached(interaction.guildId) and
readSettingsAuditLog(...).command(...) so audit events are recorded even when
container.logger.has(LogLevel.Debug) is false. Ensure references: onLoad,
this.enabled, container.logger.has(LogLevel.Debug), readSettingsCached,
readSettingsAuditLog, and the .command(...) call are updated accordingly.

In `@src/listeners/commands/contextMenuCommandSuccessLogger.ts`:
- Around line 16-31: The listener's onLoad currently gates the whole listener
behind container.logger.has(LogLevel.Debug), causing run()'s audit writes
(readSettingsAuditLog / command audit) to be skipped outside debug mode; change
onLoad so the listener remains enabled (e.g. set this.enabled = true or remove
the LogLevel.Debug gating) and, if you still need debug-only behavior for
verbose logging, check container.logger.has(LogLevel.Debug) inside run() or a
separate flag rather than disabling the listener itself; update the onLoad
method accordingly so audit logging always runs while keeping any debug-only
logging conditional.

In `@src/listeners/commands/messageCommandSuccessLogger.ts`:
- Around line 16-31: The listener's onLoad() currently disables the listener
when LogLevel.Debug is not present, preventing the message-command audit writes;
update onLoad() in messageCommandSuccessLogger (or remove the override) so the
listener remains enabled in non-debug deployments (e.g., set this.enabled = true
or simply call and return super.onLoad() without changing enabled) so the
readSettingsAuditLog(...) call can run regardless of logger debug level while
still calling super.onLoad().
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: d389a42a-f179-48be-99ae-9fca0cb2e4a1

📥 Commits

Reviewing files that changed from the base of the PR and between 890248a and 42d0cb5.

📒 Files selected for processing (18)
  • .oxlintrc.json
  • prisma/migrations/20260516000000_add_channels_logs_command_settings/migration.sql
  • prisma/schema.prisma
  • src/languages/en-US/events/guilds-logs.json
  • src/lib/database/settings/auditActions.ts
  • src/lib/database/settings/constants.ts
  • src/lib/database/settings/structures/AuditLogManager.ts
  • src/lib/database/settings/types.ts
  • src/lib/i18n/languageKeys/keys/events/guilds/Logs.ts
  • src/lib/util/functions/auditLogEmbeds.ts
  • src/lib/util/functions/index.ts
  • src/listeners/commands/chatInputCommandSuccessLogger.ts
  • src/listeners/commands/contextMenuCommandSuccessLogger.ts
  • src/listeners/commands/messageCommandSuccessLogger.ts
  • tests/lib/database/settings/functions.test.ts
  • tests/lib/database/settings/structures/AuditLogManager.test.ts
  • tests/lib/database/settings/structures/PermissionNodeManager.test.ts
  • tests/lib/util/functions/auditLogEmbeds.test.ts
✅ Files skipped from review due to trivial changes (2)
  • prisma/migrations/20260516000000_add_channels_logs_command_settings/migration.sql
  • src/lib/util/functions/index.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/database/settings/auditActions.ts
  • prisma/schema.prisma

Comment thread .oxlintrc.json Outdated
Comment thread src/lib/database/settings/structures/AuditLogManager.ts
Comment thread src/lib/util/functions/auditLogEmbeds.ts Outdated
Comment thread tests/lib/database/settings/structures/AuditLogManager.test.ts Outdated
@RedStar071
Copy link
Copy Markdown
Member Author

@copilot Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.oxlintrc.json:

  • Line 139: The ignore pattern "src/languages/" in the ignorePatterns entry is
    too broad and excludes TypeScript handler files; update the ignorePatterns to
    only exclude translation JSONs (e.g. replace the "src/languages/
    " entry with a
    narrower pattern such as "src/languages//*.json") so that files like index.ts
    and the various Handler-extending constants files are linted; ensure you modify
    the ignorePatterns array entry (the string "src/languages/
    ") accordingly.

In @src/lib/util/functions/auditLogEmbeds.ts:

  • Around line 34-35: The log embed always prefixes commandName with "/" even for
    non-slash commands; update the field construction in auditLogEmbeds.ts (the
    object using LanguageKeys.Events.Guilds.Logs.LogFieldCommand) to only prefix
    with "/" when commandType indicates a slash command (e.g., commandType ===
    'slash' or whatever enum/string you use for slash commands), otherwise render
    commandName as-is (no leading slash); adjust the value expression so it
    conditionally formats \/${commandName}` vs ``\${commandName}`` depending
    on commandType.

In @tests/lib/database/settings/structures/AuditLogManager.test.ts:

  • Around line 257-263: Replace the loose "no emit" assertions that use
    not.toHaveBeenCalledWith(...) with strict zero-call assertions so we assert that
    emit was never called; specifically change the assertions referencing emitSpy
    and Events.GuildMessageLog (the block around the test using emitSpy and
    'channelsLogsCommand') to use expect(emitSpy).not.toHaveBeenCalled() and do the
    same for the second occurrence noted (the other block around lines 271-277) so
    the test verifies no emits happened at all.

Outside diff comments:
In @src/listeners/commands/chatInputCommandSuccessLogger.ts:

  • Around line 16-31: The audit write is gated by the listener being enabled only
    in debug mode via onLoad() (this.enabled =
    this.container.logger.has(LogLevel.Debug)), so move the audit logging out of
    that debug-only gate: remove or change the onLoad override so the listener (or
    at least the readSettingsAuditLog(...).command(...) call inside the handler
    using readSettingsCached and readSettingsAuditLog) runs regardless of
    LogLevel.Debug; alternatively extract the audit write into a separate
    always-enabled function/listener that calls
    readSettingsCached(interaction.guildId) and
    readSettingsAuditLog(...).command(...) so audit events are recorded even when
    container.logger.has(LogLevel.Debug) is false. Ensure references: onLoad,
    this.enabled, container.logger.has(LogLevel.Debug), readSettingsCached,
    readSettingsAuditLog, and the .command(...) call are updated accordingly.

In @src/listeners/commands/contextMenuCommandSuccessLogger.ts:

  • Around line 16-31: The listener's onLoad currently gates the whole listener
    behind container.logger.has(LogLevel.Debug), causing run()'s audit writes
    (readSettingsAuditLog / command audit) to be skipped outside debug mode; change
    onLoad so the listener remains enabled (e.g. set this.enabled = true or remove
    the LogLevel.Debug gating) and, if you still need debug-only behavior for
    verbose logging, check container.logger.has(LogLevel.Debug) inside run() or a
    separate flag rather than disabling the listener itself; update the onLoad
    method accordingly so audit logging always runs while keeping any debug-only
    logging conditional.

In @src/listeners/commands/messageCommandSuccessLogger.ts:

  • Around line 16-31: The listener's onLoad() currently disables the listener
    when LogLevel.Debug is not present, preventing the message-command audit writes;
    update onLoad() in messageCommandSuccessLogger (or remove the override) so the
    listener remains enabled in non-debug deployments (e.g., set this.enabled = true
    or simply call and return super.onLoad() without changing enabled) so the
    readSettingsAuditLog(...) call can run regardless of logger debug level while
    still calling super.onLoad().

Copy link
Copy Markdown
Contributor

Copilot AI commented May 16, 2026

@copilot Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

...

Applied in 2021cd8. I verified each finding against current code and all of them were still valid, so I fixed them with minimal changes: narrowed .oxlintrc.json to ignore only src/languages/**/*.json, made command embeds prefix / only for chat-input, tightened the two AuditLogManager no-emit assertions to not.toHaveBeenCalled(), and removed the debug-only listener enable gating from the three command-success listeners so audit writes still run outside debug mode. Validated with focused oxlint runs, pnpm vitest run tests/lib/util/functions/auditLogEmbeds.test.ts tests/lib/database/settings/structures/AuditLogManager.test.ts, pnpm build, and an extra oxlint check on src/languages/index.ts / src/languages/en-US/constants.ts. No UI changes, so there isn’t a screenshot to attach.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • checkpoint.prisma.io
    • Triggering command: /usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/wolfstar/wolfstar/node_modules/.pnpm/prisma@7.8.0_@types&#43;react@19.2.14_magicast@0.5.2_react-dom@19.2.5_react@19.2.5_typescript@6.0.3/node_modules/prisma/build/child {&#34;product&#34;:&#34;prisma&#34;,&#34;version&#34;:&#34;7.8.0&#34;,&#34;cli_install_type&#34;:&#34;local&#34;,&#34;information&#34;:&#34;&#34;,&#34;local_timestamp&#34;:&#34;2026-05-16T14:34:34Z&#34;,&#34;project_hash&#34;:&#34;fc198bae&#34;,&#34;cli_path&#34;:&#34;/home/REDACTED/work/wolfstar/wolfstar/node_modules/prisma/build/index.js&#34;,&#34;cli_path_hash&#34;:&#34;62ada (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

RedStar071 added 20 commits May 17, 2026 14:52
- AutoModerationCommand: chatInputRunEdit/Reset now use transactions
- SetUpModerationCommand: inhibit() role assignment now audited
- permissionNodes: add/remove/reset now use transactions with audit
- create-mute: rolesMuted write now audited
- add _command-log-shared.ts with writeCommandLog and normalizeCommandError helpers
- add 6 listener adapters for chat-input/message/context-menu success/error events
- add authenticated paginated GET /guilds/:guild/command-logs route
- add CommandLog model to prisma schema with migration
- add tests for shared helper (14 passing)
- fix chat-input slash prefix in formatChatInputMention fallback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants