Skip to content

Fix/quota store bootstrap#562

Merged
ginccc merged 5 commits into
mainfrom
fix/quota-store-bootstrap
Jun 23, 2026
Merged

Fix/quota store bootstrap#562
ginccc merged 5 commits into
mainfrom
fix/quota-store-bootstrap

Conversation

@ginccc

@ginccc ginccc commented Jun 22, 2026

Copy link
Copy Markdown
Member

Summary

This pull request introduces dependency updates and improves tenant quota bootstrapping for both MongoDB and Postgres implementations. The main focus is on ensuring that a default tenant quota is created automatically if none exists, bringing parity with the in-memory implementation. It also adds comprehensive tests to verify this behavior. Additionally, two dependencies have been safely bumped to their latest stable versions.

Dependency Updates:

  • Bumped quarkus-mcp-server.version from 1.12.1 to 1.13.0 in pom.xml, which adds Streamable HTTP transport support.
  • Bumped swagger-parser from 2.1.42 to 2.1.44 in pom.xml, including patch-level bug fixes.
  • Updated changelog to document these safe dependency bumps.

Tenant Quota Bootstrapping Enhancements:

  • MongoDB: The MongoTenantQuotaStore now injects default quota config values and bootstraps a default tenant quota if none exists, with a new test-only constructor for flexibility. [1] [2]
  • Postgres: The PostgresTenantQuotaStore similarly injects default quota config, bootstraps a default tenant quota if missing, and splits out internal helpers for quota access during bootstrap. [1] [2] [3] [4]

