feat: implement envelope operation logging with cursor pagination - #764

Merged
coodos merged 4 commits into
mainfrom
feat/logs-endpoint
Feb 4, 2026
Merged

feat: implement envelope operation logging with cursor pagination#764
coodos merged 4 commits into
mainfrom
feat/logs-endpoint

Conversation

@coodos

@coodoscoodos commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Description of change

Issue Number

Type of change

  • New (a change which implements a new feature)

How the change has been tested

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

  • New Features

    • Envelope operations (create, update, delete, value updates) are logged with operation, platform, timestamp, ontology and envelope hash; logs can be appended and queried with cursor-based pagination via a new /logs HTTP endpoint.
  • Chores

    • One-time index creation and backfill steps added to initialization to populate and index operation logs.
  • Documentation

    • API docs updated with /logs endpoint, parameters and examples.
  • Tests

    • Integration and end-to-end tests covering logging, pagination and header validation.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds envelope operation logging: new DB types, DbService methods for appending and paginating logs, a /logs HTTP endpoint, GraphQL mutation hooks to emit logs (best-effort), migrations (index + backfill) run at startup/tests, and unit + e2e tests for storage and retrieval.

Changes

Cohort / File(s)Summary
Type Definitions
infrastructure/evault-core/src/core/db/types.ts
Add types for operation logs: EnvelopeOperationType, EnvelopeOperationLogEntry, AppendEnvelopeOperationLogParams, GetEnvelopeOperationLogsResult.
Database Service & Tests
infrastructure/evault-core/src/core/db/db.service.ts, infrastructure/evault-core/src/core/db/db.service.spec.ts
Add methods getMetaEnvelopeIdByEnvelopeId, appendEnvelopeOperationLog, getEnvelopeOperationLogs (cursor-based pagination, limit bounds); tests for storing, pagination, and meta-envelope mapping.
Hashing & Ontology Helpers
infrastructure/evault-core/src/core/db/envelope-hash.ts, infrastructure/evault-core/src/core/db/ontology-platform.ts, .../ontology-platform.spec.ts
Add deterministic envelope hash utilities and ontology→platform inference used by backfill; unit tests for inference.
Migrations / Backfill
infrastructure/evault-core/src/core/db/migrations/add-envelope-operation-log-index.ts, infrastructure/evault-core/src/core/db/migrations/backfill-envelope-operation-logs.ts
Add migration to create EnvelopeOperationLog indexes and a backfill script to create initial log entries from existing MetaEnvelope nodes; marker node to avoid rerun.
HTTP Server & Docs
infrastructure/evault-core/src/core/http/server.ts, docs/docs/Infrastructure/eVault.md
New GET /logs endpoint requiring X-ENAME, supports limit and cursor, returns { logs, nextCursor, hasMore }; Swagger/docs updated.
GraphQL Instrumentation
infrastructure/evault-core/src/protocol/graphql-server.ts
Fire-and-forget logging after create/update/delete/update_envelope_value mutations: compute envelopeHash, look up meta info when needed, call appendEnvelopeOperationLog (errors caught and logged).
Startup & Test Setup
infrastructure/evault-core/src/index.ts, infrastructure/evault-core/src/test-utils/e2e-setup.ts
Run index-creation and backfill modules during initialization and E2E setup via dynamic imports; wrapped in try/catch with warnings.
E2E Tests
infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Add E2E tests for GET /logs (success after storing meta-envelope; 400 when X-ENAME missing).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQL as GraphQL Server
participant HTTP as HTTP Server
participant DbService
participant DB as Neo4j
Client->>GraphQL: mutation (create/update/delete/update_envelope_value)
GraphQL->>DB: persist envelope change
GraphQL->>GraphQL: compute envelopeHash / lookup metaEnvelopeId & ontology
GraphQL->>DbService: appendEnvelopeOperationLog(params) (fire-and-forget)
DbService->>DB: CREATE EnvelopeOperationLog node
Client->>HTTP: GET /logs (X-ENAME, limit, cursor)
HTTP->>DbService: getEnvelopeOperationLogs(eName, {limit, cursor})
DbService->>DB: MATCH logs ORDER BY timestamp DESC, id ASC WITH cursor filter
DB-->>DbService: paginated records
DbService-->>HTTP: { logs, nextCursor, hasMore }
HTTP-->>Client: 200 { logs, nextCursor, hasMore }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • sosweetham
  • xPathin
  • dkraemerwork

Poem

🐰 I hop through logs with a tiny pen,
I hash the envelopes and write them when,
Cursors curl like carrot vines,
Paging through timestamps in neat lines. 🥕📜

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check nameStatusExplanationResolution
Description check⚠️ WarningThe PR description follows the template structure but lacks critical implementation details; it contains no issue number, no explanation of the feature being added, and no description of how testing was performed.Complete the PR description with the linked issue number, a detailed explanation of the envelope operation logs feature, and specific testing approach or scenarios covered.
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the main feature added: envelope operation logging with cursor pagination.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/logs-endpoint

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 978-1007: The cursor comparison in the cypher used by
runQueryInternal for EnvelopeOperationLog is inconsistent with the ORDER BY
clause: with "ORDER BY l.timestamp DESC, l.id ASC" the cursor predicate
"(l.timestamp < $cursorTs) OR (l.timestamp = $cursorTs AND l.id < $cursorId)" is
wrong and should use l.id > $cursorId for correct pagination; update the query
string to use "l.id > $cursorId" in the cursor branch (and keep the same
parameter names cursorTs/cursorId and limitPlusOne) so results for equal
timestamps are correctly ordered and no items are skipped or duplicated.
In `@infrastructure/evault-core/src/core/protocol/graphql-server.ts`:
- Around line 7-10: The import of computeEnvelopeHash and
computeEnvelopeHashForDelete in graphql-server.ts fails because
../db/envelope-hash does not exist or exports differ; either restore/create the
module exporting those two functions or correct the import to the actual module
that provides them (e.g., update the path or named exports to match where
computeEnvelopeHash and computeEnvelopeHashForDelete are defined), then run the
build to verify the import resolves.
- Around line 244-260: The post-write call to appendEnvelopeOperationLog (which
uses computeEnvelopeHash and result.metaEnvelope.id) must not cause the mutation
to fail if logging errors; change the logic so the main write completes
atomically and the log is recorded best-effort—either include the envelope log
in the same DB transaction as the write (so both commit or both rollback) or, if
a transaction is not feasible, invoke appendEnvelopeOperationLog without
blocking the response and wrap it in a try/catch (or attach .catch) to
swallow/log errors; update the code paths that call appendEnvelopeOperationLog
(e.g., in the create mutation where result.metaEnvelope is used) so failures in
appendEnvelopeOperationLog never bubble up and cause duplicate side effects.
- Around line 349-363: The audit log is being appended before the actual
deletion, and meta may be null; move logging to occur only after confirming
deletion succeeds (or perform both actions inside a DB transaction).
Specifically: call findMetaEnvelopeById(id, context.eName) to capture ontology
first, then call deleteMetaEnvelope(id, context.eName) and verify its
success/return value, and only then call appendEnvelopeOperationLog with
computeEnvelopeHashForDelete(id), platform, timestamp and ontology (use
null/explicit fallback if meta is missing). Alternatively wrap
deleteMetaEnvelope and appendEnvelopeOperationLog in a transaction to ensure
atomicity.
- Around line 379-405: Create the missing module ../db/envelope-hash that
exports computeEnvelopeHash and computeEnvelopeHashForDelete, implement
deterministic hashing of the provided envelope inputs (e.g., ontology and
payload) and ensure the functions are used where computeEnvelopeHash is called
in graphql-server.ts; specifically, make computeEnvelopeHash include an id field
in the payload for the "update_envelope_value" operation (use the envelopeId
parameter as id) so its inputs match the create/update hash shape, and implement
computeEnvelopeHashForDelete to accept the same identifying fields used when
deleting; ensure exports match the named imports used by graphql-server.ts.
In `@infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts`:
- Around line 600-630: The test uses the variable client inside the "GET /logs
endpoint" block but never initializes it; add a beforeAll (and matching afterAll
if needed) in that describe block to set up client the same way other suites do
(e.g., call whatever setup used elsewhere to assign client and ensure evault1 is
available), so that client.storeMetaEnvelope and subsequent fetch calls run
against a valid client instance; reference the describe block name "GET /logs
endpoint", the variable client, and the method storeMetaEnvelope to locate where
to add the beforeAll/afterAll setup and teardown.
In `@infrastructure/evault-core/src/index.ts`:
- Around line 120-126: The dynamic import/usage of backfillEnvelopeOperationLogs
in index.ts is referencing a missing migration module and will fail at runtime;
either add an exported async function backfillEnvelopeOperationLogs that accepts
the existing driver and performs the backfill, and place it where the dynamic
import in index.ts expects to load it, or remove the try/catch block and call
entirely (including the import and await backfillEnvelopeOperationLogs(driver))
if the migration isn’t needed yet—ensure the symbol name
backfillEnvelopeOperationLogs and the driver argument remain consistent with the
current code when you implement or remove the call.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Comment threadinfrastructure/evault-core/src/index.ts
@coodoscoodos changed the title feat: logseat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodoscoodos changed the title eat: implement envelope operation logging with cursor paginationfeat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodos
coodos merged commit 570a770 into mainFeb 4, 2026
5 of 6 checks passed
@coodos
coodos deleted the feat/logs-endpoint branch February 4, 2026 08:11
This was referenced Feb 4, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

2 participants

@coodos@sosweetham
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: implement envelope operation logging with cursor pagination - #764

