Skip to content

Development#1263

Merged
GregJohnStewart merged 63 commits into
mainfrom
development
May 22, 2026
Merged

Development#1263
GregJohnStewart merged 63 commits into
mainfrom
development

Conversation

@GregJohnStewart
Copy link
Copy Markdown
Contributor

@GregJohnStewart GregJohnStewart commented May 16, 2026

Checklist:

  • Tested

Summary by CodeRabbit

  • New Features

    • Database indexes added for name fields to improve query performance
    • Startup DB initialization to prepare indexes and backfill mutexes
  • Changes

    • Stored items moved to a state-based model; persistence schema bumped to v5 (migration applied)
    • Mutex/configuration and locking enhanced with configurable identity, wait/timeout behavior and better concurrency handling
  • Removed Features

    • /media/runBy/{image} endpoint removed
    • Direct PUT endpoint for stored-item updates removed

Review Change Stack

…handler to mongo services to optionally handle adding objects. Used this to create mutex for items.
…n appliers beans instead of pojos to allow for metrics and similar
…core-api-add-item-mutex

Dev/1227 fr core api add item mutex
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

📝 Walkthrough

Walkthrough

A single large change: migrate Stored -> polymorphic StoredState, add StoredSchema upgrader, add mutex await/timeout and resource locking, add DB index/init hooks and MongoDbInit startup backfill, refactor transaction appliers to CDI/state checks, update client/UI callsites, and add many integration tests and version bumps.

Changes

Core State, Mutex, and Initialization

Layer / File(s) Summary
End-to-end state, mutex, and init changes
software/core/oqm-core-api/..., software/core/oqm-core-base-station/..., software/libs/core-api-lib-quarkus/..., software/plugins/storagotchi/...
Polymorphic StoredState replaces storageBlock; upgrader (StoredItemBumper5) migrates legacy docs. InstanceMutexService adds await/timeout, atomic lock updates, resource helper API, and exceptions. Mongo DB index/init hooks and MongoDbInit perform startup index creation and mutex backfill. Transaction appliers moved to CDI, inject services, and validate/operate on state (StoredInBlock) consistently. Client REST interface and UI templates updated to state usage. Large test additions and version bumps.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant AppliedTransactionService
  participant InstanceMutexService
  participant MongoDB
  Client->>AppliedTransactionService: apply(transaction)
  AppliedTransactionService->>InstanceMutexService: getResource(mutexId)
  InstanceMutexService-->>AppliedTransactionService: locked resource
  AppliedTransactionService->>MongoDB: perform mutations within session
  AppliedTransactionService->>InstanceMutexService: free(mutexId)
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Poem

Arrr, the stored state hoisted new and true,
Locks be timed, we queue the hearty crew,
At startup we mend each anchor and chart,
Transactions sail safe, no datum torn apart,
Shipshape and ready — onward, whole and true.

✨ 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 development

@github-actions
Copy link
Copy Markdown

@github-actions
Copy link
Copy Markdown

Code Coverage

There is no coverage information present for the Files changed

@github-actions
Copy link
Copy Markdown

Code Coverage

Overall Project 61.83% -1.2% 🍏
Files changed 70.21%

File Coverage
AttKeywordMainObject.java 100% 🍏
MutexNotRegisteredException.java 100% 🍏
StoredInBlock.java 100% 🍏
StoredStateType.java 100% 🍏
TransactionApplier.java 100% 🍏
CheckinOutTransactionApplier.java 100% 🍏
ItemWholeCheckout.java 100% 🍏
StoredSchemaUpgrader.java 100% 🍏
AppliedTransactionService.java 93.72% 🍏
CheckoutWholeTransactionApplier.java 92.75% 🍏
Stored.java 91.33% -0.21% 🍏
CheckoutAmountTransactionApplier.java 87% -2.5% 🍏
MongoObjectService.java 84.63% 🍏
InstanceMutexService.java 84.22% -10.82%
TransferAmountTransactionApplier.java 83.86% -3.51%
AddAmountTransactionApplier.java 83.66% -4.95% 🍏
SetAmountTransactionApplier.java 83.23% -2.99% 🍏
CheckinFullTransactionApplier.java 83.08% -5.64% 🍏
MongoDbInit.java 81.97% -18.03% 🍏
ItemCheckout.java 77.78% 🍏
AddWholeTransactionApplier.java 77.38% -16.67%
SubtractAmountTransactionApplier.java 74.71% -2.87%
TransferWholeTransactionApplier.java 72.22% -11.9%
StoredService.java 71.36% -9.14%
StoredSearch.java 63.73% -3.43% 🍏
StoredInItemEndpoints.java 57.29% -33.33%
ItemStatsService.java 51.31% -3.25%
MutexWaitTimeoutException.java 50% 🍏
CheckinPartTransactionApplier.java 50% 🍏
CheckinLossTransactionApplier.java 50% 🍏
InventoryItemService.java 43.25% 🍏
SubtractWholeTransactionApplier.java 12.5% 🍏
StoredEndpoints.java 5.33% 🍏
StoredItemBumper5.java 4.3% -95.7%
MutexWaitInterruptedException.java 0%

@github-actions
Copy link
Copy Markdown

Code Coverage

There is no coverage information present for the Files changed

@github-actions
Copy link
Copy Markdown

Code Coverage

Overall Project 61.82% -1.2% 🍏
Files changed 72.55%

File Coverage
AttKeywordMainObject.java 100% 🍏
MutexNotRegisteredException.java 100% 🍏
StoredInBlock.java 100% 🍏
StoredStateType.java 100% 🍏
TransactionApplier.java 100% 🍏
CheckinOutTransactionApplier.java 100% 🍏
ItemWholeCheckout.java 100% 🍏
StoredSchemaUpgrader.java 100% 🍏
LifecycleBean.java 97.5% 🍏
AppliedTransactionService.java 93.72% 🍏
CheckoutWholeTransactionApplier.java 92.75% 🍏
Stored.java 91.33% -0.21% 🍏
CheckoutAmountTransactionApplier.java 87% -2.5% 🍏
MongoService.java 85.94% 🍏
MongoDbInit.java 85.9% -14.1% 🍏
MongoObjectService.java 84.63% 🍏
TransferAmountTransactionApplier.java 83.86% -3.51%
AddAmountTransactionApplier.java 83.66% -4.95% 🍏
SetAmountTransactionApplier.java 83.23% -2.99% 🍏
CheckinFullTransactionApplier.java 83.08% -5.64% 🍏
InstanceMutexService.java 79.08% -10.82%
OqmDatabaseService.java 78.32% 🍏
ItemCheckout.java 77.78% 🍏
AddWholeTransactionApplier.java 77.38% -16.67%
SubtractAmountTransactionApplier.java 74.71% -2.87%
TransferWholeTransactionApplier.java 72.22% -11.9%
TopLevelMongoService.java 72.2% -0.36% 🍏
StoredService.java 71.36% -9.14%
MongoDbAwareService.java 68.34% -0.5% 🍏
StoredSearch.java 63.73% -3.43% 🍏
StoredInItemEndpoints.java 57.29% -33.33%
ItemStatsService.java 51.31% -3.25%
MutexWaitTimeoutException.java 50% 🍏
CheckinPartTransactionApplier.java 50% 🍏
CheckinLossTransactionApplier.java 50% 🍏
InventoryItemService.java 44.02% 🍏
StorageBlockService.java 33.55% 🍏
ItemListService.java 24.66% 🍏
SubtractWholeTransactionApplier.java 12.5% 🍏
StoredEndpoints.java 5.33% 🍏
StoredItemBumper5.java 4.3% -95.7%
MutexWaitInterruptedException.java 0%

