Skip to content

feat(files): persist + expose indexation timestamp (files.created_at) - #529

Merged
Ahmath-Gadji merged 4 commits into
refactor/hexagonalfrom
fix/files-created-at
Jun 22, 2026
Merged

feat(files): persist + expose indexation timestamp (files.created_at)#529
Ahmath-Gadji merged 4 commits into
refactor/hexagonalfrom
fix/files-created-at

Conversation

@andyne13

@andyne13 andyne13 commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Problem

The admin UI documents list has an "Indexed" column, but it's always empty. The list is built from the Postgres files catalog (SELECT * FROM files_row_to_dict), and that table has no timestamp column — the index time exists only in the Milvus chunk metadata (which is why the file detail view shows created_at/indexed_at but the list can't).

Fix

  • Add a files.created_at column — DateTime(timezone=True), server_default now(), NOT NULL — to the model (schema.py).
  • Surface it in _row_to_dict (placed after the **metadata spread so the column value always wins).
  • Idempotent Alembic migration (column_exists guard, both directions), consistent with the repo's create_all-then-migrate policy.

The file INSERT doesn't list created_at, so the server default sets it at insert time = the indexation time. No UI change needed — the existing "Indexed" column reads indexed_at ?? created_at.

Caveat

Existing files have no recorded index time, so the server_default backfills them to the migration run time; newly indexed files get their true insert time.

Tests

Persistence + partition-service unit suites green (66 passed); ruff clean. Both _row_to_dict callers use SELECT *, so the new column is always present.

Summary by CodeRabbit

  • New Features

    • Added tracking for an indexing timestamp across document catalog writes and vector-store chunk upserts, with the ability to pin it to a caller-provided time (otherwise it uses the current time).
  • Chores

    • Added a database migration to introduce a new non-null indexed_at column with a default for existing rows.
    • Updated unit test doubles and assertions to include the new timestamp parameter in indexing flows.

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

An error occurred during the review process. Please try again later.

📝 Walkthrough

Walkthrough

Adds an indexed_at timezone-aware timestamp column to the files table via schema definition and an idempotent Alembic migration. A single timestamp per file is computed in IndexerWorker.process_file and propagated through the store pipeline stage into MilvusVectorStore.upsert and through _write_catalog_record into both add_file_to_partition and update_file_in_partition in PgDocumentRepository.

Changes

indexed_at Timestamp Propagation

Layer / File(s) Summary
Schema definition and Alembic migration
openrag/services/persistence/schema.py, openrag/services/persistence/migrations/alembic/versions/b7c1d2e3f4a5_add_files_indexed_at.py
Adds indexed_at as a non-nullable, timezone-aware DateTime column with server_default now() to the SQLAlchemy files table and an idempotent migration that backfills existing rows and supports downgrade.
VectorStore abstract interface
openrag/core/vector_stores/vector_store.py
Adds a keyword-only indexed_at: datetime | None = None parameter to the VectorStore.upsert abstract method, with a TYPE_CHECKING-guarded import and pinning semantics documented in the docstring.
Document repository: insert, update, and row serialization
openrag/services/persistence/document_repo.py
Extends add_file_to_partition and update_file_in_partition to accept an optional indexed_at, conditionally including it in the SQL only when non-None. Updates _row_to_dict to read and ISO-format indexed_at from the row, overriding any same-named metadata key.
Milvus upsert timestamp pinning
openrag/services/storage/milvus_store.py
Implements the indexed_at keyword argument in MilvusVectorStore.upsert, using the caller-provided value when non-None and falling back to datetime.now(UTC) otherwise.
Indexer worker and store stage orchestration
openrag/services/workers/indexer_actor.py, openrag/services/workers/stages/store.py
IndexerWorker.process_file computes a single indexed_at timestamp per file, injects it into the pipeline row, and passes it to _write_catalog_record. The store stage reads indexed_at from the row and threads it into the vector store upsert call.
Test doubles and indexer worker assertions
tests/unit/conftest.py, tests/unit/services/workers/stages/test_pipeline_stages.py, tests/unit/services/workers/test_batch_ingest.py, tests/unit/services/workers/test_indexer_worker.py, tests/unit/services/workers/test_pipeline_builder.py
Updates all fake/mock upsert stubs to accept indexed_at. Extends indexer worker tests to record the timestamp in the fake's call tuple and assert the same datetime instance is shared between the vector-store and catalog-repository calls.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 A timestamp was born, a single tick in time,
Passed through the pipeline, neat and sublime.
Milvus and Postgres now share the same clock,
No drift between catalog and vector block.
The rabbit hops fast, but leaves a clear trace —
indexed_at stamped with precision and grace! 🕐

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title claims to add a 'created_at' column, but the actual implementation adds an 'indexed_at' column as documented in the objectives and confirmed throughout the code changes. Update the PR title to 'feat(files): persist + expose indexation timestamp (files.indexed_at)' to accurately reflect the implementation that adds 'indexed_at', not 'created_at'.
Docstring Coverage ⚠️ Warning Docstring coverage is 40.74% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/files-created-at

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.