Merged
coodos merged 4 commits into
mainfrom
feat/logs-endpoint
Feb 4, 2026
Merged

feat: implement envelope operation logging with cursor pagination#764
coodos merged 4 commits into
mainfrom
feat/logs-endpoint

Conversation

@coodos

@coodoscoodos commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Description of change

Issue Number

Type of change

  • New (a change which implements a new feature)

How the change has been tested

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

  • New Features

    • Envelope operations (create, update, delete, value updates) are logged with operation, platform, timestamp, ontology and envelope hash; logs can be appended and queried with cursor-based pagination via a new /logs HTTP endpoint.
  • Chores

    • One-time index creation and backfill steps added to initialization to populate and index operation logs.
  • Documentation

    • API docs updated with /logs endpoint, parameters and examples.
  • Tests

    • Integration and end-to-end tests covering logging, pagination and header validation.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds envelope operation logging: new DB types, DbService methods for appending and paginating logs, a /logs HTTP endpoint, GraphQL mutation hooks to emit logs (best-effort), migrations (index + backfill) run at startup/tests, and unit + e2e tests for storage and retrieval.

Changes

Cohort / File(s)Summary
Type Definitions
infrastructure/evault-core/src/core/db/types.ts
Add types for operation logs: EnvelopeOperationType, EnvelopeOperationLogEntry, AppendEnvelopeOperationLogParams, GetEnvelopeOperationLogsResult.
Database Service & Tests
infrastructure/evault-core/src/core/db/db.service.ts, infrastructure/evault-core/src/core/db/db.service.spec.ts
Add methods getMetaEnvelopeIdByEnvelopeId, appendEnvelopeOperationLog, getEnvelopeOperationLogs (cursor-based pagination, limit bounds); tests for storing, pagination, and meta-envelope mapping.
Hashing & Ontology Helpers
infrastructure/evault-core/src/core/db/envelope-hash.ts, infrastructure/evault-core/src/core/db/ontology-platform.ts, .../ontology-platform.spec.ts
Add deterministic envelope hash utilities and ontology→platform inference used by backfill; unit tests for inference.
Migrations / Backfill
infrastructure/evault-core/src/core/db/migrations/add-envelope-operation-log-index.ts, infrastructure/evault-core/src/core/db/migrations/backfill-envelope-operation-logs.ts
Add migration to create EnvelopeOperationLog indexes and a backfill script to create initial log entries from existing MetaEnvelope nodes; marker node to avoid rerun.
HTTP Server & Docs
infrastructure/evault-core/src/core/http/server.ts, docs/docs/Infrastructure/eVault.md
New GET /logs endpoint requiring X-ENAME, supports limit and cursor, returns { logs, nextCursor, hasMore }; Swagger/docs updated.
GraphQL Instrumentation
infrastructure/evault-core/src/protocol/graphql-server.ts
Fire-and-forget logging after create/update/delete/update_envelope_value mutations: compute envelopeHash, look up meta info when needed, call appendEnvelopeOperationLog (errors caught and logged).
Startup & Test Setup
infrastructure/evault-core/src/index.ts, infrastructure/evault-core/src/test-utils/e2e-setup.ts
Run index-creation and backfill modules during initialization and E2E setup via dynamic imports; wrapped in try/catch with warnings.
E2E Tests
infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Add E2E tests for GET /logs (success after storing meta-envelope; 400 when X-ENAME missing).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQL as GraphQL Server
participant HTTP as HTTP Server
participant DbService
participant DB as Neo4j
Client->>GraphQL: mutation (create/update/delete/update_envelope_value)
GraphQL->>DB: persist envelope change
GraphQL->>GraphQL: compute envelopeHash / lookup metaEnvelopeId & ontology
GraphQL->>DbService: appendEnvelopeOperationLog(params) (fire-and-forget)
DbService->>DB: CREATE EnvelopeOperationLog node
Client->>HTTP: GET /logs (X-ENAME, limit, cursor)
HTTP->>DbService: getEnvelopeOperationLogs(eName, {limit, cursor})
DbService->>DB: MATCH logs ORDER BY timestamp DESC, id ASC WITH cursor filter
DB-->>DbService: paginated records
DbService-->>HTTP: { logs, nextCursor, hasMore }
HTTP-->>Client: 200 { logs, nextCursor, hasMore }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • sosweetham
  • xPathin
  • dkraemerwork

Poem

🐰 I hop through logs with a tiny pen,
I hash the envelopes and write them when,
Cursors curl like carrot vines,
Paging through timestamps in neat lines. 🥕📜

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check nameStatusExplanationResolution
Description check⚠️ WarningThe PR description follows the template structure but lacks critical implementation details; it contains no issue number, no explanation of the feature being added, and no description of how testing was performed.Complete the PR description with the linked issue number, a detailed explanation of the envelope operation logs feature, and specific testing approach or scenarios covered.
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the main feature added: envelope operation logging with cursor pagination.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/logs-endpoint

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 978-1007: The cursor comparison in the cypher used by
runQueryInternal for EnvelopeOperationLog is inconsistent with the ORDER BY
clause: with "ORDER BY l.timestamp DESC, l.id ASC" the cursor predicate
"(l.timestamp < $cursorTs) OR (l.timestamp = $cursorTs AND l.id < $cursorId)" is
wrong and should use l.id > $cursorId for correct pagination; update the query
string to use "l.id > $cursorId" in the cursor branch (and keep the same
parameter names cursorTs/cursorId and limitPlusOne) so results for equal
timestamps are correctly ordered and no items are skipped or duplicated.
In `@infrastructure/evault-core/src/core/protocol/graphql-server.ts`:
- Around line 7-10: The import of computeEnvelopeHash and
computeEnvelopeHashForDelete in graphql-server.ts fails because
../db/envelope-hash does not exist or exports differ; either restore/create the
module exporting those two functions or correct the import to the actual module
that provides them (e.g., update the path or named exports to match where
computeEnvelopeHash and computeEnvelopeHashForDelete are defined), then run the
build to verify the import resolves.
- Around line 244-260: The post-write call to appendEnvelopeOperationLog (which
uses computeEnvelopeHash and result.metaEnvelope.id) must not cause the mutation
to fail if logging errors; change the logic so the main write completes
atomically and the log is recorded best-effort—either include the envelope log
in the same DB transaction as the write (so both commit or both rollback) or, if
a transaction is not feasible, invoke appendEnvelopeOperationLog without
blocking the response and wrap it in a try/catch (or attach .catch) to
swallow/log errors; update the code paths that call appendEnvelopeOperationLog
(e.g., in the create mutation where result.metaEnvelope is used) so failures in
appendEnvelopeOperationLog never bubble up and cause duplicate side effects.
- Around line 349-363: The audit log is being appended before the actual
deletion, and meta may be null; move logging to occur only after confirming
deletion succeeds (or perform both actions inside a DB transaction).
Specifically: call findMetaEnvelopeById(id, context.eName) to capture ontology
first, then call deleteMetaEnvelope(id, context.eName) and verify its
success/return value, and only then call appendEnvelopeOperationLog with
computeEnvelopeHashForDelete(id), platform, timestamp and ontology (use
null/explicit fallback if meta is missing). Alternatively wrap
deleteMetaEnvelope and appendEnvelopeOperationLog in a transaction to ensure
atomicity.
- Around line 379-405: Create the missing module ../db/envelope-hash that
exports computeEnvelopeHash and computeEnvelopeHashForDelete, implement
deterministic hashing of the provided envelope inputs (e.g., ontology and
payload) and ensure the functions are used where computeEnvelopeHash is called
in graphql-server.ts; specifically, make computeEnvelopeHash include an id field
in the payload for the "update_envelope_value" operation (use the envelopeId
parameter as id) so its inputs match the create/update hash shape, and implement
computeEnvelopeHashForDelete to accept the same identifying fields used when
deleting; ensure exports match the named imports used by graphql-server.ts.
In `@infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts`:
- Around line 600-630: The test uses the variable client inside the "GET /logs
endpoint" block but never initializes it; add a beforeAll (and matching afterAll
if needed) in that describe block to set up client the same way other suites do
(e.g., call whatever setup used elsewhere to assign client and ensure evault1 is
available), so that client.storeMetaEnvelope and subsequent fetch calls run
against a valid client instance; reference the describe block name "GET /logs
endpoint", the variable client, and the method storeMetaEnvelope to locate where
to add the beforeAll/afterAll setup and teardown.
In `@infrastructure/evault-core/src/index.ts`:
- Around line 120-126: The dynamic import/usage of backfillEnvelopeOperationLogs
in index.ts is referencing a missing migration module and will fail at runtime;
either add an exported async function backfillEnvelopeOperationLogs that accepts
the existing driver and performs the backfill, and place it where the dynamic
import in index.ts expects to load it, or remove the try/catch block and call
entirely (including the import and await backfillEnvelopeOperationLogs(driver))
if the migration isn’t needed yet—ensure the symbol name
backfillEnvelopeOperationLogs and the driver argument remain consistent with the
current code when you implement or remove the call.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Comment threadinfrastructure/evault-core/src/index.ts
@coodoscoodos changed the title feat: logseat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodoscoodos changed the title eat: implement envelope operation logging with cursor paginationfeat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodos
coodos merged commit 570a770 into mainFeb 4, 2026
5 of 6 checks passed
@coodos
coodos deleted the feat/logs-endpoint branch February 4, 2026 08:11
This was referenced Feb 4, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

2 participants

@coodos@sosweetham
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: implement envelope operation logging with cursor pagination - #764

