Skip to content

docs: add Javadoc to datastore core interfaces - #623

Merged
ginccc merged 3 commits into
labsai:mainfrom
Kayvan-Zahiri:docs/546-datastore-interface-javadoc
Jul 31, 2026
Merged

docs: add Javadoc to datastore core interfaces#623
ginccc merged 3 commits into
labsai:mainfrom
Kayvan-Zahiri:docs/546-datastore-interface-javadoc

Conversation

@Kayvan-Zahiri

@Kayvan-Zahiri Kayvan-Zahiri commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Fixes #546

Documents the seven interfaces listed in the issue. Six carried an @author-only Javadoc block — the case the issue calls out as needing replacement — and IResourceStorageFactory already had prose, so only its @author tag is removed.

Each one was written from the interface's own method set plus its implementation (ResourceFilter, PostgresResourceStorage, HistorizedResourceStore/AbstractResourceStore, DescriptorStore, DocumentBuilder, JsonSerialization), following the house style already set by IResourceStorageFactory.

Interface What the doc says
IResourceStore The versioned CRUD contract: id + integer version, update returns a new version rather than mutating, delete marks a version while leaving it readable via readIncludingDeleted, deleteAllPermanently is the only history-removing call. Also why IResourceId, the checked exceptions and ConfigurationUpdate are nested in the contract.
IResourceStorage The backend-facing half — raw revision persistence without the validation/interception IResourceStore layers on top, obtained through the factory rather than injected, and why MAX_RESULT_LIMIT/resolveLimit live here so backends can't drift.
IResourceFilter The query surface on top of id-addressed reads: how QueryFilters groups combine via ConnectingType, index/limit paging, and that it backs the REST list endpoints.
IDescriptorStore Metadata held separately from the configuration document, and that browsing reads descriptors instead of deserializing every document — plus why NO_LIMIT/DEFAULT_LIMIT exist.
IDocumentBuilder The mapping seam between database documents and model classes, so persistence code never hand-rolls it.
IJsonSerialization The shared wrapper so mapper settings are declared once rather than per call site.

Verification

./mvnw compile   →  BUILD SUCCESS

Every {@link} target was checked to resolve (members against the declaring interface, types against the source tree) — 20 references, none dangling.

Docs only, no behavior change, no @author tags left in the seven files.

One note on the sibling issues

While scoping this I checked #544 and #545 against main as well. Their state is mixed rather than open or done:

Worth trimming those file lists so the next contributor doesn't rewrite documentation that already exists — that appears to be what happened on #547, where the interfaces turned out to be done. Happy to take either of them next if useful.

Summary by CodeRabbit

  • Documentation
    • Clarified versioned resource store behavior, including revision reads, history writing, and how backend limit clamping works.
    • Expanded resource filtering documentation, including how groups are combined during listing/search (within-group AND/OR; groups joined with AND).
    • Improved guidance for store interception configuration, noting the current lack of runtime interceptor behavior.
    • Refined descriptor store, document-to-model mapping, and shared JSON serialization documentation.
    • No functional behavior or public interfaces changed.

Documents the six interfaces in the datastore package that carried an
@author-only Javadoc block, and removes the @author tags per CONTRIBUTING.

IResourceStore, IResourceStorage and IResourceFilter now state the
versioned CRUD contract explicitly: id plus integer version, update
returning a new version rather than mutating in place, delete marking a
version while leaving it readable through readIncludingDeleted, and
deleteAllPermanently as the only history-removing operation. The
storage/store split and the shared query-limit ceiling are named where a
caller would look for them.

IDescriptorStore, IDocumentBuilder and IJsonSerialization describe what
consumes them: descriptors back the UI's configuration listing without
deserializing each document, the document builder is the mapping seam
between storage and the models, and the serialization wrapper exists so
mapper settings are declared once.

IResourceStorageFactory already had prose Javadoc; only its @author tag
is removed.

Docs only, no behavior change.

Fixes labsai#546
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c12a9802-6dac-4ec5-81cf-95d007d6fc8a

📥 Commits

Reviewing files that changed from the base of the PR and between e19049c and 4b1239f.

📒 Files selected for processing (1)
  • src/main/java/ai/labs/eddi/datastore/IResourceStore.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/ai/labs/eddi/datastore/IResourceStore.java

📝 Walkthrough

Walkthrough

Expanded class-level Javadocs across datastore resource and serialization interfaces, documenting filtering, persistence, mutation annotations, paging, document mapping, and JSON serialization. Existing author tags were removed; no declarations or behavior changed.

Changes

Datastore Contracts