@github-actions
Copy link
Copy Markdown

Code Coverage

There is no coverage information present for the Files changed

2 similar comments
@github-actions
Copy link
Copy Markdown

Code Coverage

There is no coverage information present for the Files changed

@github-actions
Copy link
Copy Markdown

Code Coverage

There is no coverage information present for the Files changed

@github-actions
Copy link
Copy Markdown

Code Coverage

Overall Project 62.13% -1.2% 🍏
Files changed 72.55%

File Coverage
AttKeywordMainObject.java 100% 🍏
MutexNotRegisteredException.java 100% 🍏
StoredInBlock.java 100% 🍏
StoredStateType.java 100% 🍏
TransactionApplier.java 100% 🍏
CheckinOutTransactionApplier.java 100% 🍏
ItemWholeCheckout.java 100% 🍏
StoredSchemaUpgrader.java 100% 🍏
LifecycleBean.java 97.5% 🍏
AppliedTransactionService.java 93.72% 🍏
CheckoutWholeTransactionApplier.java 92.75% 🍏
Stored.java 91.33% -0.21% 🍏
CheckoutAmountTransactionApplier.java 87% -2.5% 🍏
MongoService.java 85.94% 🍏
MongoDbInit.java 85.9% -14.1% 🍏
MongoObjectService.java 84.63% 🍏
InstanceMutexService.java 84.22% -10.82%
TransferAmountTransactionApplier.java 83.86% -3.51%
AddAmountTransactionApplier.java 83.66% -4.95% 🍏
SetAmountTransactionApplier.java 83.23% -2.99% 🍏
CheckinFullTransactionApplier.java 83.08% -5.64% 🍏
OqmDatabaseService.java 78.32% 🍏
ItemCheckout.java 77.78% 🍏
AddWholeTransactionApplier.java 77.38% -16.67%
SubtractAmountTransactionApplier.java 74.71% -2.87%
TransferWholeTransactionApplier.java 72.22% -11.9%
TopLevelMongoService.java 72.2% -0.36% 🍏
StoredService.java 71.36% -9.14%
MongoDbAwareService.java 68.34% -0.5% 🍏
StoredSearch.java 63.73% -3.43% 🍏
StoredInItemEndpoints.java 57.29% -33.33%
ItemStatsService.java 51.31% -3.25%
MutexWaitTimeoutException.java 50% 🍏
CheckinPartTransactionApplier.java 50% 🍏
CheckinLossTransactionApplier.java 50% 🍏
InventoryItemService.java 44.02% 🍏
StorageBlockService.java 38.54% 🍏
ItemListService.java 24.66% 🍏
SubtractWholeTransactionApplier.java 12.5% 🍏
StoredEndpoints.java 5.33% 🍏
StoredItemBumper5.java 4.3% -95.7%
MutexWaitInterruptedException.java 0%

@GregJohnStewart GregJohnStewart marked this pull request as ready for review May 21, 2026 14:53
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 19

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/AddWholeTransactionApplier.java (1)

44-60: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avast! Potential null on transaction.getToBlock() could pitch ye overboard with an NPE.

Two foul winds in this stretch:

  1. Lines 44-45: if stored.getState() is null and transaction.getToBlock() is also null, a StoredInBlock is built with a null storageBlock — leaving an unanchored stored in the hold.
  2. Line 58: transaction.getToBlock().equals(...) is called without any null check. If the transaction was submitted without a toBlock (and the caller supplied a state on stored), this throws NullPointerException instead of the intended IllegalArgumentException.

Recommend rejecting a null toBlock up front, or comparing in a null-safe way (e.g. Objects.equals(...)).

🪢 Suggested null-safety patch
+		if (transaction.getToBlock() == null) {
+			throw new IllegalArgumentException("No to block given for whole add.");
+		}
+
 		if(stored.getState() == null) {
 			stored.setState(StoredInBlock.builder().storageBlock(transaction.getToBlock()).build());
 		} else if(!stored.isState(StoredStateType.STORED)) {
 			throw new IllegalArgumentException("Cannot add whole stored that is not stored in a block.");
 		}