Merged
coodos merged 4 commits into
mainfrom
feat/logs-endpoint
Feb 4, 2026
Merged

feat: implement envelope operation logging with cursor pagination#764
coodos merged 4 commits into
mainfrom
feat/logs-endpoint

Conversation

@coodos

@coodoscoodos commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Description of change

Issue Number

Type of change

  • New (a change which implements a new feature)

How the change has been tested

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

  • New Features

    • Envelope operations (create, update, delete, value updates) are logged with operation, platform, timestamp, ontology and envelope hash; logs can be appended and queried with cursor-based pagination via a new /logs HTTP endpoint.
  • Chores

    • One-time index creation and backfill steps added to initialization to populate and index operation logs.
  • Documentation

    • API docs updated with /logs endpoint, parameters and examples.
  • Tests

    • Integration and end-to-end tests covering logging, pagination and header validation.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds envelope operation logging: new DB types, DbService methods for appending and paginating logs, a /logs HTTP endpoint, GraphQL mutation hooks to emit logs (best-effort), migrations (index + backfill) run at startup/tests, and unit + e2e tests for storage and retrieval.

Changes

Cohort / File(s)Summary
Type Definitions
infrastructure/evault-core/src/core/db/types.ts
Add types for operation logs: EnvelopeOperationType, EnvelopeOperationLogEntry, AppendEnvelopeOperationLogParams, GetEnvelopeOperationLogsResult.
Database Service & Tests
infrastructure/evault-core/src/core/db/db.service.ts, infrastructure/evault-core/src/core/db/db.service.spec.ts
Add methods getMetaEnvelopeIdByEnvelopeId, appendEnvelopeOperationLog, getEnvelopeOperationLogs (cursor-based pagination, limit bounds); tests for storing, pagination, and meta-envelope mapping.
Hashing & Ontology Helpers
infrastructure/evault-core/src/core/db/envelope-hash.ts, infrastructure/evault-core/src/core/db/ontology-platform.ts, .../ontology-platform.spec.ts
Add deterministic envelope hash utilities and ontology→platform inference used by backfill; unit tests for inference.
Migrations / Backfill
infrastructure/evault-core/src/core/db/migrations/add-envelope-operation-log-index.ts, infrastructure/evault-core/src/core/db/migrations/backfill-envelope-operation-logs.ts
Add migration to create EnvelopeOperationLog indexes and a backfill script to create initial log entries from existing MetaEnvelope nodes; marker node to avoid rerun.
HTTP Server & Docs
infrastructure/evault-core/src/core/http/server.ts, docs/docs/Infrastructure/eVault.md
New GET /logs endpoint requiring X-ENAME, supports limit and cursor, returns { logs, nextCursor, hasMore }; Swagger/docs updated.
GraphQL Instrumentation
infrastructure/evault-core/src/protocol/graphql-server.ts
Fire-and-forget logging after create/update/delete/update_envelope_value mutations: compute envelopeHash, look up meta info when needed, call appendEnvelopeOperationLog (errors caught and logged).
Startup & Test Setup
infrastructure/evault-core/src/index.ts, infrastructure/evault-core/src/test-utils/e2e-setup.ts
Run index-creation and backfill modules during initialization and E2E setup via dynamic imports; wrapped in try/catch with warnings.
E2E Tests
infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Add E2E tests for GET /logs (success after storing meta-envelope; 400 when X-ENAME missing).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQL as GraphQL Server
participant HTTP as HTTP Server
participant DbService
participant DB as Neo4j
Client->>GraphQL: mutation (create/update/delete/update_envelope_value)
GraphQL->>DB: persist envelope change
GraphQL->>GraphQL: compute envelopeHash / lookup metaEnvelopeId & ontology
GraphQL->>DbService: appendEnvelopeOperationLog(params) (fire-and-forget)
DbService->>DB: CREATE EnvelopeOperationLog node
Client->>HTTP: GET /logs (X-ENAME, limit, cursor)
HTTP->>DbService: getEnvelopeOperationLogs(eName, {limit, cursor})
DbService->>DB: MATCH logs ORDER BY timestamp DESC, id ASC WITH cursor filter
DB-->>DbService: paginated records
DbService-->>HTTP: { logs, nextCursor, hasMore }
HTTP-->>Client: 200 { logs, nextCursor, hasMore }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • sosweetham
  • xPathin
  • dkraemerwork

Poem

🐰 I hop through logs with a tiny pen,
I hash the envelopes and write them when,
Cursors curl like carrot vines,
Paging through timestamps in neat lines. 🥕📜

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check nameStatusExplanationResolution
Description check⚠️ WarningThe PR description follows the template structure but lacks critical implementation details; it contains no issue number, no explanation of the feature being added, and no description of how testing was performed.Complete the PR description with the linked issue number, a detailed explanation of the envelope operation logs feature, and specific testing approach or scenarios covered.
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the main feature added: envelope operation logging with cursor pagination.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/logs-endpoint

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 978-1007: The cursor comparison in the cypher used by
runQueryInternal for EnvelopeOperationLog is inconsistent with the ORDER BY
clause: with "ORDER BY l.timestamp DESC, l.id ASC" the cursor predicate
"(l.timestamp < $cursorTs) OR (l.timestamp = $cursorTs AND l.id < $cursorId)" is
wrong and should use l.id > $cursorId for correct pagination; update the query
string to use "l.id > $cursorId" in the cursor branch (and keep the same
parameter names cursorTs/cursorId and limitPlusOne) so results for equal
timestamps are correctly ordered and no items are skipped or duplicated.
In `@infrastructure/evault-core/src/core/protocol/graphql-server.ts`:
- Around line 7-10: The import of computeEnvelopeHash and
computeEnvelopeHashForDelete in graphql-server.ts fails because
../db/envelope-hash does not exist or exports differ; either restore/create the
module exporting those two functions or correct the import to the actual module
that provides them (e.g., update the path or named exports to match where
computeEnvelopeHash and computeEnvelopeHashForDelete are defined), then run the
build to verify the import resolves.
- Around line 244-260: The post-write call to appendEnvelopeOperationLog (which
uses computeEnvelopeHash and result.metaEnvelope.id) must not cause the mutation
to fail if logging errors; change the logic so the main write completes
atomically and the log is recorded best-effort—either include the envelope log
in the same DB transaction as the write (so both commit or both rollback) or, if
a transaction is not feasible, invoke appendEnvelopeOperationLog without
blocking the response and wrap it in a try/catch (or attach .catch) to
swallow/log errors; update the code paths that call appendEnvelopeOperationLog
(e.g., in the create mutation where result.metaEnvelope is used) so failures in
appendEnvelopeOperationLog never bubble up and cause duplicate side effects.
- Around line 349-363: The audit log is being appended before the actual
deletion, and meta may be null; move logging to occur only after confirming
deletion succeeds (or perform both actions inside a DB transaction).
Specifically: call findMetaEnvelopeById(id, context.eName) to capture ontology
first, then call deleteMetaEnvelope(id, context.eName) and verify its
success/return value, and only then call appendEnvelopeOperationLog with
computeEnvelopeHashForDelete(id), platform, timestamp and ontology (use
null/explicit fallback if meta is missing). Alternatively wrap
deleteMetaEnvelope and appendEnvelopeOperationLog in a transaction to ensure
atomicity.
- Around line 379-405: Create the missing module ../db/envelope-hash that
exports computeEnvelopeHash and computeEnvelopeHashForDelete, implement
deterministic hashing of the provided envelope inputs (e.g., ontology and
payload) and ensure the functions are used where computeEnvelopeHash is called
in graphql-server.ts; specifically, make computeEnvelopeHash include an id field
in the payload for the "update_envelope_value" operation (use the envelopeId
parameter as id) so its inputs match the create/update hash shape, and implement
computeEnvelopeHashForDelete to accept the same identifying fields used when
deleting; ensure exports match the named imports used by graphql-server.ts.
In `@infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts`:
- Around line 600-630: The test uses the variable client inside the "GET /logs
endpoint" block but never initializes it; add a beforeAll (and matching afterAll
if needed) in that describe block to set up client the same way other suites do
(e.g., call whatever setup used elsewhere to assign client and ensure evault1 is
available), so that client.storeMetaEnvelope and subsequent fetch calls run
against a valid client instance; reference the describe block name "GET /logs
endpoint", the variable client, and the method storeMetaEnvelope to locate where
to add the beforeAll/afterAll setup and teardown.
In `@infrastructure/evault-core/src/index.ts`:
- Around line 120-126: The dynamic import/usage of backfillEnvelopeOperationLogs
in index.ts is referencing a missing migration module and will fail at runtime;
either add an exported async function backfillEnvelopeOperationLogs that accepts
the existing driver and performs the backfill, and place it where the dynamic
import in index.ts expects to load it, or remove the try/catch block and call
entirely (including the import and await backfillEnvelopeOperationLogs(driver))
if the migration isn’t needed yet—ensure the symbol name
backfillEnvelopeOperationLogs and the driver argument remain consistent with the
current code when you implement or remove the call.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Comment threadinfrastructure/evault-core/src/index.ts
@coodoscoodos changed the title feat: logseat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodoscoodos changed the title eat: implement envelope operation logging with cursor paginationfeat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodos
coodos merged commit 570a770 into mainFeb 4, 2026
5 of 6 checks passed
@coodos
coodos deleted the feat/logs-endpoint branch February 4, 2026 08:11
This was referenced Feb 4, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

2 participants

@coodos@sosweetham
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: implement envelope operation logging with cursor pagination - #764