Testing Improvements:

  • Added dedicated tests for both Mongo and Postgres quota stores to verify that bootstrapping creates a default quota only when needed and does not overwrite existing quotas. [1] [2]

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • [] ✨ New feature (non-breaking change that adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📝 Documentation update
  • ♻️ Refactoring (no functional changes)
  • 🔧 Chore (dependency updates, CI changes, etc.)

Checklist

  • My code follows the project's code style
  • I have added tests that prove my fix/feature works
  • Existing tests pass locally (./mvnw clean verify -DskipITs)
  • I have updated documentation if needed
  • My commit messages follow conventional commits
  • I have not committed any secrets, API keys, or tokens
  • This PR has a clear, focused scope (one concern per PR)

Summary by CodeRabbit

Release Notes

  • New Features

    • Added automatic default tenant quota initialization on system startup.
  • Chores

    • Updated dependencies: Quarkus MCP Server and Swagger Parser.
  • Tests

    • Added tests for default tenant quota bootstrap initialization.

@ginccc ginccc requested a review from rolandpickl as a code owner June 22, 2026 13:50
@ginccc ginccc requested review from Copilot and removed request for rolandpickl June 22, 2026 13:50
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Both MongoTenantQuotaStore and PostgresTenantQuotaStore gain a CDI constructor injecting quota limit @ConfigProperty values, replacing the previous single public constructor. On startup each store atomically bootstraps a default tenant quota document/row without overwriting existing data. The Postgres store also extracts internal connection-reusing helpers for quota read/write. Bootstrap behavior is covered by new nested tests. Two Maven dependency versions are bumped.

Changes

Default Tenant Quota Bootstrapping

Layer / File(s) Summary
MongoTenantQuotaStore CDI constructor and bootstrap
src/main/java/ai/labs/eddi/engine/tenancy/MongoTenantQuotaStore.java, src/test/java/ai/labs/eddi/engine/tenancy/MongoTenantQuotaStoreTest.java
Replaces the old public constructor with a CDI constructor accepting @ConfigProperty quota limits that creates unique tenantId indexes and bootstraps the default tenant quota via findOneAndUpdate with $setOnInsert. A package-private constructor is retained for test use without bootstrap. A new nested Bootstrap test verifies findOneAndUpdate is invoked during construction.
PostgresTenantQuotaStore CDI constructor, bootstrap, and schema refactor
src/main/java/ai/labs/eddi/engine/tenancy/PostgresTenantQuotaStore.java, src/test/java/ai/labs/eddi/engine/tenancy/PostgresTenantQuotaStoreTest.java
Adds defaultTenantId and defaultQuota fields, replaces the CDI constructor to read @ConfigProperty values, adds a package-private test constructor, extends ensureSchema() to call bootstrapDefaultQuota (INSERT ... ON CONFLICT DO NOTHING), and refactors getQuota/setQuota to delegate to getQuotaInternal/setQuotaInternal connection-reusing helpers. A new nested Bootstrap test asserts CREATE TABLE executes twice and the bootstrap insert runs at least once.

Dependency Bumps

Layer / File(s) Summary
Dependency version bumps and changelog entry
pom.xml, docs/changelog.md
quarkus-mcp-server.version updated from 1.12.1 to 1.13.0 and swagger-parser from 2.1.42 to 2.1.44 in pom.xml; changelog records both bumps under 2026-06-19.

Sequence Diagram(s)

sequenceDiagram
    rect rgba(70, 130, 180, 0.5)
        note right of CDI: MongoTenantQuotaStore startup
        CDI->>MongoTenantQuotaStore: new(database, defaultTenantId, quota config props)
        MongoTenantQuotaStore->>MongoDatabase: getCollection("tenant_quotas")
        MongoTenantQuotaStore->>MongoDatabase: getCollection("tenant_usage")
        MongoTenantQuotaStore->>MongoDatabase: createIndex(tenantId, unique) × 2
        MongoTenantQuotaStore->>MongoDatabase: findOneAndUpdate(filter, $setOnInsert, upsert=true)
        MongoDatabase-->>MongoTenantQuotaStore: null
    end
    rect rgba(60, 179, 113, 0.5)
        note right of CDI: PostgresTenantQuotaStore startup
        CDI->>PostgresTenantQuotaStore: new(dataSourceInstance, defaultTenantId, quota config props)
        note over PostgresTenantQuotaStore: deferred until first getQuota call
        PostgresTenantQuotaStore->>DataSource: getConnection()
        PostgresTenantQuotaStore->>PostgreSQL: CREATE TABLE IF NOT EXISTS tenant_quotas
        PostgresTenantQuotaStore->>PostgreSQL: CREATE TABLE IF NOT EXISTS tenant_usage
        PostgresTenantQuotaStore->>PostgreSQL: INSERT INTO tenant_quotas ON CONFLICT DO NOTHING
        PostgresTenantQuotaStore->>PostgreSQL: SELECT * FROM tenant_quotas WHERE tenantId=?
        PostgreSQL-->>PostgresTenantQuotaStore: ResultSet
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • labsai/EDDI#494: Introduces the MongoTenantQuotaStore/PostgresTenantQuotaStore implementations that this PR extends with CDI-configured bootstrapping and constructor refactoring.

Suggested reviewers

  • rolandpickl

Poem

🐇 Hop, hop, the defaults are set,
No tenant left without a quota yet!
Mongo upserts with $setOnInsert flair,
Postgres says ON CONFLICT—no duplicate dare.
Dependencies bumped, the compile runs clean,
The cleverest bootstrap a bunny has seen! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix/quota store bootstrap' directly addresses the primary objective of the pull request: implementing default tenant quota bootstrapping for MongoDB and Postgres quota stores.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/quota-store-bootstrap

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.

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 2 package(s) with unknown licenses.
See the Details below.

License Issues

pom.xml

PackageVersionLicenseIssue Type
io.quarkiverse.mcp:quarkus-mcp-server-http1.13.0NullUnknown License
io.swagger.parser.v3:swagger-parser2.1.44NullUnknown License
Denied Licenses: GPL-3.0, AGPL-3.0

OpenSSF Scorecard

PackageVersionScoreDetails
maven/io.quarkiverse.mcp:quarkus-mcp-server-http 1.13.0 UnknownUnknown
maven/io.swagger.parser.v3:swagger-parser 2.1.44 🟢 6.2
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review🟢 8Found 10/12 approved changesets -- score normalized to 8
Binary-Artifacts🟢 10no binaries found in the repo
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
Signed-Releases⚠️ -1no releases found
Security-Policy⚠️ 0security policy file not detected
Packaging🟢 10packaging workflow detected
SAST🟢 10SAST tool is run on all commits

Scanned Files

  • pom.xml

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 updates a couple of dependencies and adds “default tenant quota” bootstrapping so MongoDB and PostgreSQL quota stores auto-create a default quota when none exists (matching the in-memory store), with accompanying unit tests.

Changes:

  • Bumped quarkus-mcp-server and swagger-parser versions in pom.xml and documented it in the changelog.
  • Added default-tenant quota bootstrapping to MongoTenantQuotaStore and PostgresTenantQuotaStore using injected config defaults.
  • Added unit tests to validate bootstrapping behavior (create when missing; don’t overwrite when present).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/main/java/ai/labs/eddi/engine/tenancy/PostgresTenantQuotaStore.java Adds config-driven default quota bootstrap during lazy schema initialization.
src/main/java/ai/labs/eddi/engine/tenancy/MongoTenantQuotaStore.java Adds config-driven default quota bootstrap during store construction.
src/test/java/ai/labs/eddi/engine/tenancy/PostgresTenantQuotaStoreTest.java Adds bootstrap-focused tests for the Postgres store.
src/test/java/ai/labs/eddi/engine/tenancy/MongoTenantQuotaStoreTest.java Adds bootstrap-focused tests for the Mongo store.
pom.xml Dependency version bumps for MCP server + swagger parser.
docs/changelog.md Documents dependency bumps.

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

Comment on lines +72 to +79
// Bootstrap default tenant quota if none exists (parity with
// InMemoryTenantQuotaStore)
if (getQuota(defaultTenantId) == null) {
var defaultQuota = new TenantQuota(defaultTenantId, maxConvPerDay, maxAgents, maxApiCalls, maxCost, enabled);
setQuota(defaultQuota);
LOGGER.infof("Bootstrapped default tenant quota: tenantId=%s, enabled=%s, maxConv=%d, maxAgents=%d, maxApi=%d, maxCost=%.2f",
defaultTenantId, enabled, maxConvPerDay, maxAgents, maxApiCalls, maxCost);
}
…ove schemaInitialized after bootstrap, remove unused vars

@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

🧹 Nitpick comments (2)
src/test/java/ai/labs/eddi/engine/tenancy/PostgresTenantQuotaStoreTest.java (1)

705-707: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Assert bootstrap SQL contract, not only invocation count.

executeUpdate() being called doesn’t prove the no-overwrite path is preserved. Capture prepared SQL and assert it includes ON CONFLICT (tenant_id) DO NOTHING.

Suggested assertion upgrade
+import org.mockito.ArgumentCaptor;
@@
         void bootstrapsAtomically() throws Exception {
@@
             // CREATE TABLE x2 + bootstrap INSERT + getQuota SELECT
             verify(statement, times(2)).execute(anyString());
             verify(preparedStatement, atLeastOnce()).executeUpdate();
+            ArgumentCaptor<String> sqlCaptor = ArgumentCaptor.forClass(String.class);
+            verify(connection, atLeastOnce()).prepareStatement(sqlCaptor.capture());
+            assertTrue(sqlCaptor.getAllValues().stream()
+                    .anyMatch(sql -> sql.contains("ON CONFLICT (tenant_id) DO NOTHING")));
         }
🤖 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 `@src/test/java/ai/labs/eddi/engine/tenancy/PostgresTenantQuotaStoreTest.java`
around lines 705 - 707, The test currently only verifies that executeUpdate() is
called on the preparedStatement, but does not validate the actual SQL being
executed. To properly assert that the no-overwrite path is preserved, capture
the SQL string that was passed to the preparedStatement during execution and add
an assertion that verifies the captured SQL contains the clause `ON CONFLICT
(tenant_id) DO NOTHING`. This ensures the bootstrap operation properly handles
duplicate inserts rather than just checking invocation count.
src/test/java/ai/labs/eddi/engine/tenancy/MongoTenantQuotaStoreTest.java (1)

542-550: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Strengthen bootstrap verification to assert atomic upsert semantics.

This test currently proves only that findOneAndUpdate was called. It won’t catch regressions where upsert(true) is removed. Capture FindOneAndUpdateOptions and assert isUpsert().

Suggested test tightening
+import org.mockito.ArgumentCaptor;
@@
         void bootstrapsAtomically() {
@@
-            verify(quotasCollection, atLeastOnce()).findOneAndUpdate(
-                    any(Bson.class), any(Bson.class), any(FindOneAndUpdateOptions.class));
+            ArgumentCaptor<FindOneAndUpdateOptions> optionsCaptor =
+                    ArgumentCaptor.forClass(FindOneAndUpdateOptions.class);
+            verify(quotasCollection, atLeastOnce()).findOneAndUpdate(
+                    any(Bson.class), any(Bson.class), optionsCaptor.capture());
+            assertTrue(optionsCaptor.getValue().isUpsert());
         }
🤖 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 `@src/test/java/ai/labs/eddi/engine/tenancy/MongoTenantQuotaStoreTest.java`
around lines 542 - 550, The test for MongoTenantQuotaStore bootstrap
initialization currently only verifies that findOneAndUpdate was called, but
does not validate that the upsert option is actually enabled. To strengthen this
test, use an ArgumentCaptor to capture the FindOneAndUpdateOptions argument
passed to the findOneAndUpdate method call, then assert that isUpsert() returns
true on the captured options object. This will ensure the test catches any
regressions where the upsert(true) setting is accidentally removed from the
bootstrap logic.
🤖 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 `@docs/changelog.md`:
- Around line 7-19: The changelog entry for quarkus-mcp-server version bump
incorrectly describes the feature as adding Streamable HTTP transport support
when it actually added lazy SSE initialization for Streamable HTTP. Update the
description in the quarkus-mcp-server.version line to accurately state that
version 1.13.0 adds lazy SSE initialization for Streamable HTTP rather than
claiming it adds the Streamable HTTP transport itself, since that transport
already existed in prior versions.

---

Nitpick comments:
In `@src/test/java/ai/labs/eddi/engine/tenancy/MongoTenantQuotaStoreTest.java`:
- Around line 542-550: The test for MongoTenantQuotaStore bootstrap
initialization currently only verifies that findOneAndUpdate was called, but
does not validate that the upsert option is actually enabled. To strengthen this
test, use an ArgumentCaptor to capture the FindOneAndUpdateOptions argument
passed to the findOneAndUpdate method call, then assert that isUpsert() returns
true on the captured options object. This will ensure the test catches any
regressions where the upsert(true) setting is accidentally removed from the
bootstrap logic.

In `@src/test/java/ai/labs/eddi/engine/tenancy/PostgresTenantQuotaStoreTest.java`:
- Around line 705-707: The test currently only verifies that executeUpdate() is
called on the preparedStatement, but does not validate the actual SQL being
executed. To properly assert that the no-overwrite path is preserved, capture
the SQL string that was passed to the preparedStatement during execution and add
an assertion that verifies the captured SQL contains the clause `ON CONFLICT
(tenant_id) DO NOTHING`. This ensures the bootstrap operation properly handles
duplicate inserts rather than just checking invocation count.
🪄 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

Run ID: ee22b98f-41e1-4c9b-a488-f511f45bae9a

📥 Commits

Reviewing files that changed from the base of the PR and between bd1b859 and 217b8fd.

📒 Files selected for processing (6)
  • docs/changelog.md
  • pom.xml
  • src/main/java/ai/labs/eddi/engine/tenancy/MongoTenantQuotaStore.java
  • src/main/java/ai/labs/eddi/engine/tenancy/PostgresTenantQuotaStore.java
  • src/test/java/ai/labs/eddi/engine/tenancy/MongoTenantQuotaStoreTest.java
  • src/test/java/ai/labs/eddi/engine/tenancy/PostgresTenantQuotaStoreTest.java

Comment thread docs/changelog.md
@ginccc ginccc merged commit cbb9c53 into main Jun 23, 2026
23 checks passed
@ginccc ginccc deleted the fix/quota-store-bootstrap branch June 23, 2026 13:02
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.

3 participants