@@
-		if (!transaction.getToBlock().equals(((StoredInBlock)stored.getState()).getStorageBlock())) {
+		if (!transaction.getToBlock().equals(((StoredInBlock) stored.getState()).getStorageBlock())) {
 			throw new IllegalArgumentException("To Block given does not match block marked in stored.");
 		}
🧹 Nitpick comments (13)
software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/state/StoredInBlock.java (1)

4-4: 💤 Low value

Stowaway import! ApplicationScoped be aboard but never called to duty.

jakarta.enterprise.context.ApplicationScoped is imported but unused — this is a plain POJO, not a CDI bean. Toss it overboard.

🧹 Suggested fix
-import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.validation.constraints.NotNull;
software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/scheduled/MongoDbInit.java (1)

41-55: ⚡ Quick win

Steady the tiller — backfill be unbounded with nary an error rail.

A few concerns about ensureItemMutexesExist:

  1. No error handling per item/db. If a single instanceMutexService.register(...) call throws (e.g., mutex already exists in a state that rejects re-registration, or a transient DB hiccup mid-iteration), the entire startup fails. Consider wrapping each per-item registration in a try/catch and logging the failure so other items still get backfilled.
  2. Idempotency. The doc-comment says this "can be removed once all inventory items have mutexes" but the code unconditionally calls register on every startup. Confirm register is idempotent (or guard with a "registered?" check), else restarts may produce duplicate-registration errors or wasted work on large inventories.
  3. Observability. For large inventories, a count of items processed per DB would help operators distinguish "ran fast because empty" from "skipped silently".
♻️ Suggested per-item guard + counters
     private void ensureItemMutexesExist() {
         log.info("Ensuring inventory item mutexes exist.");

         for (DbCacheEntry curDb : this.oqmDatabaseService.getDatabases()) {
             log.info("Ensuring inventory item mutexes exist for database: {}", curDb.getDbName());
+            int registered = 0, failed = 0;
             this.inventoryItemService.iterator(curDb.getDbId().toHexString()).forEachRemaining((item) -> {
-                this.instanceMutexService.register(
-                    this.instanceMutexService.getMutexIdFor(curDb.getDbId().toHexString(), item)
-                );
+                try {
+                    this.instanceMutexService.register(
+                        this.instanceMutexService.getMutexIdFor(curDb.getDbId().toHexString(), item)
+                    );
+                } catch (Exception e) {
+                    log.warn("Failed registering mutex for item {} in db {}: {}", item.getId(), curDb.getDbName(), e.toString());
+                }
             });
-            log.info("DONE Ensuring inventory item mutexes exist for database: {}", curDb.getDbName());
+            log.info("DONE Ensuring inventory item mutexes exist for database: {}", curDb.getDbName());
         }

         log.info("DONE Ensuring inventory item mutexes exist.");
     }
software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoService.java (1)

117-122: 💤 Low value

Set sail to remove the no-op background(true)
In MongoService.setupIndexes, new IndexOptions().background(true) won’t steer anything on your current MongoDB waters: MongoDB 4.2+ ignores the background option for createIndex/createIndexes. Since you’re using mongo:7 in both dev services and tests, this is just extra rope—safe to drop (keep the same startup-fail behavior if an index build errors).

🛠️ Proposed cleanup
 	protected static void setupIndexes(MongoCollection<?> collection, List<Bson> indexes) {
-		IndexOptions options = new IndexOptions().background(true);
+		IndexOptions options = new IndexOptions();
 		for (Bson index : indexes) {
 			collection.createIndex(index, options);
 		}
 	}
software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/AppliedTransactionService.java (1)

47-66: 💤 Low value

Steady as she goes — registry build via CDI looks ship-shape.

The @All-injected applier list populated in @PostConstruct into applierTypeMap is sound for an @ApplicationScoped bean (single init, concurrent reads thereafter). One small caution from the crow's nest: if two TransactionApplier beans ever return the same TransactionType from getTransactionType(), the latter would silently overwrite the former in the map. A putIfAbsent with a thrown exception (or a startup-time duplicate check) would prevent a stowaway applier from quietly taking over.

🧭 Suggested guard against duplicate applier types
 	`@PostConstruct`
 	void setupAppliers() {
 		for (TransactionApplier<?> applier : this.transactionAppliers) {
-			this.applierTypeMap.put(applier.getTransactionType(), applier);
+			TransactionApplier<?> prev = this.applierTypeMap.putIfAbsent(applier.getTransactionType(), applier);
+			if (prev != null) {
+				throw new IllegalStateException(
+					"Duplicate TransactionApplier registered for type " + applier.getTransactionType()
+					+ ": " + prev.getClass().getName() + " and " + applier.getClass().getName()
+				);
+			}
 		}
 	}
software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/AddAmountTransactionApplier.java (1)

78-103: 💤 Low value

Two lookouts hollerin' the same warning — duplicate STORED state check.

The isState(StoredStateType.STORED) check on lines 80-82 is repeated almost verbatim at lines 101-103 after the switch. Since the post-switch check (line 101) covers all branches, the inner one in the AMOUNT_LIST existing-stored path is redundant. Trim one of them to keep the rigging tidy.

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/TransferWholeTransactionApplier.java (1)

42-71: ⚡ Quick win

Three checks of the same knot — and the rope's grammar be frayed.

Two matters t' tidy on this deck:

  1. Redundant state checks. The STORED check be raised thrice — once in each branch of the switch (lines 42-44, 53-55) and again after the switch (lines 69-71). The inner check at lines 53-55 be needed to guard the cast at line 57, but the BULK/UNIQUE_SINGLE check at 42-44 hath no cast that follows, and the outer check at 69-71 be entirely redundant once both branches have run. Hoist 'em down to one well-placed check apiece.
  2. Grammar in the error message. "Cannot transfer whole stored that not stored." be missin' the word "is" — appears three times. Should read "...that is not stored."
♻️ Proposed tidyin' of the riggin'
 		switch (inventoryItem.getStorageType()) {
 			case BULK, UNIQUE_SINGLE -> {
 				toTransfer = this.getStoredService().getSingleStoredForItemBlock(oqmDbIdOrName, cs, inventoryItem.getId(), transaction.getFromBlock(), Stored.class);
-				
-				if(!toTransfer.isState(StoredStateType.STORED)){
-					throw new IllegalArgumentException("Cannot transfer whole stored that not stored.");
-				}
-				
+
 				if(transaction.getStoredToTransfer() != null && !toTransfer.getId().equals(transaction.getStoredToTransfer())) {
 					throw new IllegalArgumentException("Stored item from block does not match stored specified.");
 				}
 			}
 			case AMOUNT_LIST, UNIQUE_MULTI -> {
 				toTransfer = this.getStoredService().get(oqmDbIdOrName, cs, transaction.getStoredToTransfer());
-				
+
 				if(!toTransfer.isState(StoredStateType.STORED)){
-					throw new IllegalArgumentException("Cannot transfer whole stored that not stored.");
+					throw new IllegalArgumentException("Cannot transfer whole stored that is not stored.");
 				}
-				
+
 				if(transaction.getFromBlock() != null && !((StoredInBlock)toTransfer.getState()).getStorageBlock().equals(transaction.getFromBlock())) {
 					throw new IllegalArgumentException("Stored item specified does not match stored from storage block.");
 				}
 			}
 			default ->
 				throw new IllegalArgumentException("Unsupported storage type. This should never happen.");
 		}

 		if (!inventoryItem.getId().equals(toTransfer.getItem())) {
 			throw new IllegalArgumentException("Stored is not associated with the item.");
 		}
-		
+
 		if(!toTransfer.isState(StoredStateType.STORED)){
-			throw new IllegalArgumentException("Cannot transfer whole stored that not stored.");
+			throw new IllegalArgumentException("Cannot transfer whole stored that is not stored.");
 		}
software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/serviceState/InstanceMutexService.java (2)

254-256: 💤 Low value

Spellin' mutiny: "maitTime" be no proper word, matey.

maitTimeMin / maitTimeMax should be waitTimeMin / waitTimeMax. Same misspell sails on into the debug log on line 260. Set the rigging right.

🪛 Trim the typo
-		long maitTimeMin = this.getMutexConfig().await().loopPauseMin().toMillis();
-		long maitTimeMax = this.getMutexConfig().await().loopPauseMax().toMillis();
+		long waitTimeMin = this.getMutexConfig().await().loopPauseMin().toMillis();
+		long waitTimeMax = this.getMutexConfig().await().loopPauseMax().toMillis();
 		...
-		log.debug("Awaiting lock for {} with timeout of {}. Max wait time: {}. Min wait time: {}", mutexId, toWait, maitTimeMax, maitTimeMin);
+		log.debug("Awaiting lock for {} with timeout of {}. Max wait time: {}. Min wait time: {}", mutexId, toWait, waitTimeMax, waitTimeMin);
 		...
-				long sleepTime = random.nextLong(maitTimeMin, maitTimeMax);
+				long sleepTime = random.nextLong(waitTimeMin, waitTimeMax);

Also applies to: 260-260


134-161: ⚡ Quick win

Belay the redundant find, the upsert can carry the load alone.

The pre-check find().into(ArrayList) at line 136 is followed by an idempotent upsert at line 145 that already does the right thing on its own; the read-then-write window also leaves a wee gap for races. Strikin' the read would simplify register and remove a dead reef — the clearDuplicateMutexes path on line 156 won't ever be reached anyway since the upsert prevents duplicates by id of the mutexId field (assuming a unique index — see related comment in OqmDatabaseService for the same indexing concern; should also add a unique index on mutexId for this collection).

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/interfaces/endpoints/inventory/items/InventoryItemsCrudTest.java (1)

216-216: ⚡ Quick win

TODO be flyin' the black flag.

//TODO:: check results — the test asserts only the HTTP 200 on each call and the final GET status. With nothing checked, a regression that silently drops updates (the very thing a mutex test ought to catch) would sail right past. At minimum, assert that the final item's attributes contains an entry per thread keyed testThread-N with value numIterations.

Want me to draft the assertions and open a follow-up issue to track the rest of the result verification?

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/serviceState/InstanceMutexServiceTest.java (1)

157-164: 💤 Low value

That there be a busy-waitin' loop, mate!

Ye've got an empty while loop here when await be false - just spinnin' the wheel until the lock be available. Now, this ain't technically wrong, but it be wastin' CPU cycles like throwin' rum overboard!

Consider addin' a Thread.yield() or Thread.onSpinWait() inside that loop to give other threads a chance to do their work, or at least add a comment explainin' why ye chose this approach. Makes the code easier for the next sailor who comes aboard to understand yer intentions.

🔄 Suggested improvement to ease the CPU burden
 				if(await){
 					instanceMutexService.awaitLock(this.mutexId, threadIdOpt);
 				} else {
-					//noinspection StatementWithEmptyBody
-					while (!instanceMutexService.lock(this.mutexId, threadIdOpt)) {
-						//nothing to do
-					}
+					while (!instanceMutexService.lock(this.mutexId, threadIdOpt)) {
+						Thread.onSpinWait(); // Give other threads a chance
+					}
 				}
software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/ui/pages/UiProvider.java (1)

70-82: 💤 Low value

Swab these commented lines from the deck, sailor!

This here be a sizeable block o' commented code cluttering up yer hull. Dead code like this makes the ship harder to navigate and maintain. Best to heave it overboard entirely rather than lettin' it drift about in yer codebase.

software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/modelTweak/SearchResultTweak.java (1)

39-39: ⚖️ Poor tradeoff

Aye—your callers be sailing the new signature cleanly (old-order use lives only in commented code).

  • Active invocations in OverviewUi, ItemStoredPassthrough, ItemInBlockPassthrough, ItemCheckoutUi, and ItemCheckoutPassthrough all pass (results, oqmDb, apiToken, "...keys"), matching (ObjectNode, String oqmDb, String apiToken, String... keys).
  • ItemStoredPassthrough.java still has a commented-out call using the old argument order; safe for now, but best to delete or update it to keep the deck shipshape.
software/libs/core-api-lib-quarkus/runtime/src/main/java/tech/ebp/oqm/lib/core/api/quarkus/runtime/restClient/models/InteractingEntity.java (1)

11-24: ⚡ Quick win

Add @JsonIgnoreProperties(ignoreUnknown = true) to the client DTO for forward-compatibility.

No repo-wide Quarkus/Jackson setting was found that would ignore unknown fields for this rest-client deserialization; only server-side Mappers/readers toggle FAIL_ON_UNKNOWN_PROPERTIES. Batten down InteractingEntity against surprise payload sails.

♻️ Suggested charm against unknown-field shipwreck
 package tech.ebp.oqm.lib.core.api.quarkus.runtime.restClient.models;

+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;

 import java.util.List;
 import java.util.Map;
 import java.util.Set;

 `@Data`
 `@AllArgsConstructor`
 `@NoArgsConstructor`
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class InteractingEntity {

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3c367179-8474-4d3e-8c18-1f735d887804

📥 Commits

Reviewing files that changed from the base of the PR and between 4c4bfbe and 87562ab.

📒 Files selected for processing (92)
  • software/core/oqm-core-api/build.gradle
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/config/MutexConfig.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/exception/mutex/MutexNotRegisteredException.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/exception/mutex/MutexWaitInterruptedException.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/exception/mutex/MutexWaitTimeoutException.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/interfaces/endpoints/info/RunByUtils.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/interfaces/endpoints/inventory/items/StoredEndpoints.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/interfaces/endpoints/inventory/items/StoredInItemEndpoints.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/AttKeywordMainObject.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/checkout/ItemCheckout.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/checkout/ItemWholeCheckout.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/Stored.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/state/StoredInBlock.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/state/StoredState.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/state/StoredStateType.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/rest/search/StoredSearch.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/scheduled/LifecycleBean.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/scheduled/MongoDbInit.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/ItemStatsService.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/InventoryItemService.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/ItemListService.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoDbAwareService.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoObjectService.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoService.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/StorageBlockService.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/StoredService.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/TopLevelMongoService.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/AppliedTransactionService.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/AddAmountTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/AddWholeTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/CheckinFullTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/CheckinLossTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/CheckinOutTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/CheckinPartTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/CheckoutAmountTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/CheckoutWholeTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/SetAmountTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/SubtractAmountTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/SubtractWholeTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/TransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/TransferAmountTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/TransferWholeTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/schemaVersioning/upgraders/stored/StoredSchemaUpgrader.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/schemaVersioning/upgraders/stored/bumpers/StoredItemBumper5.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/serviceState/InstanceMutexService.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/serviceState/db/OqmDatabaseService.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/interfaces/endpoints/inventory/items/InventoryItemsCrudTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/interfaces/endpoints/inventory/items/InventoryItemsStatsTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/interfaces/endpoints/inventory/items/StoredInItemEndpointsTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/StoredTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/AppliedTransactionServiceTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/GeneratedIdentifierGenerationServiceTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/StoredServiceTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/AddAmountAppliedTransactionTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/AddWholeAppliedTransactionTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/AppliedTransactionServiceTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/CheckinFullAmountAppliedTransactionTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/CheckinWholeAppliedTransactionTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/CheckoutAmountAppliedTransactionTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/CheckoutWholeAppliedTransactionTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/SetAmountAppliedTransactionTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/SubtractAmountAppliedTransactionTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/SubtractWholeAppliedTransactionTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/TransferAmountAppliedTransactionTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/TransferWholeAppliedTransactionTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/serviceState/InstanceMutexServiceTest.java
  • software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/testResources/data/StoredTestObjectCreator.java
  • software/core/oqm-core-api/src/test/resources/application.yaml
  • software/core/oqm-core-base-station/build.gradle
  • software/core/oqm-core-base-station/installerSrc/installerProperties.json
  • software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/rest/passthrough/inventory/ItemCheckoutPassthrough.java
  • software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/rest/passthrough/inventory/ItemInBlockPassthrough.java
  • software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/rest/passthrough/inventory/ItemStoredPassthrough.java
  • software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/ui/pages/ItemCheckoutUi.java
  • software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/ui/pages/OverviewUi.java
  • software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/ui/pages/UiProvider.java
  • software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/modelTweak/SearchResultTweak.java
  • software/core/oqm-core-base-station/src/main/resources/META-INF/resources/res/js/obj/item/ItemView.js
  • software/core/oqm-core-base-station/src/main/resources/META-INF/resources/res/js/obj/itemStored/ItemStoredTransaction.js
  • software/core/oqm-core-base-station/src/main/resources/META-INF/resources/res/js/obj/itemStored/StoredView.js
  • software/core/oqm-core-base-station/src/main/resources/templates/tags/search/itemStored/searchResults.html
  • software/core/oqm-core-base-station/src/main/resources/templates/webui/mainWebPageTemplate.html
  • software/core/oqm-core-base-station/src/test/java/tech/ebp/oqm/core/baseStation/testResources/testUsers/TestUser.java
  • software/libs/core-api-lib-quarkus/deployment/pom.xml
  • software/libs/core-api-lib-quarkus/deployment/src/main/java/tech/ebp/oqm/lib/core/api/quarkus/deployment/config/CoreApiLibBuildTimeConfig.java
  • software/libs/core-api-lib-quarkus/integration-tests/pom.xml
  • software/libs/core-api-lib-quarkus/pom.xml
  • software/libs/core-api-lib-quarkus/runtime/pom.xml
  • software/libs/core-api-lib-quarkus/runtime/src/main/java/tech/ebp/oqm/lib/core/api/quarkus/runtime/restClient/OqmCoreApiClientService.java
  • software/libs/core-api-lib-quarkus/runtime/src/main/java/tech/ebp/oqm/lib/core/api/quarkus/runtime/restClient/models/InteractingEntity.java
  • software/libs/core-api-lib-quarkus/runtime/src/main/java/tech/ebp/oqm/lib/core/api/quarkus/runtime/restClient/searchObjects/StoredSearch.java
  • software/plugins/storagotchi/src/main/docker/Dockerfile.native
💤 Files with no reviewable changes (2)
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/interfaces/endpoints/info/RunByUtils.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/interfaces/endpoints/inventory/items/StoredEndpoints.java
📜 Review details
🧰 Additional context used
🪛 HTMLHint (1.9.2)
software/core/oqm-core-base-station/src/main/resources/templates/tags/search/itemStored/searchResults.html

[error] 97-97: Special characters must be escaped : [ < ].

(spec-char-escape)


[error] 99-99: Special characters must be escaped : [ > ].

(spec-char-escape)


[error] 101-101: Tag must be paired, no start tag: [ ]

(tag-pair)


[error] 96-96: Tag must be paired, missing: [ ], start tag match failed [ ] on line 96.

(tag-pair)

software/core/oqm-core-base-station/src/main/resources/templates/webui/mainWebPageTemplate.html

[error] 275-275: The id value [ messageDiv ] must be unique.

(id-unique)

🪛 PMD (7.24.0)
software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/AddAmountAppliedTransactionTest.java

[Low] 57-57: InvalidLogMessageFormat (Error Prone): Too many arguments, expected 0 argument but found 1

(InvalidLogMessageFormat (Error Prone))

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/AppliedTransactionServiceTest.java

[Low] 231-231: InvalidLogMessageFormat (Error Prone): Too many arguments, expected 0 argument but found 1

(InvalidLogMessageFormat (Error Prone))

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/serviceState/InstanceMutexServiceTest.java

[Medium] 127-127: OverrideBothEqualsAndHashCodeOnComparable (Error Prone): When implementing Comparable, both equals() and hashCode() should be overridden

(OverrideBothEqualsAndHashCodeOnComparable (Error Prone))

🔇 Additional comments (85)
software/core/oqm-core-api/build.gradle (1)

11-11: LGTM!

Also applies to: 47-47

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/AttKeywordMainObject.java (1)

44-44: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/checkout/ItemCheckout.java (1)

42-115: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/exception/mutex/MutexWaitTimeoutException.java (1)

1-1: ⚡ Quick win

No stowaways left after hoisting MutexWaitTimeoutException into .mutex
Aye—no callsites still reference the old FQN tech.ebp.oqm.core.api.exception.MutexWaitTimeoutException anywhere in the repo (Java or non-Java resources). All usages point to tech.ebp.oqm.core.api.exception.mutex.MutexWaitTimeoutException (e.g., InstanceMutexService and InstanceMutexServiceTest).

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/config/MutexConfig.java (1)

11-12: ⚡ Quick win

${quarkus.uuid} expands correctly in @WithDefault (no literal string risk)

Avast! SmallRye Config expands ${...} property expressions for configuration values used via @WithDefault, so MutexConfig.instanceId() resolves to Quarkus’s generated quarkus.uuid (not the literal "${quarkus.uuid}") at runtime. [software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/config/MutexConfig.java:11-12]

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/interfaces/endpoints/inventory/items/StoredInItemEndpoints.java (1)

151-164: ⚡ Quick win

Provide the original <review_comment> (and any related diff/context) so I can rewrite it.

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/state/StoredStateType.java (1)

3-5: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/rest/search/StoredSearch.java (2)

88-108: LGTM!


74-74: ⚡ Quick win

Missing input: provide the <review_comment> text Paste the original review comment (and any verification outputs/results you want me to use) so I can rewrite it in the required format.

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/scheduled/LifecycleBean.java (1)

45-45: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/state/StoredState.java (1)

12-25: 🏗️ Heavy lift

Missing input to rewrite the review comment: Provide the original text inside the <review_comment> tags (and any verification outputs/results), otherwise the comment can’t be rewritten accurately.

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/Stored.java (1)

72-72: ⚡ Quick win

No gap in v4→v5 Stored migration — StoredItemBumper5 moves storageBlock into state.storageBlock and clears the old field
Ahoy matey: StoredItemBumper5 normalizes the legacy top-level storageBlock, removes it (oldObj.remove("storageBlock")), and writes state with type: "STORED" plus state.storageBlock. StoredSearch then queries state.type and state.storageBlock, and state.storageBlock lands in StoredInBlock.storageBlock (an ObjectId) via MongoObjectIdModule’s String→ObjectId deserializer, so the upgraded records should surface correctly.

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/scheduled/MongoDbInit.java (1)

58-70: ⚡ Quick win

Missing input: Provide the original review comment text (inside <review_comment> tags) and the verification outputs/logs you want me to base the rewrite on.

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/InventoryItemService.java (2)

286-290: LGTM!


453-458: ⚡ Quick win

Provide the original <review_comment> (including any diff snippets and file/line context) plus the verification outputs you have (shell/web results).
Without those, I can’t rewrite the comment or apply the correct verification-based updates.

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/ItemListService.java (1)

70-75: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoDbAwareService.java (1)

180-191: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoObjectService.java (1)

423-425: LGTM!

Also applies to: 452-452

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/MongoService.java (1)

113-115: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/StorageBlockService.java (1)

196-201: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/StoredService.java (1)

177-181: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/ItemStatsService.java (1)

144-146: ⚡ Quick win

Request missing context: Paste the original review comment (inside <review_comment>...</review_comment>) and the verification outputs/results you have, so the comment can be rewritten accurately.

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/TopLevelMongoService.java (1)

207-216: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/CheckinLossTransactionApplier.java (1)

19-20: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/CheckinOutTransactionApplier.java (1)

22-27: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/CheckinPartTransactionApplier.java (1)

18-25: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/CheckinFullTransactionApplier.java (1)

71-83: Need the original review comment to rewrite: Paste the full <review_comment> content (and any verification output/logs you want applied) so I can produce the corrected rewritten comment.

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/AppliedTransactionService.java (1)

87-91: ⚡ Quick win

Mutex wait isn’t unbounded here; Optional.empty() is for identity, not timeout

That Optional.empty() passed to InstanceMutexService.getResource(mutexId, Optional.empty()) is the additionalIdentity slot. This resource always starts locked (getResource(... ) calls awaitLock()), and awaitLock() caps the wait using service.mutex.await.timeout (default 30s). So the “becalmed forever” risk from Optional.empty() alone doesn’t hold—only adjusts if the timeout config is set too high.

			> Likely an incorrect or invalid review comment.
software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/CheckoutWholeTransactionApplier.java (1)

23-23: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/SetAmountTransactionApplier.java (1)

46-52: LGTM!

Also applies to: 70-77

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/SubtractAmountTransactionApplier.java (1)

20-20: LGTM!

Also applies to: 67-74

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/SubtractWholeTransactionApplier.java (1)

19-19: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/TransferAmountTransactionApplier.java (1)

21-23: LGTM!

Also applies to: 53-53, 64-64, 101-106

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/TransactionApplier.java (1)

31-41: ⚡ Quick win

Please include the original review comment text inside <review_comment>...</review_comment> (and any relevant diff/snippet) so I can rewrite it in the required format.

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/schemaVersioning/upgraders/stored/StoredSchemaUpgrader.java (1)

10-10: LGTM!

Also applies to: 22-23

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/interfaces/endpoints/inventory/items/InventoryItemsStatsTest.java (1)

11-11: LGTM!

Also applies to: 21-21, 130-130, 226-226

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/interfaces/endpoints/inventory/items/StoredInItemEndpointsTest.java (1)

14-14: LGTM!

Also applies to: 23-23, 140-140, 263-263

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/StoredTest.java (1)

11-11: LGTM!

Also applies to: 53-53, 64-64

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/serviceState/db/OqmDatabaseService.java (1)

192-197: ⚡ Quick win

Missing context: Provide the original review text inside the <review_comment> tags (and any code/diff snippets it references) so it can be rewritten correctly.

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/schemaVersioning/upgraders/stored/bumpers/StoredItemBumper5.java (1)

39-40: 💤 Low value

Provide the original review comment to rewrite (the content inside <review_comment> tags).
Cannot rewrite without the original comment text.

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/StoredServiceTest.java (1)

15-15: LGTM!

Also applies to: 100-110, 124-134, 148-158, 173-181, 204-213, 227-237, 251-260, 274-283, 302-311, 331-341

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/AddAmountAppliedTransactionTest.java (2)

54-58: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avast! Yer log message be improperly rigged, sailor!

Line 57's log statement be passin' an exception to log.warn() without a proper placeholder. The logger expects a format string with {} markers, but ye're providin' the exception as a parameter without tellin' it what to do with the beast.

⚓ Proper log format, as per the old sea charts
 		} catch(UnknownTopicOrPartitionException e) {
-			log.warn("Failed to clear queues", e);
+			log.warn("Failed to clear queues: {}", e.getMessage(), e);
 		}

Or if ye want the full stack trace in yer ship's log:

 		} catch(UnknownTopicOrPartitionException e) {
-			log.warn("Failed to clear queues", e);
+			log.warn("Failed to clear queues", e);
 		}