Merged
coodos merged 4 commits into
mainfrom
feat/logs-endpoint
Feb 4, 2026
Merged

feat: implement envelope operation logging with cursor pagination#764
coodos merged 4 commits into
mainfrom
feat/logs-endpoint

Conversation

@coodos

@coodoscoodos commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Description of change

Issue Number

Type of change

  • New (a change which implements a new feature)

How the change has been tested

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

  • New Features

    • Envelope operations (create, update, delete, value updates) are logged with operation, platform, timestamp, ontology and envelope hash; logs can be appended and queried with cursor-based pagination via a new /logs HTTP endpoint.
  • Chores

    • One-time index creation and backfill steps added to initialization to populate and index operation logs.
  • Documentation

    • API docs updated with /logs endpoint, parameters and examples.
  • Tests

    • Integration and end-to-end tests covering logging, pagination and header validation.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds envelope operation logging: new DB types, DbService methods for appending and paginating logs, a /logs HTTP endpoint, GraphQL mutation hooks to emit logs (best-effort), migrations (index + backfill) run at startup/tests, and unit + e2e tests for storage and retrieval.

Changes

Cohort / File(s)Summary
Type Definitions
infrastructure/evault-core/src/core/db/types.ts
Add types for operation logs: EnvelopeOperationType, EnvelopeOperationLogEntry, AppendEnvelopeOperationLogParams, GetEnvelopeOperationLogsResult.
Database Service & Tests
infrastructure/evault-core/src/core/db/db.service.ts, infrastructure/evault-core/src/core/db/db.service.spec.ts
Add methods getMetaEnvelopeIdByEnvelopeId, appendEnvelopeOperationLog, getEnvelopeOperationLogs (cursor-based pagination, limit bounds); tests for storing, pagination, and meta-envelope mapping.
Hashing & Ontology Helpers
infrastructure/evault-core/src/core/db/envelope-hash.ts, infrastructure/evault-core/src/core/db/ontology-platform.ts, .../ontology-platform.spec.ts
Add deterministic envelope hash utilities and ontology→platform inference used by backfill; unit tests for inference.
Migrations / Backfill
infrastructure/evault-core/src/core/db/migrations/add-envelope-operation-log-index.ts, infrastructure/evault-core/src/core/db/migrations/backfill-envelope-operation-logs.ts
Add migration to create EnvelopeOperationLog indexes and a backfill script to create initial log entries from existing MetaEnvelope nodes; marker node to avoid rerun.
HTTP Server & Docs
infrastructure/evault-core/src/core/http/server.ts, docs/docs/Infrastructure/eVault.md
New GET /logs endpoint requiring X-ENAME, supports limit and cursor, returns { logs, nextCursor, hasMore }; Swagger/docs updated.
GraphQL Instrumentation
infrastructure/evault-core/src/protocol/graphql-server.ts
Fire-and-forget logging after create/update/delete/update_envelope_value mutations: compute envelopeHash, look up meta info when needed, call appendEnvelopeOperationLog (errors caught and logged).
Startup & Test Setup
infrastructure/evault-core/src/index.ts, infrastructure/evault-core/src/test-utils/e2e-setup.ts
Run index-creation and backfill modules during initialization and E2E setup via dynamic imports; wrapped in try/catch with warnings.
E2E Tests
infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Add E2E tests for GET /logs (success after storing meta-envelope; 400 when X-ENAME missing).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQL as GraphQL Server
participant HTTP as HTTP Server
participant DbService
participant DB as Neo4j
Client->>GraphQL: mutation (create/update/delete/update_envelope_value)
GraphQL->>DB: persist envelope change
GraphQL->>GraphQL: compute envelopeHash / lookup metaEnvelopeId & ontology
GraphQL->>DbService: appendEnvelopeOperationLog(params) (fire-and-forget)
DbService->>DB: CREATE EnvelopeOperationLog node
Client->>HTTP: GET /logs (X-ENAME, limit, cursor)
HTTP->>DbService: getEnvelopeOperationLogs(eName, {limit, cursor})
DbService->>DB: MATCH logs ORDER BY timestamp DESC, id ASC WITH cursor filter
DB-->>DbService: paginated records
DbService-->>HTTP: { logs, nextCursor, hasMore }
HTTP-->>Client: 200 { logs, nextCursor, hasMore }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • sosweetham
  • xPathin
  • dkraemerwork

Poem

🐰 I hop through logs with a tiny pen,
I hash the envelopes and write them when,
Cursors curl like carrot vines,
Paging through timestamps in neat lines. 🥕📜

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check nameStatusExplanationResolution
Description check⚠️ WarningThe PR description follows the template structure but lacks critical implementation details; it contains no issue number, no explanation of the feature being added, and no description of how testing was performed.Complete the PR description with the linked issue number, a detailed explanation of the envelope operation logs feature, and specific testing approach or scenarios covered.
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the main feature added: envelope operation logging with cursor pagination.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/logs-endpoint

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 978-1007: The cursor comparison in the cypher used by
runQueryInternal for EnvelopeOperationLog is inconsistent with the ORDER BY
clause: with "ORDER BY l.timestamp DESC, l.id ASC" the cursor predicate
"(l.timestamp < $cursorTs) OR (l.timestamp = $cursorTs AND l.id < $cursorId)" is
wrong and should use l.id > $cursorId for correct pagination; update the query
string to use "l.id > $cursorId" in the cursor branch (and keep the same
parameter names cursorTs/cursorId and limitPlusOne) so results for equal
timestamps are correctly ordered and no items are skipped or duplicated.
In `@infrastructure/evault-core/src/core/protocol/graphql-server.ts`:
- Around line 7-10: The import of computeEnvelopeHash and
computeEnvelopeHashForDelete in graphql-server.ts fails because
../db/envelope-hash does not exist or exports differ; either restore/create the
module exporting those two functions or correct the import to the actual module
that provides them (e.g., update the path or named exports to match where
computeEnvelopeHash and computeEnvelopeHashForDelete are defined), then run the
build to verify the import resolves.
- Around line 244-260: The post-write call to appendEnvelopeOperationLog (which
uses computeEnvelopeHash and result.metaEnvelope.id) must not cause the mutation
to fail if logging errors; change the logic so the main write completes
atomically and the log is recorded best-effort—either include the envelope log
in the same DB transaction as the write (so both commit or both rollback) or, if
a transaction is not feasible, invoke appendEnvelopeOperationLog without
blocking the response and wrap it in a try/catch (or attach .catch) to
swallow/log errors; update the code paths that call appendEnvelopeOperationLog
(e.g., in the create mutation where result.metaEnvelope is used) so failures in
appendEnvelopeOperationLog never bubble up and cause duplicate side effects.
- Around line 349-363: The audit log is being appended before the actual
deletion, and meta may be null; move logging to occur only after confirming
deletion succeeds (or perform both actions inside a DB transaction).
Specifically: call findMetaEnvelopeById(id, context.eName) to capture ontology
first, then call deleteMetaEnvelope(id, context.eName) and verify its
success/return value, and only then call appendEnvelopeOperationLog with
computeEnvelopeHashForDelete(id), platform, timestamp and ontology (use
null/explicit fallback if meta is missing). Alternatively wrap
deleteMetaEnvelope and appendEnvelopeOperationLog in a transaction to ensure
atomicity.
- Around line 379-405: Create the missing module ../db/envelope-hash that
exports computeEnvelopeHash and computeEnvelopeHashForDelete, implement
deterministic hashing of the provided envelope inputs (e.g., ontology and
payload) and ensure the functions are used where computeEnvelopeHash is called
in graphql-server.ts; specifically, make computeEnvelopeHash include an id field
in the payload for the "update_envelope_value" operation (use the envelopeId
parameter as id) so its inputs match the create/update hash shape, and implement
computeEnvelopeHashForDelete to accept the same identifying fields used when
deleting; ensure exports match the named imports used by graphql-server.ts.
In `@infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts`:
- Around line 600-630: The test uses the variable client inside the "GET /logs
endpoint" block but never initializes it; add a beforeAll (and matching afterAll
if needed) in that describe block to set up client the same way other suites do
(e.g., call whatever setup used elsewhere to assign client and ensure evault1 is
available), so that client.storeMetaEnvelope and subsequent fetch calls run
against a valid client instance; reference the describe block name "GET /logs
endpoint", the variable client, and the method storeMetaEnvelope to locate where
to add the beforeAll/afterAll setup and teardown.
In `@infrastructure/evault-core/src/index.ts`:
- Around line 120-126: The dynamic import/usage of backfillEnvelopeOperationLogs
in index.ts is referencing a missing migration module and will fail at runtime;
either add an exported async function backfillEnvelopeOperationLogs that accepts
the existing driver and performs the backfill, and place it where the dynamic
import in index.ts expects to load it, or remove the try/catch block and call
entirely (including the import and await backfillEnvelopeOperationLogs(driver))
if the migration isn’t needed yet—ensure the symbol name
backfillEnvelopeOperationLogs and the driver argument remain consistent with the
current code when you implement or remove the call.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Comment threadinfrastructure/evault-core/src/index.ts
@coodoscoodos changed the title feat: logseat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodoscoodos changed the title eat: implement envelope operation logging with cursor paginationfeat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodos
coodos merged commit 570a770 into mainFeb 4, 2026
5 of 6 checks passed
@coodos
coodos deleted the feat/logs-endpoint branch February 4, 2026 08:11
This was referenced Feb 4, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

2 participants

@coodos@sosweetham
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: implement envelope operation logging with cursor pagination - #764

Merged
coodos merged 4 commits into
mainfrom
feat/logs-endpoint
Feb 4, 2026
Merged

