BeechCMS v0.6.4
Release Date: July 15, 2026
π Bug Fixes
-
Surface queue enqueue failures instead of silently dropping oversized payloads β
CloudflareQueueService.enqueuecaughtqueue.send()rejections (e.g. the 128 KiB per-message size limit) and only logged them, resolving as a success. Callers had no way to detect the drop, causing permanent data loss for bulk export/import, large webhook payloads, and audit logs.IQueueService.enqueuenow returnsPromise<boolean>instead ofPromise<void>:CloudflareQueueServicereturnsfalseon transport failure,InMemoryQueueServicereturnsfalsewhen no handler is registered, andNoOpQueueServicealways returnstrue. (220) (257) -
Guard
InMemoryQueueServicehandler invocation against sync throws and void returns β Handler invocations in the in-memory queue service were not wrapped in a try/catch, meaning synchronous handler throws would propagate uncaught and bubble out of the test harness instead of being surfaced as a structured failure. The invocation path now catches sync throws and treats non-Promise return values correctly. (223) (256) -
Preserve array-of-object tag entries in
extractTagChipsβ Tag field values stored as arrays of objects (e.g.[{ value: "foo" }]) were silently dropped byextractTagChipsbecause the function only handled flat string arrays. This caused tag chips to render as empty in the dashboard UI for seeds using object-shaped tag data. (230) (255) -
Distinguish
getByKeyrejection from genuine not-tracked indeleteR2Objectsβ A transient DB error frommediaRepository.getByKeywas swallowed via.catch(() => null)and treated identically to a resolvednull(row genuinely not tracked), causing the R2 object to be silently skipped and leaked on every retry instead of surfacing as a distinct failure. The error path is now re-thrown so callers can distinguish infrastructure failures from legitimately untracked objects. (218) (253) -
Update stale
enqueuereturn-value assertions afterPromise<boolean>contract β Two test assertions still expected.resolves.toBeUndefined()from the pre-#257Promise<void>contract, failing CI on thedevsHEAD after the return type change. Updated to assert the correct boolean return values. (259)
π§Ή Housekeeping
-
Remove dead duplicate
queue.interface.ts/queue.stub.tsatpackages/coresrc root β Stale copies of the queue interface and stub files existed at thepackages/coresource root alongside the authoritative versions under the correct nested paths. Only the nested paths were ever imported; the root copies were dead code confirmed via repo-wide grep before deletion. (258) (260) -
Remove duplicate orphaned
InMemoryQueueServicefiles βapps/api/src/shared/in-memory-queue-service.tsand its test were byte-identical duplicates of the canonical version underapps/api/src/shared/services/queue/. Only the nested path is imported byqueue.middleware.ts; the root-level copies were dead code. Deleting them eliminates silent double test execution under Vitest. (224) (252) -
Remove redundant root-level queue duplicate files β
apps/api/src/shared/cloudflare-queue-service.ts, its test, andqueue-consumer.tswere dead-code duplicates of the versions undershared/services/queue/andshared/jobs/. Production code only ever imported the nested paths, causing Vitest to run the same test suite twice. The architecture doc has been updated to reference the correct paths. (221) (254)
Upgrading
This release contains no breaking changes to existing schemas or API contracts. The IQueueService.enqueue return type has changed from Promise<void> to Promise<boolean>, but no production call site depended on the previous void contract β only tests and doc comments referenced it. All duplicate dead-code files removed in this release were confirmed unreferenced before deletion. Upgrading is safe for all deployments.