Actually, belay that - the second option be what ye already have. The PMD tool be raisin' a false alarm here, as SLF4J does support passin' the exception as the last parameter without a placeholder. Ye can safely ignore this warnin', or add a @SuppressWarnings("PMD.InvalidLogMessageFormat") annotation if it bothers ye.


43-342: LGTM!

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/AddWholeAppliedTransactionTest.java (1)

46-294: LGTM!

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/AppliedTransactionServiceTest.java (1)

82-234: LGTM!

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/CheckinFullAmountAppliedTransactionTest.java (1)

52-427: LGTM!

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/CheckinWholeAppliedTransactionTest.java (1)

53-275: LGTM!

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/CheckoutAmountAppliedTransactionTest.java (1)

50-487: LGTM!

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/GeneratedIdentifierGenerationServiceTest.java (1)

244-264: ⚖️ Poor tradeoff

Provide the original <review_comment> content (and any verification outputs/results) so it can be rewritten in the required format.

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/CheckoutWholeAppliedTransactionTest.java (1)

49-103: LGTM!

Also applies to: 105-159, 161-214, 216-269

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/SetAmountAppliedTransactionTest.java (1)

49-84: LGTM!

Also applies to: 87-132, 135-180, 182-196, 198-212, 214-227, 229-245, 247-263, 265-293, 295-309

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/SubtractAmountAppliedTransactionTest.java (1)