feat: implement envelope operation logging with cursor pagination#764
coodos merged 4 commits into
mainfrom
feat/logs-endpoint

Conversation

@coodos

@coodoscoodos commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Description of change

Issue Number

Type of change

  • New (a change which implements a new feature)

How the change has been tested

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

  • New Features

    • Envelope operations (create, update, delete, value updates) are logged with operation, platform, timestamp, ontology and envelope hash; logs can be appended and queried with cursor-based pagination via a new /logs HTTP endpoint.
  • Chores

    • One-time index creation and backfill steps added to initialization to populate and index operation logs.
  • Documentation

    • API docs updated with /logs endpoint, parameters and examples.
  • Tests

    • Integration and end-to-end tests covering logging, pagination and header validation.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds envelope operation logging: new DB types, DbService methods for appending and paginating logs, a /logs HTTP endpoint, GraphQL mutation hooks to emit logs (best-effort), migrations (index + backfill) run at startup/tests, and unit + e2e tests for storage and retrieval.

Changes

Cohort / File(s)Summary
Type Definitions
infrastructure/evault-core/src/core/db/types.ts
Add types for operation logs: EnvelopeOperationType, EnvelopeOperationLogEntry, AppendEnvelopeOperationLogParams, GetEnvelopeOperationLogsResult.
Database Service & Tests
infrastructure/evault-core/src/core/db/db.service.ts, infrastructure/evault-core/src/core/db/db.service.spec.ts
Add methods getMetaEnvelopeIdByEnvelopeId, appendEnvelopeOperationLog, getEnvelopeOperationLogs (cursor-based pagination, limit bounds); tests for storing, pagination, and meta-envelope mapping.
Hashing & Ontology Helpers
infrastructure/evault-core/src/core/db/envelope-hash.ts, infrastructure/evault-core/src/core/db/ontology-platform.ts, .../ontology-platform.spec.ts
Add deterministic envelope hash utilities and ontology→platform inference used by backfill; unit tests for inference.
Migrations / Backfill
infrastructure/evault-core/src/core/db/migrations/add-envelope-operation-log-index.ts, infrastructure/evault-core/src/core/db/migrations/backfill-envelope-operation-logs.ts
Add migration to create EnvelopeOperationLog indexes and a backfill script to create initial log entries from existing MetaEnvelope nodes; marker node to avoid rerun.
HTTP Server & Docs
infrastructure/evault-core/src/core/http/server.ts, docs/docs/Infrastructure/eVault.md
New GET /logs endpoint requiring X-ENAME, supports limit and cursor, returns { logs, nextCursor, hasMore }; Swagger/docs updated.
GraphQL Instrumentation
infrastructure/evault-core/src/protocol/graphql-server.ts
Fire-and-forget logging after create/update/delete/update_envelope_value mutations: compute envelopeHash, look up meta info when needed, call appendEnvelopeOperationLog (errors caught and logged).
Startup & Test Setup
infrastructure/evault-core/src/index.ts, infrastructure/evault-core/src/test-utils/e2e-setup.ts
Run index-creation and backfill modules during initialization and E2E setup via dynamic imports; wrapped in try/catch with warnings.
E2E Tests
infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Add E2E tests for GET /logs (success after storing meta-envelope; 400 when X-ENAME missing).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQL as GraphQL Server
participant HTTP as HTTP Server
participant DbService
participant DB as Neo4j
Client->>GraphQL: mutation (create/update/delete/update_envelope_value)
GraphQL->>DB: persist envelope change
GraphQL->>GraphQL: compute envelopeHash / lookup metaEnvelopeId & ontology
GraphQL->>DbService: appendEnvelopeOperationLog(params) (fire-and-forget)
DbService->>DB: CREATE EnvelopeOperationLog node
Client->>HTTP: GET /logs (X-ENAME, limit, cursor)
HTTP->>DbService: getEnvelopeOperationLogs(eName, {limit, cursor})
DbService->>DB: MATCH logs ORDER BY timestamp DESC, id ASC WITH cursor filter
DB-->>DbService: paginated records
DbService-->>HTTP: { logs, nextCursor, hasMore }
HTTP-->>Client: 200 { logs, nextCursor, hasMore }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • sosweetham
  • xPathin
  • dkraemerwork

Poem

🐰 I hop through logs with a tiny pen,
I hash the envelopes and write them when,
Cursors curl like carrot vines,
Paging through timestamps in neat lines. 🥕📜

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check nameStatusExplanationResolution
Description check⚠️ WarningThe PR description follows the template structure but lacks critical implementation details; it contains no issue number, no explanation of the feature being added, and no description of how testing was performed.Complete the PR description with the linked issue number, a detailed explanation of the envelope operation logs feature, and specific testing approach or scenarios covered.
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the main feature added: envelope operation logging with cursor pagination.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/logs-endpoint

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 978-1007: The cursor comparison in the cypher used by
runQueryInternal for EnvelopeOperationLog is inconsistent with the ORDER BY
clause: with "ORDER BY l.timestamp DESC, l.id ASC" the cursor predicate
"(l.timestamp < $cursorTs) OR (l.timestamp = $cursorTs AND l.id < $cursorId)" is
wrong and should use l.id > $cursorId for correct pagination; update the query
string to use "l.id > $cursorId" in the cursor branch (and keep the same
parameter names cursorTs/cursorId and limitPlusOne) so results for equal
timestamps are correctly ordered and no items are skipped or duplicated.
In `@infrastructure/evault-core/src/core/protocol/graphql-server.ts`:
- Around line 7-10: The import of computeEnvelopeHash and
computeEnvelopeHashForDelete in graphql-server.ts fails because
../db/envelope-hash does not exist or exports differ; either restore/create the
module exporting those two functions or correct the import to the actual module
that provides them (e.g., update the path or named exports to match where
computeEnvelopeHash and computeEnvelopeHashForDelete are defined), then run the
build to verify the import resolves.
- Around line 244-260: The post-write call to appendEnvelopeOperationLog (which
uses computeEnvelopeHash and result.metaEnvelope.id) must not cause the mutation
to fail if logging errors; change the logic so the main write completes
atomically and the log is recorded best-effort—either include the envelope log
in the same DB transaction as the write (so both commit or both rollback) or, if
a transaction is not feasible, invoke appendEnvelopeOperationLog without
blocking the response and wrap it in a try/catch (or attach .catch) to
swallow/log errors; update the code paths that call appendEnvelopeOperationLog
(e.g., in the create mutation where result.metaEnvelope is used) so failures in
appendEnvelopeOperationLog never bubble up and cause duplicate side effects.
- Around line 349-363: The audit log is being appended before the actual
deletion, and meta may be null; move logging to occur only after confirming
deletion succeeds (or perform both actions inside a DB transaction).
Specifically: call findMetaEnvelopeById(id, context.eName) to capture ontology
first, then call deleteMetaEnvelope(id, context.eName) and verify its
success/return value, and only then call appendEnvelopeOperationLog with
computeEnvelopeHashForDelete(id), platform, timestamp and ontology (use
null/explicit fallback if meta is missing). Alternatively wrap
deleteMetaEnvelope and appendEnvelopeOperationLog in a transaction to ensure
atomicity.
- Around line 379-405: Create the missing module ../db/envelope-hash that
exports computeEnvelopeHash and computeEnvelopeHashForDelete, implement
deterministic hashing of the provided envelope inputs (e.g., ontology and
payload) and ensure the functions are used where computeEnvelopeHash is called
in graphql-server.ts; specifically, make computeEnvelopeHash include an id field
in the payload for the "update_envelope_value" operation (use the envelopeId
parameter as id) so its inputs match the create/update hash shape, and implement
computeEnvelopeHashForDelete to accept the same identifying fields used when
deleting; ensure exports match the named imports used by graphql-server.ts.
In `@infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts`:
- Around line 600-630: The test uses the variable client inside the "GET /logs
endpoint" block but never initializes it; add a beforeAll (and matching afterAll
if needed) in that describe block to set up client the same way other suites do
(e.g., call whatever setup used elsewhere to assign client and ensure evault1 is
available), so that client.storeMetaEnvelope and subsequent fetch calls run
against a valid client instance; reference the describe block name "GET /logs
endpoint", the variable client, and the method storeMetaEnvelope to locate where
to add the beforeAll/afterAll setup and teardown.
In `@infrastructure/evault-core/src/index.ts`:
- Around line 120-126: The dynamic import/usage of backfillEnvelopeOperationLogs
in index.ts is referencing a missing migration module and will fail at runtime;
either add an exported async function backfillEnvelopeOperationLogs that accepts
the existing driver and performs the backfill, and place it where the dynamic
import in index.ts expects to load it, or remove the try/catch block and call
entirely (including the import and await backfillEnvelopeOperationLogs(driver))
if the migration isn’t needed yet—ensure the symbol name
backfillEnvelopeOperationLogs and the driver argument remain consistent with the
current code when you implement or remove the call.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Comment threadinfrastructure/evault-core/src/index.ts
@coodoscoodos changed the title feat: logseat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodoscoodos changed the title eat: implement envelope operation logging with cursor paginationfeat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodos
coodos merged commit 570a770 into mainFeb 4, 2026
5 of 6 checks passed
@coodos
coodos deleted the feat/logs-endpoint branch February 4, 2026 08:11
This was referenced Feb 4, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

2 participants

@coodos@sosweetham
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: implement envelope operation logging with cursor pagination - #764

Merged
coodos merged 4 commits into
mainfrom
feat/logs-endpoint
Feb 4, 2026
Merged

