Skip to content

BeechCMS v0.6.4

Choose a tag to compare

@fdemusso fdemusso released this 21 Jul 20:16
· 109 commits to master since this release

Release Date: July 15, 2026


πŸ› Bug Fixes

  • Surface queue enqueue failures instead of silently dropping oversized payloads β€” CloudflareQueueService.enqueue caught queue.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.enqueue now returns Promise<boolean> instead of Promise<void>: CloudflareQueueService returns false on transport failure, InMemoryQueueService returns false when no handler is registered, and NoOpQueueService always returns true. (220) (257)

  • Guard InMemoryQueueService handler 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 by extractTagChips because 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 getByKey rejection from genuine not-tracked in deleteR2Objects β€” A transient DB error from mediaRepository.getByKey was swallowed via .catch(() => null) and treated identically to a resolved null (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 enqueue return-value assertions after Promise<boolean> contract β€” Two test assertions still expected .resolves.toBeUndefined() from the pre-#257 Promise<void> contract, failing CI on the devs HEAD after the return type change. Updated to assert the correct boolean return values. (259)


🧹 Housekeeping

  • Remove dead duplicate queue.interface.ts / queue.stub.ts at packages/core src root β€” Stale copies of the queue interface and stub files existed at the packages/core source 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 InMemoryQueueService files β€” apps/api/src/shared/in-memory-queue-service.ts and its test were byte-identical duplicates of the canonical version under apps/api/src/shared/services/queue/. Only the nested path is imported by queue.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, and queue-consumer.ts were dead-code duplicates of the versions under shared/services/queue/ and shared/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.