43-89: LGTM!

Also applies to: 91-139, 141-189, 191-215, 217-241, 243-268, 270-295, 297-337, 339-379, 381-421, 423-463, 465-489

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/TransferAmountAppliedTransactionTest.java (1)

41-113: LGTM!

Also applies to: 115-195, 197-278, 280-361, 363-445, 447-520, 523-545, 547-569, 571-603, 605-638, 640-681, 683-724

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/mongo/transactions/transactionApplier/TransferWholeAppliedTransactionTest.java (1)

43-99: LGTM!

Also applies to: 101-158, 160-215, 218-273

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/service/serviceState/InstanceMutexServiceTest.java (2)

184-261: LGTM!


30-51: 💤 Low value

Missing review comment payload
No <review_comment>...</review_comment> content was provided to rewrite—please paste the original review comment (and any related code diff/snippet if included).

software/core/oqm-core-api/src/test/java/tech/ebp/oqm/core/api/testResources/data/StoredTestObjectCreator.java (1)

31-41: LGTM!

software/core/oqm-core-api/src/test/resources/application.yaml (1)

12-15: LGTM!

software/core/oqm-core-base-station/build.gradle (2)

8-8: LGTM!

Also applies to: 48-48, 52-52


35-35: ⚡ Quick win

Request the missing inputs to rewrite the review comment: Provide the original <review_comment> content (and any shell/web outputs you have) so I can rewrite it accurately.