feat: implement envelope operation logging with cursor pagination#764
coodos merged 4 commits into
mainfrom
feat/logs-endpoint

Conversation

@coodos

@coodoscoodos commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Description of change

Issue Number

Type of change

  • New (a change which implements a new feature)

How the change has been tested

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

  • New Features

    • Envelope operations (create, update, delete, value updates) are logged with operation, platform, timestamp, ontology and envelope hash; logs can be appended and queried with cursor-based pagination via a new /logs HTTP endpoint.
  • Chores

    • One-time index creation and backfill steps added to initialization to populate and index operation logs.
  • Documentation

    • API docs updated with /logs endpoint, parameters and examples.
  • Tests

    • Integration and end-to-end tests covering logging, pagination and header validation.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds envelope operation logging: new DB types, DbService methods for appending and paginating logs, a /logs HTTP endpoint, GraphQL mutation hooks to emit logs (best-effort), migrations (index + backfill) run at startup/tests, and unit + e2e tests for storage and retrieval.

Changes

Cohort / File(s)Summary
Type Definitions
infrastructure/evault-core/src/core/db/types.ts
Add types for operation logs: EnvelopeOperationType, EnvelopeOperationLogEntry, AppendEnvelopeOperationLogParams, GetEnvelopeOperationLogsResult.
Database Service & Tests
infrastructure/evault-core/src/core/db/db.service.ts, infrastructure/evault-core/src/core/db/db.service.spec.ts
Add methods getMetaEnvelopeIdByEnvelopeId, appendEnvelopeOperationLog, getEnvelopeOperationLogs (cursor-based pagination, limit bounds); tests for storing, pagination, and meta-envelope mapping.
Hashing & Ontology Helpers
infrastructure/evault-core/src/core/db/envelope-hash.ts, infrastructure/evault-core/src/core/db/ontology-platform.ts, .../ontology-platform.spec.ts
Add deterministic envelope hash utilities and ontology→platform inference used by backfill; unit tests for inference.
Migrations / Backfill
infrastructure/evault-core/src/core/db/migrations/add-envelope-operation-log-index.ts, infrastructure/evault-core/src/core/db/migrations/backfill-envelope-operation-logs.ts
Add migration to create EnvelopeOperationLog indexes and a backfill script to create initial log entries from existing MetaEnvelope nodes; marker node to avoid rerun.
HTTP Server & Docs
infrastructure/evault-core/src/core/http/server.ts, docs/docs/Infrastructure/eVault.md
New GET /logs endpoint requiring X-ENAME, supports limit and cursor, returns { logs, nextCursor, hasMore }; Swagger/docs updated.
GraphQL Instrumentation
infrastructure/evault-core/src/protocol/graphql-server.ts
Fire-and-forget logging after create/update/delete/update_envelope_value mutations: compute envelopeHash, look up meta info when needed, call appendEnvelopeOperationLog (errors caught and logged).
Startup & Test Setup
infrastructure/evault-core/src/index.ts, infrastructure/evault-core/src/test-utils/e2e-setup.ts
Run index-creation and backfill modules during initialization and E2E setup via dynamic imports; wrapped in try/catch with warnings.
E2E Tests
infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Add E2E tests for GET /logs (success after storing meta-envelope; 400 when X-ENAME missing).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQL as GraphQL Server
participant HTTP as HTTP Server
participant DbService
participant DB as Neo4j
Client->>GraphQL: mutation (create/update/delete/update_envelope_value)
GraphQL->>DB: persist envelope change
GraphQL->>GraphQL: compute envelopeHash / lookup metaEnvelopeId & ontology
GraphQL->>DbService: appendEnvelopeOperationLog(params) (fire-and-forget)
DbService->>DB: CREATE EnvelopeOperationLog node
Client->>HTTP: GET /logs (X-ENAME, limit, cursor)
HTTP->>DbService: getEnvelopeOperationLogs(eName, {limit, cursor})
DbService->>DB: MATCH logs ORDER BY timestamp DESC, id ASC WITH cursor filter
DB-->>DbService: paginated records
DbService-->>HTTP: { logs, nextCursor, hasMore }
HTTP-->>Client: 200 { logs, nextCursor, hasMore }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • sosweetham
  • xPathin
  • dkraemerwork

Poem

🐰 I hop through logs with a tiny pen,
I hash the envelopes and write them when,
Cursors curl like carrot vines,
Paging through timestamps in neat lines. 🥕📜

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check nameStatusExplanationResolution
Description check⚠️ WarningThe PR description follows the template structure but lacks critical implementation details; it contains no issue number, no explanation of the feature being added, and no description of how testing was performed.Complete the PR description with the linked issue number, a detailed explanation of the envelope operation logs feature, and specific testing approach or scenarios covered.
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the main feature added: envelope operation logging with cursor pagination.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/logs-endpoint

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 978-1007: The cursor comparison in the cypher used by
runQueryInternal for EnvelopeOperationLog is inconsistent with the ORDER BY
clause: with "ORDER BY l.timestamp DESC, l.id ASC" the cursor predicate
"(l.timestamp < $cursorTs) OR (l.timestamp = $cursorTs AND l.id < $cursorId)" is
wrong and should use l.id > $cursorId for correct pagination; update the query
string to use "l.id > $cursorId" in the cursor branch (and keep the same
parameter names cursorTs/cursorId and limitPlusOne) so results for equal
timestamps are correctly ordered and no items are skipped or duplicated.
In `@infrastructure/evault-core/src/core/protocol/graphql-server.ts`:
- Around line 7-10: The import of computeEnvelopeHash and
computeEnvelopeHashForDelete in graphql-server.ts fails because
../db/envelope-hash does not exist or exports differ; either restore/create the
module exporting those two functions or correct the import to the actual module
that provides them (e.g., update the path or named exports to match where
computeEnvelopeHash and computeEnvelopeHashForDelete are defined), then run the
build to verify the import resolves.
- Around line 244-260: The post-write call to appendEnvelopeOperationLog (which
uses computeEnvelopeHash and result.metaEnvelope.id) must not cause the mutation
to fail if logging errors; change the logic so the main write completes
atomically and the log is recorded best-effort—either include the envelope log
in the same DB transaction as the write (so both commit or both rollback) or, if
a transaction is not feasible, invoke appendEnvelopeOperationLog without
blocking the response and wrap it in a try/catch (or attach .catch) to
swallow/log errors; update the code paths that call appendEnvelopeOperationLog
(e.g., in the create mutation where result.metaEnvelope is used) so failures in
appendEnvelopeOperationLog never bubble up and cause duplicate side effects.
- Around line 349-363: The audit log is being appended before the actual
deletion, and meta may be null; move logging to occur only after confirming
deletion succeeds (or perform both actions inside a DB transaction).
Specifically: call findMetaEnvelopeById(id, context.eName) to capture ontology
first, then call deleteMetaEnvelope(id, context.eName) and verify its
success/return value, and only then call appendEnvelopeOperationLog with
computeEnvelopeHashForDelete(id), platform, timestamp and ontology (use
null/explicit fallback if meta is missing). Alternatively wrap
deleteMetaEnvelope and appendEnvelopeOperationLog in a transaction to ensure
atomicity.
- Around line 379-405: Create the missing module ../db/envelope-hash that
exports computeEnvelopeHash and computeEnvelopeHashForDelete, implement
deterministic hashing of the provided envelope inputs (e.g., ontology and
payload) and ensure the functions are used where computeEnvelopeHash is called
in graphql-server.ts; specifically, make computeEnvelopeHash include an id field
in the payload for the "update_envelope_value" operation (use the envelopeId
parameter as id) so its inputs match the create/update hash shape, and implement
computeEnvelopeHashForDelete to accept the same identifying fields used when
deleting; ensure exports match the named imports used by graphql-server.ts.
In `@infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts`:
- Around line 600-630: The test uses the variable client inside the "GET /logs
endpoint" block but never initializes it; add a beforeAll (and matching afterAll
if needed) in that describe block to set up client the same way other suites do
(e.g., call whatever setup used elsewhere to assign client and ensure evault1 is
available), so that client.storeMetaEnvelope and subsequent fetch calls run
against a valid client instance; reference the describe block name "GET /logs
endpoint", the variable client, and the method storeMetaEnvelope to locate where
to add the beforeAll/afterAll setup and teardown.
In `@infrastructure/evault-core/src/index.ts`:
- Around line 120-126: The dynamic import/usage of backfillEnvelopeOperationLogs
in index.ts is referencing a missing migration module and will fail at runtime;
either add an exported async function backfillEnvelopeOperationLogs that accepts
the existing driver and performs the backfill, and place it where the dynamic
import in index.ts expects to load it, or remove the try/catch block and call
entirely (including the import and await backfillEnvelopeOperationLogs(driver))
if the migration isn’t needed yet—ensure the symbol name
backfillEnvelopeOperationLogs and the driver argument remain consistent with the
current code when you implement or remove the call.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Comment threadinfrastructure/evault-core/src/index.ts
@coodoscoodos changed the title feat: logseat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodoscoodos changed the title eat: implement envelope operation logging with cursor paginationfeat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodos
coodos merged commit 570a770 into mainFeb 4, 2026
5 of 6 checks passed
@coodos
coodos deleted the feat/logs-endpoint branch February 4, 2026 08:11
This was referenced Feb 4, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

2 participants

@coodos@sosweetham
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: implement envelope operation logging with cursor pagination - #764

Merged
coodos merged 4 commits into
mainfrom
feat/logs-endpoint
Feb 4, 2026
Merged