Layer / File(s) Summary
Resource storage and filtering contracts
src/main/java/ai/labs/eddi/datastore/IResourceFilter.java, IResourceStorage.java, IResourceStore.java
Documents query grouping, paging limits, backend persistence, and the current behavior of the ConfigurationUpdate interceptor binding.
Serialization and descriptor contracts
src/main/java/ai/labs/eddi/datastore/serialization/IDescriptorStore.java, IDocumentBuilder.java, IDsonSerialization.java
Documents descriptor metadata storage, paging constants, document/model conversion, and shared JSON mapping responsibilities.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related issues

  • #545: Updates class-level Javadocs for related datastore and configuration store interfaces, including removal of obsolete author tags.

Suggested reviewers: rolandpickl, ginccc

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the documentation-only Javadoc update for datastore core interfaces.
Linked Issues check ✅ Passed The changes match issue #546 by documenting the listed datastore interfaces, explaining IResourceStore versioning, and removing author tags.
Out of Scope Changes check ✅ Passed The diff stays within datastore Javadocs and related comments, with no unrelated code or API changes introduced.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot 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: 1

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

Inline comments:
In `@src/main/java/ai/labs/eddi/datastore/IResourceFilter.java`:
- Around line 13-16: Update the Javadoc in IResourceFilter to explicitly state
that groups of QueryFilters are combined with AND after each group applies its
own ConnectingType; clarify that group-level connectors do not control the outer
combination.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1fba3a6f-7fdf-410d-98e1-4e1a23e61073

📥 Commits

Reviewing files that changed from the base of the PR and between 5d8b5bc and f4bcf3f.

📒 Files selected for processing (6)
  • src/main/java/ai/labs/eddi/datastore/IResourceFilter.java
  • src/main/java/ai/labs/eddi/datastore/IResourceStorage.java
  • src/main/java/ai/labs/eddi/datastore/IResourceStore.java
  • src/main/java/ai/labs/eddi/datastore/serialization/IDescriptorStore.java
  • src/main/java/ai/labs/eddi/datastore/serialization/IDocumentBuilder.java
  • src/main/java/ai/labs/eddi/datastore/serialization/IJsonSerialization.java

Comment thread src/main/java/ai/labs/eddi/datastore/IResourceFilter.java Outdated
Review feedback on labsai#623. The previous wording said the groups "are then
combined" without saying how, which invites the reading that a group's
ConnectingType also governs the outer combination.

ResourceFilter.createQuery applies each group's ConnectingType via
Filters.and/Filters.or, then wraps the resulting group expressions in
Filters.and, so the outer join is always AND regardless of what the
individual groups use.
@Kayvan-Zahiri

Copy link
Copy Markdown
Contributor Author

Good catch, fixed in the latest push.

I checked it against ResourceFilter.createQuery before changing anything: each group's ConnectingType selects Filters.and/Filters.or for the filters inside that group, and the resulting group expressions are then wrapped in Filters.and(connectedFilters). So the outer join is always AND, and my original "the groups themselves are then combined" left exactly the ambiguity you flagged.

Worded it slightly more explicitly than the suggestion, since the misreading worth preventing is that a group's connector might govern the outer combination:

Filters inside a group combine under that group's ConnectingType (AND or OR); the groups themselves are always combined with AND, so a group's connector never affects how it joins the other groups.

./mvnw compile still passes.

Copilot AI 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.

Pull request overview

This PR addresses issue #546 by replacing @author-only class Javadocs with descriptive documentation across the datastore core abstraction interfaces, clarifying the responsibilities and contracts of the versioned CRUD store, storage backends, filtering/query surfaces, descriptor browsing, document mapping, and shared JSON serialization.

Changes:

  • Added/expanded class-level Javadoc for the seven datastore core interfaces called out in #546, removing @author-only blocks.
  • Documented key behavioral contracts (versioning, deletion/history semantics, paging/limit clamping, query filter grouping semantics) directly on the interfaces.
  • Kept IResourceStorageFactory’s existing prose and removed its @author tag.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/main/java/ai/labs/eddi/datastore/IResourceStore.java Documents the versioned CRUD contract and nested contract types/exceptions.
src/main/java/ai/labs/eddi/datastore/IResourceStorage.java Documents backend storage responsibilities and shared limit clamping.
src/main/java/ai/labs/eddi/datastore/IResourceFilter.java Documents filter-group semantics and paging behavior for list endpoints.
src/main/java/ai/labs/eddi/datastore/IResourceStorageFactory.java Preserves existing factory documentation while removing @author.
src/main/java/ai/labs/eddi/datastore/serialization/IDescriptorStore.java Documents descriptor browsing/paging semantics and limit conventions.
src/main/java/ai/labs/eddi/datastore/serialization/IDocumentBuilder.java Documents document↔model mapping responsibilities used by persistence.
src/main/java/ai/labs/eddi/datastore/serialization/IJsonSerialization.java Documents the shared JSON serialization/deserialization wrapper contract.

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