software/core/oqm-core-base-station/installerSrc/installerProperties.json (1)

9-9: LGTM!

software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/rest/passthrough/inventory/ItemInBlockPassthrough.java (1)

79-79: LGTM!

software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/rest/passthrough/inventory/ItemStoredPassthrough.java (1)

73-74: LGTM!

software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/ui/pages/ItemCheckoutUi.java (1)

64-64: LGTM!

software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/ui/pages/OverviewUi.java (1)

106-112: LGTM!

software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/rest/passthrough/inventory/ItemCheckoutPassthrough.java (1)

73-73: 💤 Low value

Missing input: Provide the original review comment inside <review_comment>...</review_comment> (and any relevant diff/context) so I can rewrite it per the guidelines.

software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/interfaces/ui/pages/UiProvider.java (1)

84-88: LGTM!

software/core/oqm-core-base-station/src/main/java/tech/ebp/oqm/core/baseStation/service/modelTweak/SearchResultTweak.java (1)

31-37: LGTM!

software/core/oqm-core-base-station/src/main/resources/META-INF/resources/res/js/obj/itemStored/ItemStoredTransaction.js (2)

1193-1193: LGTM!


1798-1798: LGTM!

software/core/oqm-core-base-station/src/main/resources/META-INF/resources/res/js/obj/itemStored/StoredView.js (2)