feat: implement envelope operation logging with cursor pagination#764
coodos merged 4 commits into
mainfrom
feat/logs-endpoint

Conversation

@coodos

@coodoscoodos commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Description of change

Issue Number

Type of change

  • New (a change which implements a new feature)

How the change has been tested

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

  • New Features

    • Envelope operations (create, update, delete, value updates) are logged with operation, platform, timestamp, ontology and envelope hash; logs can be appended and queried with cursor-based pagination via a new /logs HTTP endpoint.
  • Chores

    • One-time index creation and backfill steps added to initialization to populate and index operation logs.
  • Documentation

    • API docs updated with /logs endpoint, parameters and examples.
  • Tests

    • Integration and end-to-end tests covering logging, pagination and header validation.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds envelope operation logging: new DB types, DbService methods for appending and paginating logs, a /logs HTTP endpoint, GraphQL mutation hooks to emit logs (best-effort), migrations (index + backfill) run at startup/tests, and unit + e2e tests for storage and retrieval.

Changes

Cohort / File(s)Summary
Type Definitions
infrastructure/evault-core/src/core/db/types.ts
Add types for operation logs: EnvelopeOperationType, EnvelopeOperationLogEntry, AppendEnvelopeOperationLogParams, GetEnvelopeOperationLogsResult.
Database Service & Tests
infrastructure/evault-core/src/core/db/db.service.ts, infrastructure/evault-core/src/core/db/db.service.spec.ts
Add methods getMetaEnvelopeIdByEnvelopeId, appendEnvelopeOperationLog, getEnvelopeOperationLogs (cursor-based pagination, limit bounds); tests for storing, pagination, and meta-envelope mapping.
Hashing & Ontology Helpers
infrastructure/evault-core/src/core/db/envelope-hash.ts, infrastructure/evault-core/src/core/db/ontology-platform.ts, .../ontology-platform.spec.ts
Add deterministic envelope hash utilities and ontology→platform inference used by backfill; unit tests for inference.
Migrations / Backfill
infrastructure/evault-core/src/core/db/migrations/add-envelope-operation-log-index.ts, infrastructure/evault-core/src/core/db/migrations/backfill-envelope-operation-logs.ts
Add migration to create EnvelopeOperationLog indexes and a backfill script to create initial log entries from existing MetaEnvelope nodes; marker node to avoid rerun.
HTTP Server & Docs
infrastructure/evault-core/src/core/http/server.ts, docs/docs/Infrastructure/eVault.md
New GET /logs endpoint requiring X-ENAME, supports limit and cursor, returns { logs, nextCursor, hasMore }; Swagger/docs updated.
GraphQL Instrumentation
infrastructure/evault-core/src/protocol/graphql-server.ts
Fire-and-forget logging after create/update/delete/update_envelope_value mutations: compute envelopeHash, look up meta info when needed, call appendEnvelopeOperationLog (errors caught and logged).
Startup & Test Setup
infrastructure/evault-core/src/index.ts, infrastructure/evault-core/src/test-utils/e2e-setup.ts
Run index-creation and backfill modules during initialization and E2E setup via dynamic imports; wrapped in try/catch with warnings.
E2E Tests
infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Add E2E tests for GET /logs (success after storing meta-envelope; 400 when X-ENAME missing).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQL as GraphQL Server
participant HTTP as HTTP Server
participant DbService
participant DB as Neo4j
Client->>GraphQL: mutation (create/update/delete/update_envelope_value)
GraphQL->>DB: persist envelope change
GraphQL->>GraphQL: compute envelopeHash / lookup metaEnvelopeId & ontology
GraphQL->>DbService: appendEnvelopeOperationLog(params) (fire-and-forget)
DbService->>DB: CREATE EnvelopeOperationLog node
Client->>HTTP: GET /logs (X-ENAME, limit, cursor)
HTTP->>DbService: getEnvelopeOperationLogs(eName, {limit, cursor})
DbService->>DB: MATCH logs ORDER BY timestamp DESC, id ASC WITH cursor filter
DB-->>DbService: paginated records
DbService-->>HTTP: { logs, nextCursor, hasMore }
HTTP-->>Client: 200 { logs, nextCursor, hasMore }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • sosweetham
  • xPathin
  • dkraemerwork

Poem

🐰 I hop through logs with a tiny pen,
I hash the envelopes and write them when,
Cursors curl like carrot vines,
Paging through timestamps in neat lines. 🥕📜

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check nameStatusExplanationResolution
Description check⚠️ WarningThe PR description follows the template structure but lacks critical implementation details; it contains no issue number, no explanation of the feature being added, and no description of how testing was performed.Complete the PR description with the linked issue number, a detailed explanation of the envelope operation logs feature, and specific testing approach or scenarios covered.
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the main feature added: envelope operation logging with cursor pagination.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/logs-endpoint

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 978-1007: The cursor comparison in the cypher used by
runQueryInternal for EnvelopeOperationLog is inconsistent with the ORDER BY
clause: with "ORDER BY l.timestamp DESC, l.id ASC" the cursor predicate
"(l.timestamp < $cursorTs) OR (l.timestamp = $cursorTs AND l.id < $cursorId)" is
wrong and should use l.id > $cursorId for correct pagination; update the query
string to use "l.id > $cursorId" in the cursor branch (and keep the same
parameter names cursorTs/cursorId and limitPlusOne) so results for equal
timestamps are correctly ordered and no items are skipped or duplicated.
In `@infrastructure/evault-core/src/core/protocol/graphql-server.ts`:
- Around line 7-10: The import of computeEnvelopeHash and
computeEnvelopeHashForDelete in graphql-server.ts fails because
../db/envelope-hash does not exist or exports differ; either restore/create the
module exporting those two functions or correct the import to the actual module
that provides them (e.g., update the path or named exports to match where
computeEnvelopeHash and computeEnvelopeHashForDelete are defined), then run the
build to verify the import resolves.
- Around line 244-260: The post-write call to appendEnvelopeOperationLog (which
uses computeEnvelopeHash and result.metaEnvelope.id) must not cause the mutation
to fail if logging errors; change the logic so the main write completes
atomically and the log is recorded best-effort—either include the envelope log
in the same DB transaction as the write (so both commit or both rollback) or, if
a transaction is not feasible, invoke appendEnvelopeOperationLog without
blocking the response and wrap it in a try/catch (or attach .catch) to
swallow/log errors; update the code paths that call appendEnvelopeOperationLog
(e.g., in the create mutation where result.metaEnvelope is used) so failures in
appendEnvelopeOperationLog never bubble up and cause duplicate side effects.
- Around line 349-363: The audit log is being appended before the actual
deletion, and meta may be null; move logging to occur only after confirming
deletion succeeds (or perform both actions inside a DB transaction).
Specifically: call findMetaEnvelopeById(id, context.eName) to capture ontology
first, then call deleteMetaEnvelope(id, context.eName) and verify its
success/return value, and only then call appendEnvelopeOperationLog with
computeEnvelopeHashForDelete(id), platform, timestamp and ontology (use
null/explicit fallback if meta is missing). Alternatively wrap
deleteMetaEnvelope and appendEnvelopeOperationLog in a transaction to ensure
atomicity.
- Around line 379-405: Create the missing module ../db/envelope-hash that
exports computeEnvelopeHash and computeEnvelopeHashForDelete, implement
deterministic hashing of the provided envelope inputs (e.g., ontology and
payload) and ensure the functions are used where computeEnvelopeHash is called
in graphql-server.ts; specifically, make computeEnvelopeHash include an id field
in the payload for the "update_envelope_value" operation (use the envelopeId
parameter as id) so its inputs match the create/update hash shape, and implement
computeEnvelopeHashForDelete to accept the same identifying fields used when
deleting; ensure exports match the named imports used by graphql-server.ts.
In `@infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts`:
- Around line 600-630: The test uses the variable client inside the "GET /logs
endpoint" block but never initializes it; add a beforeAll (and matching afterAll
if needed) in that describe block to set up client the same way other suites do
(e.g., call whatever setup used elsewhere to assign client and ensure evault1 is
available), so that client.storeMetaEnvelope and subsequent fetch calls run
against a valid client instance; reference the describe block name "GET /logs
endpoint", the variable client, and the method storeMetaEnvelope to locate where
to add the beforeAll/afterAll setup and teardown.
In `@infrastructure/evault-core/src/index.ts`:
- Around line 120-126: The dynamic import/usage of backfillEnvelopeOperationLogs
in index.ts is referencing a missing migration module and will fail at runtime;
either add an exported async function backfillEnvelopeOperationLogs that accepts
the existing driver and performs the backfill, and place it where the dynamic
import in index.ts expects to load it, or remove the try/catch block and call
entirely (including the import and await backfillEnvelopeOperationLogs(driver))
if the migration isn’t needed yet—ensure the symbol name
backfillEnvelopeOperationLogs and the driver argument remain consistent with the
current code when you implement or remove the call.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Comment threadinfrastructure/evault-core/src/index.ts
@coodoscoodos changed the title feat: logseat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodoscoodos changed the title eat: implement envelope operation logging with cursor paginationfeat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodos
coodos merged commit 570a770 into mainFeb 4, 2026
5 of 6 checks passed
@coodos
coodos deleted the feat/logs-endpoint branch February 4, 2026 08:11
This was referenced Feb 4, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

2 participants

@coodos@sosweetham
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: implement envelope operation logging with cursor pagination - #764

Merged
coodos merged 4 commits into
mainfrom
feat/logs-endpoint
Feb 4, 2026
Merged

