> ## Documentation Index
> Fetch the complete documentation index at: https://docs.auction-rise.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Audit Logs

> Workspace-scoped audit trail for tracking mutations with the auditLog() helper.

# Audit Logs

The `audit_logs` table provides a tamper-evident record of mutations in your application. Each entry captures who did what, to which resource, and when.

## Schema

| Column          | Type             | Description                                             |
| --------------- | ---------------- | ------------------------------------------------------- |
| `id`            | uuid             | Primary key                                             |
| `workspace_id`  | uuid (nullable)  | Scopes the event to a workspace                         |
| `actor_id`      | uuid             | The authenticated user who performed the action         |
| `action`        | text             | Dot-namespaced action string (e.g., `member.invited`)   |
| `resource_type` | text             | What kind of resource was affected (e.g., `invitation`) |
| `resource_id`   | uuid (nullable)  | ID of the affected resource                             |
| `metadata`      | jsonb (nullable) | Extra context (role, email, old values, etc.)           |
| `ip_address`    | inet (nullable)  | Request IP (populate manually if needed)                |
| `created_at`    | timestamptz      | When the event occurred                                 |

## Recording an Event

Import `auditLog` from `@/lib/audit/log` and call it after any mutation in a server action:

```typescript theme={null}
import { auditLog } from "@/lib/audit/log";

// Inside a server action
await supabase.from("invitations").insert({ ... });

await auditLog({
  workspaceId: workspace.id,
  action: "member.invited",
  resourceType: "invitation",
  resourceId: invitation.id,
  metadata: { email: inviteeEmail, role },
});
```

The actor is captured automatically from the current auth session. The function never throws — if audit logging fails, it logs to `console.error` without breaking the calling action.

## Action Naming Convention

Use dot-namespaced strings that read as `noun.verb`:

```
workspace.created       workspace.deleted
member.invited          member.removed      member.role_changed
user.password_changed   user.deleted
subscription.created    subscription.canceled
```

## Querying Audit Logs

Use `AuditLogFilters` to query with pagination:

```typescript theme={null}
import type { AuditLogFilters } from "@/lib/audit/types";

const filters: AuditLogFilters = {
  workspaceId: "ws-123",
  action: "member.invited",
  page: 1,
  perPage: 50,
};
```

## RLS Policy

Audit logs are readable by workspace members (scoped to their workspace) and by super admins (all logs). Inserts are only allowed from authenticated sessions (actors can only log their own actions).

<Tip>
  Join `audit_logs` with `profiles` to display actor names and emails. The `AuditLogEntry` type includes optional `actor_email` and `actor_name` join fields.
</Tip>

## Adding Audit Logs to New Features

When adding a new server action that mutates data, add an `auditLog()` call as the last step:

1. Perform the mutation.
2. Check for errors and return early if needed.
3. Call `auditLog(...)` — fire and forget, no `await` needed if you don't care about the result.