233-233: LGTM!

Also applies to: 239-248


40-86: ⚡ Quick win

Check for lingering calls to renamed StoredView helpers

The old helper names still exist in software/plugins/mss-controller/mss-controller-plugin/src/main/resources/META-INF/resources/res/js/obj/item/storedView.js (they’re defined and called from within that same file), so this doesn’t yet prove any break against the core StoredView you renamed.

Next thing to hunt: any code importing/calling the core .../obj/itemStored/StoredView.js version with the old getStorageBlock* names (search for imports/usage of that core module path).

software/core/oqm-core-base-station/src/main/resources/templates/tags/search/itemStored/searchResults.html (2)

54-54: LGTM!

Also applies to: 99-99


104-104: LGTM!

software/core/oqm-core-base-station/src/test/java/tech/ebp/oqm/core/baseStation/testResources/testUsers/TestUser.java (1)

28-33: ⚡ Quick win

Smart sailin', removin' them troublesome quotes!

Aye, this be good defensive work here, matey! Stripping out single quotes from the generated username prevents all manner of mischief - SQL injection, string escaping troubles, and command injection if the username ever finds its way into shell commands. Keeps the ship secure and the tests runnin' smooth.

software/core/oqm-core-base-station/src/main/resources/META-INF/resources/res/js/obj/item/ItemView.js (1)

467-467: ⚡ Quick win

Fair winds: stored.state.storageBlock matches the Stored model’s state shape.
Ye be right to compare via if (curBlock === stored.state.storageBlock): the backend models storageBlock on StoredInBlock (a StoredState) and migrations/tests place it under state.storageBlock.

software/core/oqm-core-base-station/src/main/resources/templates/webui/mainWebPageTemplate.html (1)

207-207: ⚡ Quick win

Re-check JS/TS reads of data-userid: The template now uses data-userid on #userNameDisplay, and there are no repo occurrences of data-userId nor any getAttribute("data-userId"/"data-userid") or dataset.userId/dataset.userid dot-notation usage found.

software/libs/core-api-lib-quarkus/deployment/pom.xml (1)

11-11: Aye, version bump be shipshape! The parent reference at line 11 sails in lockstep with the parent POM's 5.0.0-SNAPSHOT declaration. Major-version jump be fittin' for the breaking changes carried in this cargo (REST client return type, removed endpoint, and the like).

software/libs/core-api-lib-quarkus/deployment/src/main/java/tech/ebp/oqm/lib/core/api/quarkus/deployment/config/CoreApiLibBuildTimeConfig.java (1)

99-100: Steady as she goes — default image tag follows the new snapshot. Just be sure the matching docker.io/ebprod/oqm-core-api:5.0.0-SNAPSHOT image be published to the registry afore any sailor consuming this extension hoists sail, else their devservices'll find naught but an empty hold.

software/libs/core-api-lib-quarkus/integration-tests/pom.xml (1)

8-8: LGTM!

software/libs/core-api-lib-quarkus/pom.xml (1)

10-10: LGTM!

software/libs/core-api-lib-quarkus/runtime/pom.xml (1)

11-11: LGTM!

software/libs/core-api-lib-quarkus/runtime/src/main/java/tech/ebp/oqm/lib/core/api/quarkus/runtime/restClient/OqmCoreApiClientService.java (2)

441-450: 💤 Low value

Summary be tellin' tales — invItemStoredUpdate still aboard.

The AI-generated summary claims the PUT invItemStoredUpdate method was struck from the manifest, yet here she sits proud at lines 441–450. Either the summary mis-logged the change or the deletion was reverted; worth a sanity check before merging so the ship's log matches the cargo.


136-138: ⚡ Quick win

Confirm downstream compilation for interactingEntityGetSelf’s typed return

Arr, the REST client now returns Uni<InteractingEntity> (instead of Uni<ObjectNode>), so any consumer expecting the old untyped JSON shape will be a proper breaker. In oqm-core-base-station, the userInfo value fed by interactingEntityGetSelf is already consumed via userInfo.getRoles()/getId()/getName() in the WebUI templates, with the former ObjectNode-style mapping left commented out—still, check any other downstream callers beyond base-station that may rely on the old ObjectNode shape.

software/plugins/storagotchi/src/main/docker/Dockerfile.native (1)

19-19: ⚡ Quick win

Cannot rewrite review comment: missing <review_comment> content and any verification outputs
Provide the original <review_comment>...</review_comment> text (and any shell/web results) so the comment can be rewritten accurately.

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 21, 2026
@github-actions
Copy link
Copy Markdown

Code Coverage

There is no coverage information present for the Files changed

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
software/core/oqm-core-base-station/src/main/resources/META-INF/resources/res/js/obj/item/ItemView.js (1)

455-492: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Empty "Stored in:" label when state ain't StoredInBlock, captain.

If stored.state.storageBlock be undefined (e.g., the unique stored is not currently in a block — checked out or otherwise), the loop on Line 471 will never match, every block falls through to "Also found in", and the Stored in: header span ends up blank with no link beside it. Ye already hide the "Also found in" container when empty (Lines 489–491); consider the symmetric treatment for the "Stored in" span, or render a fallback like "Not currently stored" so the swabbie reading the page knows where the unique item actually be.

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/CheckoutAmountTransactionApplier.java (1)

51-54: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard the AmountStored cast before it sends a bad request overboard.

Matey, Line 54 and Line 63 cast request-selected Stored records straight to AmountStored. If fromStored points at the wrong subtype, this blows up as a ClassCastException and turns invalid input into a 500 instead of a clean validation error.

⚓ Proposed fix
 			case BULK -> {
 				if (transaction.getFromBlock() != null) {
 					stored = this.getStoredService().getSingleStoredForItemBlock(oqmDbIdOrName, cs, inventoryItem.getId(), transaction.getFromBlock(), AmountStored.class);
 				} else if (transaction.getFromStored() != null) {
-					stored = (AmountStored) this.getStoredService().get(oqmDbIdOrName, cs, transaction.getFromStored());
+					Stored resolvedStored = this.getStoredService().get(oqmDbIdOrName, cs, transaction.getFromStored());
+					if (!(resolvedStored instanceof AmountStored amountStored)) {
+						throw new IllegalArgumentException("Cannot checkout an amount from a non-amount stored.");
+					}
+					stored = amountStored;
 				} else {
 					throw new IllegalArgumentException("No stored or block given to checkout from.");
 				}
 			}
 			case AMOUNT_LIST -> {
 				if (transaction.getFromStored() == null) {
 					throw new IllegalArgumentException("No stored given to checkout from.");
 				}
-				stored = (AmountStored) this.getStoredService().get(oqmDbIdOrName, cs, transaction.getFromStored());
+				Stored resolvedStored = this.getStoredService().get(oqmDbIdOrName, cs, transaction.getFromStored());
+				if (!(resolvedStored instanceof AmountStored amountStored)) {
+					throw new IllegalArgumentException("Cannot checkout an amount from a non-amount stored.");
+				}
+				stored = amountStored;
 			}

Also applies to: 59-64

🧹 Nitpick comments (3)
software/core/oqm-core-characteristics/app/UIs.py (2)

115-129: 💤 Low value

Duplicate-id check be sweepin' the deck twice for every barrel.

The current implementation filters uiList for each entry, makin' it O(n²). With small UI lists this be no kraken, but a single pass with a set makes the intent clearer and avoids the quadratic dance. Also, raisin' a bare Exception makes it hard for callers to catch specifically — ValueError would be more in keeping with Python's customs.

♻️ Suggested refactor
 	`@classmethod`
 	def validate_ui_list(cls, uiList: list[UiCache]) -> None:
-		# ensure id uniqueness
-		for uiCache in uiList:
-			if not uiCache.id:
-				continue
-			filtered_list = list(
-				filter(
-					lambda
-						x: uiCache.id == x.id,
-					uiList
-					)
-				)
-			if len(filtered_list) != 1:
-				raise Exception("Invalid UI ID (duplicates): " + uiCache.id)
+		# ensure id uniqueness
+		seen: set[str] = set()
+		for uiCache in uiList:
+			if not uiCache.id:
+				continue
+			if uiCache.id in seen:
+				raise ValueError("Invalid UI ID (duplicates): " + uiCache.id)
+			seen.add(uiCache.id)

149-161: ⚡ Quick win

Unkeyed type field will scuttle the whole load, matey.

rawUi["type"] (Lines 152–158) and rawUi["name"]/rawUi["description"]/rawUi["url"] in __get_ui will raise KeyError for any malformed .json file in UIS_DATA_DIR, abortin' the entire cache build and leavin' cls.ui_cache set to None forever — every subsequent call re-tries and re-fails. Consider validatin' each raw file, loggin' and skippin' the bad ones rather than scuttlin' the whole convoy.

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/AddAmountTransactionApplier.java (1)

84-107: 💤 Low value

Two state-checks doin' the work o' one — and a strange message at the second.

The state guard on Lines 84–86 (inside the AMOUNT_LIST/toStored != null branch) protects the cast on Line 90. The very same guard then fires again on Lines 105–107 after the switch closes. For the AMOUNT_LIST path the second one can never trip; for the BULK path it be the only check. Either lean on the outer guard and remove the inner one (the cast on Line 90 still needs some check — keep the inner, or hoist it), or document why both exist. As written it reads like one was forgotten when the other was added, and the duplicate error message ("Cannot add to stored that is not stored in a block.") will mask which branch raised it.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 34da9a4d-bad4-4093-b27e-42b2f15060a7

📥 Commits

Reviewing files that changed from the base of the PR and between 87562ab and 253ad1e.

📒 Files selected for processing (9)
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/exception/mutex/MutexNotRegisteredException.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/exception/mutex/MutexWaitInterruptedException.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/health/ConfigHealthCheck.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/state/StoredInBlock.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/AddAmountTransactionApplier.java
  • software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/service/mongo/transactions/appliers/CheckoutAmountTransactionApplier.java
  • software/core/oqm-core-base-station/src/main/resources/META-INF/resources/res/js/obj/item/ItemView.js
  • software/core/oqm-core-base-station/src/main/resources/templates/webui/mainWebPageTemplate.html
  • software/core/oqm-core-characteristics/app/UIs.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: CI-Pipeline / Unit Tests
  • GitHub Check: CI-Pipeline / Integration Tests
  • GitHub Check: CI-Pipeline / Build
🔇 Additional comments (5)
software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/exception/mutex/MutexWaitInterruptedException.java (1)

1-11: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/exception/mutex/MutexNotRegisteredException.java (1)

1-11: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/health/ConfigHealthCheck.java (1)

34-55: LGTM!

software/core/oqm-core-api/src/main/java/tech/ebp/oqm/core/api/model/object/storage/items/stored/state/StoredInBlock.java (1)

1-39: LGTM!

software/core/oqm-core-base-station/src/main/resources/templates/webui/mainWebPageTemplate.html (1)

1-469: LGTM!

Comment thread software/core/oqm-core-characteristics/app/UIs.py
@github-actions
Copy link
Copy Markdown

Code Coverage

Overall Project 62.06% -1.27% 🍏
Files changed 71.49%

File Coverage
AttKeywordMainObject.java 100% 🍏
MutexNotRegisteredException.java 100% 🍏
StoredInBlock.java 100% 🍏
StoredStateType.java 100% 🍏
TransactionApplier.java 100% 🍏
CheckinOutTransactionApplier.java 100% 🍏
ItemWholeCheckout.java 100% 🍏
StoredSchemaUpgrader.java 100% 🍏
LifecycleBean.java 97.5% 🍏
AppliedTransactionService.java 93.72% 🍏
CheckoutWholeTransactionApplier.java 92.75% 🍏
Stored.java 91.33% -0.21% 🍏
CheckoutAmountTransactionApplier.java 87% -2.5% 🍏
MongoService.java 85.94% 🍏
MongoDbInit.java 85.9% -14.1% 🍏
InstanceMutexService.java 85.46% -10.82%
MongoObjectService.java 84.63% 🍏
TransferAmountTransactionApplier.java 83.86% -3.51%
SetAmountTransactionApplier.java 83.23% -2.99% 🍏
CheckinFullTransactionApplier.java 83.08% -5.64% 🍏
AddAmountTransactionApplier.java 81.9% -7.14%
OqmDatabaseService.java 78.32% 🍏
ItemCheckout.java 77.78% 🍏
AddWholeTransactionApplier.java 77.38% -16.67%
SubtractAmountTransactionApplier.java 74.71% -2.87%
TransferWholeTransactionApplier.java 72.22% -11.9%
TopLevelMongoService.java 72.2% -0.36% 🍏
StoredService.java 71.36% -9.14%
MongoDbAwareService.java 68.34% -0.5% 🍏
StoredSearch.java 63.73% -3.43% 🍏
StoredInItemEndpoints.java 57.29% -33.33%
ItemStatsService.java 51.31% -3.25%
MutexWaitTimeoutException.java 50% 🍏
CheckinPartTransactionApplier.java 50% 🍏
CheckinLossTransactionApplier.java 50% 🍏
InventoryItemService.java 44.02% 🍏
StorageBlockService.java 33.55% 🍏
ItemListService.java 24.66% 🍏
SubtractWholeTransactionApplier.java 12.5% 🍏
StoredEndpoints.java 5.33% 🍏
StoredItemBumper5.java 4.3% -95.7%
MutexWaitInterruptedException.java 0%
ConfigHealthCheck.java 0% -17.86%

@GregJohnStewart GregJohnStewart merged commit 34e7492 into main May 22, 2026
11 of 12 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.

2 participants