* Nested here because they belong to the contract rather than any one
* implementation: {@link IResourceId} (the id/version pair), the checked
* exceptions callers are expected to handle, and {@link ConfigurationUpdate},
* the interceptor binding that fires when a store mutates a configuration.
@Kayvan-Zahiri

Copy link
Copy Markdown
Contributor Author

The Secret Scanning failure on this PR isn't from the diff — it's the fork-secrets boundary, and it will hit every external contributor.

The job fails before scanning anything:

[labsai] is an organization. License key is required.
🛑 missing gitleaks license. Go grab one at gitleaks.io and store it as a GitHub Secret named GITLEAKS_LICENSE.

GITLEAKS_LICENSE is empty in the run's env dump. GitHub doesn't expose repository secrets to pull_request runs originating from a fork, so secrets.GITLEAKS_LICENSE resolves to "" for outside PRs, and gitleaks-action hard-fails on org-owned repos without a license.

Evidence across the last 14 PRs:

PR origin Secret Scanning
#623 (this one) fork failure
#610-#622 internal success ×13

Only fork PR, only failure. Everything else here is green — Build & Test, CodeQL, Trivy, Integration Tests, Preflight.

It matters more than one red check, because gitleaks is in the ship job's needs: list (ci.yml:419), so no external contribution can reach a green pipeline while the repo is recruiting through help wanted and good first issue.

Three options, all maintainer-side:

  1. Run the gitleaks CLI directly instead of the Action. The scanner itself is MIT-licensed and needs no key — only the Action wrapper requires one for orgs. Keeps fork coverage intact, which the other two lose.
  2. Skip the job for forks: if: github.event.pull_request.head.repo.full_name == github.repository. Honest and explicit, but leaves fork diffs unscanned on the PR (push-to-main still catches them).
  3. Add the GITLEAKS_LICENSE secret — still won't help fork PRs, since the secret isn't exposed to them at all.

Happy to send option 1 as its own PR if you'd like it, though it's a CI change rather than docs so I didn't want to bundle it in here.

No @interceptor implements the binding, so the annotation has no runtime
behaviour today. Say that it marks the mutating store methods and that
callers invalidate their own caches, instead of implying something fires.
@Kayvan-Zahiri

Copy link
Copy Markdown
Contributor Author

Good catch, fixed in 4b1239f.

I checked before changing it rather than taking the review at face value: no class in src/main/java is annotated @Interceptor (the single jakarta.interceptor.Interceptor import is DisabledAuthController using Interceptor.Priority.LIBRARY_AFTER, a priority constant), and there is no CDI observer for it either. All 13 non-declaration usages are the annotation sitting on store mutation methods. AGENTS.md says the same thing, which I should have followed.

New wording:

 * exceptions callers are expected to handle, and {@link ConfigurationUpdate},
 * which marks the store methods that mutate a stored configuration. It is
 * declared as an {@link InterceptorBinding}, but nothing implements that
 * interceptor today, so the annotation has no runtime behaviour: it documents
 * intent, and callers that need a cache refreshed invalidate it themselves.

I kept the "declared as an @InterceptorBinding but nothing implements it" part deliberately. Dropping it and calling it only a marker leaves the next reader to find @InterceptorBinding on line 35 and re-derive that nothing fires. The cache claim is the observed behaviour: RestPromptSnippetStore calls snippetService.invalidateCache() explicitly, and RestSecretStore does the same with secretResolver.invalidateCache(ref).

Unrelated to this PR, but the same claim exists elsewhere: CapabilityRegistryService line 33 says the registry is rebuilt on agent create/update/delete "via @ConfigurationUpdate observer events." There are no such observer events, so that comment describes a mechanism that doesn't run. It's outside #546's scope (datastore interfaces), so I left it alone rather than widen a docs PR. Happy to send it separately if you want it.

./mvnw compile passes and javadoc -Xdoclint:reference resolves every link in the file.

@ginccc

ginccc commented Jul 31, 2026

Copy link
Copy Markdown
Member

Thanks for the contribution, looks good to me!
Re fixing secret scan for forks) option 1 would be a good addition and a separate PR is the right approach

@ginccc
ginccc merged commit f929bf5 into labsai:main Jul 31, 2026
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: add Javadoc to datastore core interfaces

3 participants