> ## Documentation Index
> Fetch the complete documentation index at: https://ayakaleaf-pro.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Project Audit Log Entries Collection

`projectAuditLogEntries` is the audit log of projects: sharing, invites, ownership transfers, downloads and admin actions. One document is one event on one project. `web` owns it; the schema is `services/web/app/src/models/ProjectAuditLogEntry.mjs`, and core writes through `services/web/app/src/Features/Project/ProjectAuditLogHandler.mjs`.

#### Fields

| Field | Type | Meaning | Source |
| - | - | - | - |
| `_id` | ObjectId | Entry id. | `ProjectAuditLogEntry.mjs:4` |
| `projectId` | ObjectId | The project the event is about. | `ProjectAuditLogEntry.mjs:6` |
| `operation` | String | What happened, a kebab-case name such as `send-invite` (see the table below). | `ProjectAuditLogEntry.mjs:8` |
| `initiatorId` | ObjectId | The user who did it, or the admin for admin actions. | `ProjectAuditLogEntry.mjs:9` |
| `ipAddress` | String | IP address of the request (`req.ip`). | `ProjectAuditLogEntry.mjs:10` |
| `timestamp` | Date | When the entry was written (default `Date.now`). | `ProjectAuditLogEntry.mjs:11` |
| `info` | Object | Details of the event; the keys depend on the operation. | `ProjectAuditLogEntry.mjs:12` |
| `managedSubscriptionId` | ObjectId | Managed group subscription of a user involved. Only found when the `saas` feature is on (`services/web/app/src/Features/Subscription/SubscriptionLocator.mjs:111-112`), so never in CE. | `ProjectAuditLogEntry.mjs:7` |
| `__v` | Number | Mongoose version key, added by `ProjectAuditLogEntry.create`. | `ProjectAuditLogHandler.mjs:103` |

#### Who Writes It

| Code | What it does |
| - | - |
| `ProjectAuditLogHandler.mjs:80-105` (`addEntry`), `:157-171` (`addEntryInBackground`) | Creates one entry (one per managed subscription involved, which only happens with `saas`). |
| `ProjectAuditLogHandler.mjs:120-150` (`addEntryIfManaged`), `:175-190` | Writes only when a managed subscription is involved. In CE that lookup always returns nothing, so these calls write no entry. |
| `services/web/modules/admin-tools/app/src/AdminAuditLog.mjs:24-32` (`logOnProject`) | Our admin panel writes admin actions with the admin as initiator. |
| `services/web/app/src/Features/Project/ProjectDeleter.mjs:392` | Deletes all entries of a project when the deleted project expires (`expireDeletedProject`, `ProjectDeleter.mjs:344`). |
| `tools/migrations/20220913125500_migrate_auditLog_to_collections.mjs` | One-time migration: moved the old `projects.auditLog` arrays into this collection. |

Operations written by core with `addEntry` or `addEntryInBackground`:

| `operation` | Written at (`services/web/app/src/Features/...`) |
| - | - |
| `send-invite`, `revoke-invite`, `resend-invite`, `accept-invite` | `Collaborators/CollaboratorsInviteController.mjs:198`, `:237`, `:293`, `:538` |
| `sharing-link-created`, `sharing-link-updated` | `Collaborators/CollaboratorsInviteController.mjs:698`, `:713` |
| `editor-moved-to-pending` | `Collaborators/CollaboratorsInviteHandler.mjs:183` |
| `remove-collaborator`, `leave-project` | `Collaborators/CollaboratorsController.mjs:67`, `:98` |
| `project-role-changed` | `Collaborators/CollaboratorsHandler.mjs:396` |
| `transfer-ownership` | `Collaborators/OwnershipTransferHandler.mjs:122` |
| `toggle-access-level` | `Project/ProjectController.mjs:268` |
| `accept-via-link-sharing` | `TokenAccess/TokenAccessController.mjs:366`, `:594` |
| `join-via-token`, `readonly-via-sharing-updates` | `TokenAccess/TokenAccessController.mjs:477`, `:660` |
| `project-downloaded` | `Downloads/ProjectDownloadsController.mjs:220`, `:276` |
| `project-exported-<type>` (for example `project-exported-docx`) | `Downloads/ProjectDownloadsController.mjs:153-158` |

Operations written by our modules (`services/web/modules/...`):

| `operation` | Written at |
| - | - |
| `integration-repo-linked`, `integration-repo-unlinked` | `github-sync/app/src/GitHubSyncController.mjs:94`, `:201`, `:244`; `gitlab-sync/app/src/GitLabSyncController.mjs:94`, `:213`, `:256`; `gitea-sync/app/src/GiteaSyncController.mjs:94`, `:213`, `:256` |
| `publish-template` | `template-gallery/app/src/TemplateGalleryController.mjs:53` |
| `restore-deleted-doc`, `project-deleted`, `project-restored` | `admin-tools/app/src/AdminProjectManager.mjs:477`, `:492`, `:513`; `admin-tools/app/src/AdminUserManager.mjs:688` (`project-restored`) |

Core also calls `addEntryIfManaged` for `project-created`, `project-deleted`, `project-archived`, `project-unarchived`, `project-trashed`, `project-untrashed`, `project-restored`, `project-cloned` (`Project/ProjectController.mjs:292-479`) and `project-history-version-restored`, `project-history-version-downloaded` (`History/HistoryController.mjs:334`, `:396`, `:454`, `:711`). These write nothing in CE; the `project-deleted` and `project-restored` entries in a CE database come from the admin panel.

#### Who Reads It

| Code | What it does |
| - | - |
| `services/web/modules/admin-tools/app/src/AdminAuditLog.mjs:128-130` (`listProjectEntries`) | Our admin panel's project audit log, `GET /admin/project/:projectId/audit-log/list` (`services/web/modules/admin-tools/app/src/AdminToolsRouter.mjs:120-124`). |

Core CE has no page that shows this log.

#### Indexes

| Name | Keys | Options | Migration |
| - | - | - | - |
| `timestamp_1` | `{ timestamp: 1 }` | TTL, `expireAfterSeconds: 78840000` (2.5 years) | `tools/migrations/20220913105500_create_auditLog_indexes.mjs` |
| `projectId_1_timestamp_-1` | `{ projectId: 1, timestamp: -1 }` | | `tools/migrations/20250912102601_add_timestamp_to_projectAuditLogEntries_index.mjs` |

`tools/migrations/20220929193200_add_auditLog_indexes.mjs` first created `project_id_1` on `{ projectId: 1 }`; `20250912102601` replaces it with the compound index. The schema's `index: true` marks are not applied, as Mongoose auto-indexing is off (`services/web/app/src/infrastructure/Mongoose.mjs:7`). The `managedSubscriptionId` index migration is tagged `saas` only.

#### Notes

* Entries expire 2.5 years after `timestamp` through the TTL index, and all entries of a project go when its deleted-project record expires.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.