feat: implement envelope operation logging with cursor pagination#764
coodos merged 4 commits into
mainfrom
feat/logs-endpoint

Conversation

@coodos

@coodoscoodos commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Description of change

Issue Number

Type of change

  • New (a change which implements a new feature)

How the change has been tested

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

  • New Features

    • Envelope operations (create, update, delete, value updates) are logged with operation, platform, timestamp, ontology and envelope hash; logs can be appended and queried with cursor-based pagination via a new /logs HTTP endpoint.
  • Chores

    • One-time index creation and backfill steps added to initialization to populate and index operation logs.
  • Documentation

    • API docs updated with /logs endpoint, parameters and examples.
  • Tests

    • Integration and end-to-end tests covering logging, pagination and header validation.

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds envelope operation logging: new DB types, DbService methods for appending and paginating logs, a /logs HTTP endpoint, GraphQL mutation hooks to emit logs (best-effort), migrations (index + backfill) run at startup/tests, and unit + e2e tests for storage and retrieval.

Changes

Cohort / File(s)Summary
Type Definitions
infrastructure/evault-core/src/core/db/types.ts
Add types for operation logs: EnvelopeOperationType, EnvelopeOperationLogEntry, AppendEnvelopeOperationLogParams, GetEnvelopeOperationLogsResult.
Database Service & Tests
infrastructure/evault-core/src/core/db/db.service.ts, infrastructure/evault-core/src/core/db/db.service.spec.ts
Add methods getMetaEnvelopeIdByEnvelopeId, appendEnvelopeOperationLog, getEnvelopeOperationLogs (cursor-based pagination, limit bounds); tests for storing, pagination, and meta-envelope mapping.
Hashing & Ontology Helpers
infrastructure/evault-core/src/core/db/envelope-hash.ts, infrastructure/evault-core/src/core/db/ontology-platform.ts, .../ontology-platform.spec.ts
Add deterministic envelope hash utilities and ontology→platform inference used by backfill; unit tests for inference.
Migrations / Backfill
infrastructure/evault-core/src/core/db/migrations/add-envelope-operation-log-index.ts, infrastructure/evault-core/src/core/db/migrations/backfill-envelope-operation-logs.ts
Add migration to create EnvelopeOperationLog indexes and a backfill script to create initial log entries from existing MetaEnvelope nodes; marker node to avoid rerun.
HTTP Server & Docs
infrastructure/evault-core/src/core/http/server.ts, docs/docs/Infrastructure/eVault.md
New GET /logs endpoint requiring X-ENAME, supports limit and cursor, returns { logs, nextCursor, hasMore }; Swagger/docs updated.
GraphQL Instrumentation
infrastructure/evault-core/src/protocol/graphql-server.ts
Fire-and-forget logging after create/update/delete/update_envelope_value mutations: compute envelopeHash, look up meta info when needed, call appendEnvelopeOperationLog (errors caught and logged).
Startup & Test Setup
infrastructure/evault-core/src/index.ts, infrastructure/evault-core/src/test-utils/e2e-setup.ts
Run index-creation and backfill modules during initialization and E2E setup via dynamic imports; wrapped in try/catch with warnings.
E2E Tests
infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Add E2E tests for GET /logs (success after storing meta-envelope; 400 when X-ENAME missing).

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQL as GraphQL Server
participant HTTP as HTTP Server
participant DbService
participant DB as Neo4j
Client->>GraphQL: mutation (create/update/delete/update_envelope_value)
GraphQL->>DB: persist envelope change
GraphQL->>GraphQL: compute envelopeHash / lookup metaEnvelopeId & ontology
GraphQL->>DbService: appendEnvelopeOperationLog(params) (fire-and-forget)
DbService->>DB: CREATE EnvelopeOperationLog node
Client->>HTTP: GET /logs (X-ENAME, limit, cursor)
HTTP->>DbService: getEnvelopeOperationLogs(eName, {limit, cursor})
DbService->>DB: MATCH logs ORDER BY timestamp DESC, id ASC WITH cursor filter
DB-->>DbService: paginated records
DbService-->>HTTP: { logs, nextCursor, hasMore }
HTTP-->>Client: 200 { logs, nextCursor, hasMore }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • sosweetham
  • xPathin
  • dkraemerwork

Poem

🐰 I hop through logs with a tiny pen,
I hash the envelopes and write them when,
Cursors curl like carrot vines,
Paging through timestamps in neat lines. 🥕📜

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check nameStatusExplanationResolution
Description check⚠️ WarningThe PR description follows the template structure but lacks critical implementation details; it contains no issue number, no explanation of the feature being added, and no description of how testing was performed.Complete the PR description with the linked issue number, a detailed explanation of the envelope operation logs feature, and specific testing approach or scenarios covered.
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly and specifically describes the main feature added: envelope operation logging with cursor pagination.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/logs-endpoint

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.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 978-1007: The cursor comparison in the cypher used by
runQueryInternal for EnvelopeOperationLog is inconsistent with the ORDER BY
clause: with "ORDER BY l.timestamp DESC, l.id ASC" the cursor predicate
"(l.timestamp < $cursorTs) OR (l.timestamp = $cursorTs AND l.id < $cursorId)" is
wrong and should use l.id > $cursorId for correct pagination; update the query
string to use "l.id > $cursorId" in the cursor branch (and keep the same
parameter names cursorTs/cursorId and limitPlusOne) so results for equal
timestamps are correctly ordered and no items are skipped or duplicated.
In `@infrastructure/evault-core/src/core/protocol/graphql-server.ts`:
- Around line 7-10: The import of computeEnvelopeHash and
computeEnvelopeHashForDelete in graphql-server.ts fails because
../db/envelope-hash does not exist or exports differ; either restore/create the
module exporting those two functions or correct the import to the actual module
that provides them (e.g., update the path or named exports to match where
computeEnvelopeHash and computeEnvelopeHashForDelete are defined), then run the
build to verify the import resolves.
- Around line 244-260: The post-write call to appendEnvelopeOperationLog (which
uses computeEnvelopeHash and result.metaEnvelope.id) must not cause the mutation
to fail if logging errors; change the logic so the main write completes
atomically and the log is recorded best-effort—either include the envelope log
in the same DB transaction as the write (so both commit or both rollback) or, if
a transaction is not feasible, invoke appendEnvelopeOperationLog without
blocking the response and wrap it in a try/catch (or attach .catch) to
swallow/log errors; update the code paths that call appendEnvelopeOperationLog
(e.g., in the create mutation where result.metaEnvelope is used) so failures in
appendEnvelopeOperationLog never bubble up and cause duplicate side effects.
- Around line 349-363: The audit log is being appended before the actual
deletion, and meta may be null; move logging to occur only after confirming
deletion succeeds (or perform both actions inside a DB transaction).
Specifically: call findMetaEnvelopeById(id, context.eName) to capture ontology
first, then call deleteMetaEnvelope(id, context.eName) and verify its
success/return value, and only then call appendEnvelopeOperationLog with
computeEnvelopeHashForDelete(id), platform, timestamp and ontology (use
null/explicit fallback if meta is missing). Alternatively wrap
deleteMetaEnvelope and appendEnvelopeOperationLog in a transaction to ensure
atomicity.
- Around line 379-405: Create the missing module ../db/envelope-hash that
exports computeEnvelopeHash and computeEnvelopeHashForDelete, implement
deterministic hashing of the provided envelope inputs (e.g., ontology and
payload) and ensure the functions are used where computeEnvelopeHash is called
in graphql-server.ts; specifically, make computeEnvelopeHash include an id field
in the payload for the "update_envelope_value" operation (use the envelopeId
parameter as id) so its inputs match the create/update hash shape, and implement
computeEnvelopeHashForDelete to accept the same identifying fields used when
deleting; ensure exports match the named imports used by graphql-server.ts.
In `@infrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts`:
- Around line 600-630: The test uses the variable client inside the "GET /logs
endpoint" block but never initializes it; add a beforeAll (and matching afterAll
if needed) in that describe block to set up client the same way other suites do
(e.g., call whatever setup used elsewhere to assign client and ensure evault1 is
available), so that client.storeMetaEnvelope and subsequent fetch calls run
against a valid client instance; reference the describe block name "GET /logs
endpoint", the variable client, and the method storeMetaEnvelope to locate where
to add the beforeAll/afterAll setup and teardown.
In `@infrastructure/evault-core/src/index.ts`:
- Around line 120-126: The dynamic import/usage of backfillEnvelopeOperationLogs
in index.ts is referencing a missing migration module and will fail at runtime;
either add an exported async function backfillEnvelopeOperationLogs that accepts
the existing driver and performs the backfill, and place it where the dynamic
import in index.ts expects to load it, or remove the try/catch block and call
entirely (including the import and await backfillEnvelopeOperationLogs(driver))
if the migration isn’t needed yet—ensure the symbol name
backfillEnvelopeOperationLogs and the driver argument remain consistent with the
current code when you implement or remove the call.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/core/protocol/graphql-server.ts Outdated
Comment threadinfrastructure/evault-core/src/e2e/evault-core.e2e.spec.ts
Comment threadinfrastructure/evault-core/src/index.ts
@coodoscoodos changed the title feat: logseat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodoscoodos changed the title eat: implement envelope operation logging with cursor paginationfeat: implement envelope operation logging with cursor paginationFeb 4, 2026
@coodos
coodos merged commit 570a770 into mainFeb 4, 2026
5 of 6 checks passed
@coodos
coodos deleted the feat/logs-endpoint branch February 4, 2026 08:11
This was referenced Feb 4, 2026
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

2 participants

@coodos@sosweetham