Comment thread openrag/services/persistence/document_repo.py Outdated

@Ahmath-Gadji Ahmath-Gadji left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Request: expose the indexation timestamp as indexed_at, not created_at

Thanks for tracking down why the "Indexed" column was empty — the diagnosis and the idempotent migration are spot-on. One blocking concern with the key name, though.

created_at is a reserved, client-supplied temporal field, not a free key we can repurpose. Per the API docs (API.mdx#L93-L102):

created_at: ISO 8601 format date of when the file was created
created_at is provided by the client in the metadata of the file during upload.

It's the user's document date (used for temporal-aware search/filtering), not the system's insert time. Placing the new column after the **metadata spread in _row_to_dict (openrag/services/persistence/document_repo.py:562) silently shadows that client value with the indexation time in the file-listing surface.

The two concepts should stay separate. Please expose the indexation timestamp as indexed_at instead:

  • It's already the codebase's intended key for this — the UI reads file.indexed_at ?? file.created_at (extern/indexer-ui/src/routes/indexer/partition/[partition]/+page.svelte:252,298), so indexed_at fills the "Indexed" column directly.
  • It leaves the reserved created_at (client temporal field) intact, so created_at sorting (+page.svelte:70) and temporal filtering keep working on the document date.

Concretely: rename the new column files.created_atfiles.indexed_at across the migration, schema.py, and the _row_to_dict key. The rest of the change (server default, idempotent guard, INSERTs relying on the default) carries over unchanged.

Everything else in the PR looks good and CI is green — just this naming.

@Ahmath-Gadji Ahmath-Gadji left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Requested change implemented: the indexation timestamp is now indexed_at (commit 9ee5c5a), with a follow-up so Milvus chunks and the files row share one timestamp (commit 0f0c925). created_at stays reserved for the client temporal field. CI re-running.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/unit/services/workers/test_indexer_worker.py (1)

267-267: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Assert timezone awareness explicitly for indexed_at.

Current checks only validate datetime type (and equality once). A naive datetime would still pass, which weakens protection of the timezone-aware timestamp contract.

Proposed test hardening
-    assert isinstance(add_call.pop("indexed_at"), datetime)
+    add_indexed_at = add_call.pop("indexed_at")
+    assert isinstance(add_indexed_at, datetime)
+    assert add_indexed_at.tzinfo is not None and add_indexed_at.utcoffset() is not None
@@
     store_indexed_at = store.calls[0][2]
     catalog_indexed_at = repo.add_calls[0]["indexed_at"]
     assert isinstance(store_indexed_at, datetime)
+    assert store_indexed_at.tzinfo is not None and store_indexed_at.utcoffset() is not None
+    assert catalog_indexed_at.tzinfo is not None and catalog_indexed_at.utcoffset() is not None
     # The store and the catalog must receive the very same timestamp object/value.
     assert store_indexed_at == catalog_indexed_at
@@
-    assert isinstance(update_call.pop("indexed_at"), datetime)
+    update_indexed_at = update_call.pop("indexed_at")
+    assert isinstance(update_indexed_at, datetime)
+    assert update_indexed_at.tzinfo is not None and update_indexed_at.utcoffset() is not None

Also applies to: 299-301, 353-353

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

In `@tests/unit/services/workers/test_indexer_worker.py` at line 267, The
assertion for indexed_at at line 267 only validates that it is a datetime
instance, but does not check for timezone awareness. A naive datetime without
tzinfo would still pass this check, weakening the validation of the
timezone-aware timestamp contract. Add an explicit assertion to verify that the
indexed_at datetime object is timezone-aware by checking that its tzinfo
attribute is not None. Apply the same fix to the similar assertions at lines
299-301 and 353 as indicated in the comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/unit/services/workers/test_indexer_worker.py`:
- Line 267: The assertion for indexed_at at line 267 only validates that it is a
datetime instance, but does not check for timezone awareness. A naive datetime
without tzinfo would still pass this check, weakening the validation of the
timezone-aware timestamp contract. Add an explicit assertion to verify that the
indexed_at datetime object is timezone-aware by checking that its tzinfo
attribute is not None. Apply the same fix to the similar assertions at lines
299-301 and 353 as indicated in the comment.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 347122dd-86c3-40bb-ab43-c0400c1b1734

📥 Commits

Reviewing files that changed from the base of the PR and between dfec225 and 0f0c925.

📒 Files selected for processing (12)
  • openrag/core/vector_stores/vector_store.py
  • openrag/services/persistence/document_repo.py
  • openrag/services/persistence/migrations/alembic/versions/b7c1d2e3f4a5_add_files_indexed_at.py
  • openrag/services/persistence/schema.py
  • openrag/services/storage/milvus_store.py
  • openrag/services/workers/indexer_actor.py
  • openrag/services/workers/stages/store.py
  • tests/unit/conftest.py
  • tests/unit/services/workers/stages/test_pipeline_stages.py
  • tests/unit/services/workers/test_batch_ingest.py
  • tests/unit/services/workers/test_indexer_worker.py
  • tests/unit/services/workers/test_pipeline_builder.py
✅ Files skipped from review due to trivial changes (2)
  • openrag/services/persistence/migrations/alembic/versions/b7c1d2e3f4a5_add_files_indexed_at.py
  • openrag/services/persistence/schema.py

andyne13 and others added 2 commits June 22, 2026 12:45
The documents list reads from the Postgres files catalog, which had no
timestamp column, so the admin UI "Indexed" column was always empty — the
index time existed only in Milvus chunk metadata (shown in the file detail).

Add a files.created_at column (timezone-aware, server_default now()), surface
it in the file-listing dict (_row_to_dict, placed after the metadata spread so
the column wins), and add an idempotent migration. Existing rows backfill to
the migration run time via the server default; newly indexed files get their
true insert time. The admin UI already renders this column.
created_at is a reserved, client-supplied temporal field (provided in
file_metadata at upload time for time-based filtering), so the indexation
timestamp must not reuse that key. Rename the new files column, its
migration, and the _row_to_dict surface from created_at to indexed_at.

This matches the existing chunk-level indexed_at field and the admin UI,
which reads `indexed_at ?? created_at`, so the document list's Indexed
column populates while the client created_at stays available for filtering.
@Ahmath-Gadji
Ahmath-Gadji force-pushed the fix/files-created-at branch from 0f0c925 to 4f5c4ad Compare June 22, 2026 12:52
…s row

The Milvus upsert and the Postgres catalog write each generated their own
now(), so a file's chunk indexed_at and its files.indexed_at could drift.

Mint a single timestamp in process_file and thread it to both sinks: the
store stage forwards it to VectorStore.upsert (stamped on every chunk) and
_write_catalog_record passes it to the files INSERT/UPDATE. Both arguments
default to None, falling back to now()/the server default, so existing
callers (direct upsert, copy/restore, create_document) are unaffected.
Re-index (replace) refreshes indexed_at to match the re-upserted chunks.
…heads

Rebasing onto refactor/hexagonal brought in the topic_tags migration
(b7c8d9e0f1a2), which also descends from 06dd2101ea3a. Two siblings off the
same parent give Alembic multiple heads, so `alembic upgrade head` fails at
startup and the ServiceContainer never initializes (every request 500s).

Re-parent indexed_at (b7c1d2e3f4a5) onto b7c8d9e0f1a2 for a single linear head.
@Ahmath-Gadji
Ahmath-Gadji force-pushed the fix/files-created-at branch from 4f5c4ad to 8a34772 Compare June 22, 2026 13:20
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/linagora/openrag/issues/comments/4752913302","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- review_stack_entry_start -->\n\n[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/linagora/openrag/pull/529?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)\n\n<!-- review_stack_entry_end -->\n<!-- This is an auto-generated comment: review in progress by coderabbit.ai -->\n\n> [!NOTE]\n> Currently processing new changes in this PR. This may take a few minutes, please wait...\n> \n> <details>\n> <summary>⚙️ Run configuration</summary>\n> \n> **Configuration used**: Path: .coderabbit.yaml\n> \n> **Review profile**: CHILL\n> \n> **Plan**: Pro\n> \n> **Run ID**: `ad2582f5-0d12-42df-8f6c-a1a52d61d463`\n> \n> </details>\n> \n> <details>\n> <summary>📥 Commits</summary>\n> \n> Reviewing files that changed from the base of the PR and between 4f5c4ad65af68ccfa66bd3607b25cd86c50c1e63 and 8a3477278709b4110dc09c0bb80ce607f4644798.\n> \n> </details>\n> \n> <details>\n> <summary>📒 Files selected for processing (11)</summary>\n> \n> * `openrag/core/vector_stores/vector_store.py`\n> * `openrag/services/persistence/document_repo.py`\n> * `openrag/services/persistence/migrations/alembic/versions/b7c1d2e3f4a5_add_files_indexed_at.py`\n> * `openrag/services/storage/milvus_store.py`\n> * `openrag/services/workers/indexer_actor.py`\n> * `openrag/services/workers/stages/store.py`\n> * `tests/unit/conftest.py`\n> * `tests/unit/services/workers/stages/test_pipeline_stages.py`\n> * `tests/unit/services/workers/test_batch_ingest.py`\n> * `tests/unit/services/workers/test_indexer_worker.py`\n> * `tests/unit/services/workers/test_pipeline_builder.py`\n> \n> </details>\n> \n> ```ascii\n>  ________________________\n> < GLaDOS? I can fix her! >\n>  ------------------------\n>   \\\n>    \\   (\\__/)\n>        (•ㅅ•)\n>        /   づ\n> ```\n\n<!-- end of auto-generated comment: review in progress by coderabbit.ai -->\n\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nAdds an `indexed_at` timezone-aware timestamp column to the `files` table via schema definition and an idempotent Alembic migration. A single timestamp per file is computed in `IndexerWorker.process_file` and propagated through the store pipeline stage into `MilvusVectorStore.upsert` and through `_write_catalog_record` into both `add_file_to_partition` and `update_file_in_partition` in `PgDocumentRepository`.\n\n## Changes\n\n**indexed_at Timestamp Propagation**\n\n| Layer / File(s) | Summary |\n|---|---|\n| **Schema definition and Alembic migration** <br> `openrag/services/persistence/schema.py`, `openrag/services/persistence/migrations/alembic/versions/b7c1d2e3f4a5_add_files_indexed_at.py` | Adds `indexed_at` as a non-nullable, timezone-aware `DateTime` column with `server_default now()` to the SQLAlchemy `files` table and an idempotent migration that backfills existing rows and supports downgrade. |\n| **VectorStore abstract interface** <br> `openrag/core/vector_stores/vector_store.py` | Adds a keyword-only `indexed_at: datetime \\| None = None` parameter to the `VectorStore.upsert` abstract method, with a `TYPE_CHECKING`-guarded import and pinning semantics documented in the docstring. |\n| **Document repository: insert, update, and row serialization** <br> `openrag/services/persistence/document_repo.py` | Extends `add_file_to_partition` and `update_file_in_partition` to accept an optional `indexed_at`, conditionally including it in the SQL only when non-`None`. Updates `_row_to_dict` to read and ISO-format `indexed_at` from the row, overriding any same-named metadata key. |\n| **Milvus upsert timestamp pinning** <br> `openrag/services/storage/milvus_store.py` | Implements the `indexed_at` keyword argument in `MilvusVectorStore.upsert`, using the caller-provided value when non-`None` and falling back to `datetime.now(UTC)` otherwise. |\n| **Indexer worker and store stage orchestration** <br> `openrag/services/workers/indexer_actor.py`, `openrag/services/workers/stages/store.py` | `IndexerWorker.process_file` computes a single `indexed_at` timestamp per file, injects it into the pipeline row, and passes it to `_write_catalog_record`. The store stage reads `indexed_at` from the row and threads it into the vector store upsert call. |\n| **Test doubles and indexer worker assertions** <br> `tests/unit/conftest.py`, `tests/unit/services/workers/stages/test_pipeline_stages.py`, `tests/unit/services/workers/test_batch_ingest.py`, `tests/unit/services/workers/test_indexer_worker.py`, `tests/unit/services/workers/test_pipeline_builder.py` | Updates all fake/mock `upsert` stubs to accept `indexed_at`. Extends indexer worker tests to record the timestamp in the fake's call tuple and assert the same `datetime` instance is shared between the vector-store and catalog-repository calls. |\n\n## Estimated code review effort\n\n🎯 3 (Moderate) | ⏱️ ~25 minutes\n\n## Poem\n\n> 🐇 A timestamp was born, a single tick in time,\n> Passed through the pipeline, neat and sublime.\n> Milvus and Postgres now share the same clock,\n> No drift between catalog and vector block.\n> The rabbit hops fast, but leaves a clear trace —\n> `indexed_at` stamped with precision and grace! 🕐\n\n</details>\n\n<!-- walkthrough_end -->\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 3 | ❌ 2</summary>\n\n### ❌ Failed checks (2 warnings)\n\n|     Check name     | Status     | Explanation                                                                                                                                                                            | Resolution                                                                                                                                                                        |\n| :----------------: | :--------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n|     Title check    | ⚠️ Warning | The PR title claims to add a 'created_at' column, but the actual implementation adds an 'indexed_at' column as documented in the objectives and confirmed throughout the code changes. | Update the PR title to 'feat(files): persist + expose indexation timestamp (files.indexed_at)' to accurately reflect the implementation that adds 'indexed_at', not 'created_at'. |\n| Docstring Coverage | ⚠️ Warning | Docstring coverage is 40.74% which is insufficient. The required threshold is 80.00%.                                                                                                  | Write docstrings for the functions missing them to satisfy the coverage threshold.                                                                                                |\n\n<details>\n<summary>✅ Passed checks (3 passed)</summary>\n\n|         Check name         | Status   | Explanation                                                              |\n| :------------------------: | :------- | :----------------------------------------------------------------------- |\n|      Description Check     | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled.              |\n|     Linked Issues check    | ✅ Passed | Check skipped because no linked issues were found for this pull request. |\n| Out of Scope Changes check | ✅ Passed | Check skipped because no linked issues were found for this pull request. |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing Touches</summary>\n\n<details>\n<summary>📝 Generate docstrings</summary>\n\n- [ ] <!-- {\"checkboxId\": \"7962f53c-55bc-4827-bfbf-6a18da830691\"} --> Create stacked PR\n- [ ] <!-- {\"checkboxId\": \"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98\"} --> Commit on current branch\n\n</details>\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Commit unit tests in branch `fix/files-created-at`\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=linagora/openrag&utm_content=529)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->"},"request":{"retryCount":3,"signal":{},"retries":3,"retryAfter":16}}}

@Ahmath-Gadji
Ahmath-Gadji merged commit 0751f4d into refactor/hexagonal Jun 22, 2026
6 checks passed
@Ahmath-Gadji
Ahmath-Gadji deleted the fix/files-created-at branch June 22, 2026 13:25
Ahmath-Gadji added a commit that referenced this pull request Jun 22, 2026
…eanup

Resolves the indexer_actor.py conflict between the parser refactor and #529:
keeps the async, file_id-required _load_document from the refactor and unions
in #529's shared indexed_at threading (process_file reads row['indexed_at']
after pipeline.run and passes it to _write_catalog_record, which forwards it to
both the add/update catalog writes). All other #529 changes (store stage,
vector_store, milvus_store, document_repo, schema, migration) apply cleanly.
@Ahmath-Gadji Ahmath-Gadji added the enhancement New feature or request label Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants