Version 5.3.14
No database schema changes; schemaVersion remains 5.3.0.
Changed
- Setup UX refresh: modernized onboarding visuals for Project, Integrations, Craft Commerce setup, and Review steps with improved spacing, status chips/cards, richer guidance, and plugin icon usage.
- Project step selection UX: clicking anywhere on a project row now selects its radio option, and the current project (or first row) is auto-selected by default.
- Dashboard snapshot refresh flow:
Refresh Snapshotnow supportsreturnTo=dashboardso dashboard refresh no longer redirects users to Setup Review.
Fixed
- Freeform realtime submissions: forms events now include required routing metadata (
organizationId,clientId) inbuildFormsSubmissionEvent(), fixing Burrow API rejections likeMissing required field: organizationId. - Dispatch auth fallback: dispatch clients now correctly fall back to the account API key when ingestion key is empty, avoiding empty-auth 401s on backfill/dispatch paths.
- Outbox source filtering: element index source criteria and query status handling now treat Outbox statuses (
pending,retrying,failed,sent) as first-class; All no longer collapses to only enabled/sent rows. - Outbox default ordering: Outbox element query now defaults to newest-first (
outboxCreatedAt DESC) for consistent recency ordering. - Outbox implicit sort override: when Craft applies an implicit default
id ASCsort, the query now overrides it to newest-first (outboxCreatedAt DESC,elements.id DESC) so default list order is never oldest-first. - Outbox sort guard: fixed a type-casting crash when Craft supplies
OrderByPlaceholderExpressionvalues inorderBy; default-sort detection now ignores non-scalar direction values safely.
Version 5.3.13
No database schema changes; schemaVersion remains 5.3.0.
Added
DeliverOutboxRowJobqueues delayed republish of a single outbox row for automatic retries and manual retry.- Outbox slide-out (element editor): “Delivery” section explains the retry cap and adds Retry now when Burrow is dispatchable, plus optional return to the same editor after POST.
Changed
- Outbox delivery now uses up to six attempts by default (aligned with the WordPress plugin). Failed realtime sends move to
retrying, schedule backoff jobs, andmarkSentno longer inflates the attempt counter on success. retryNow()resets attempts, clears the last error, and pushes the delivery job so retries actually run (previously only flipped status topending).- Backfill batch failures call
markFailedwith no automatic outbox retry queue, avoiding a storm of per-event jobs. SettingsController::actionRetryOutboxacceptsreturn=burrow/outbox/{id}for redirects from the slide-out.BurrowApiService::createClientaccepts optional runtime scope overlay so SDK client state matches DB runtime (projectId, ingestion key, forms source id). This keeps realtime/api/v1/eventsrouting consistent with backfill when persisted SDK state lags.publishEventssurfaces the last exception message when all publishes fail instead of a generic message only.
Version 5.3.12
No database schema changes; schemaVersion remains 5.3.0.
Fixed
- Freeform realtime dispatch no longer gates on
Form::isValid(). Freeform can leave the internal$validflag false after a successful DB save, which caused the handler to return before publishing to Burrow.
Changed
- Diagnostics: when a forms submission envelope cannot be built (missing project or forms source id), the plugin now logs a warning with context flags so misconfiguration is easier to spot.
Version 5.3.11
No database schema changes; schemaVersion remains 5.3.0.
Fixed
- Freeform front-end submissions were only observed when
SubmissionsService::EVENT_AFTER_SUBMITran (after a stored DB save). Forms with “Store submissions” disabled never triggered that path. The listener now usesSolspace\Freeform\Form\Form::EVENT_AFTER_SUBMIT, which runs after every successfulhandleSubmission()completion. Invalid, error, and spam-marked forms are skipped before dispatch. - Freeform form config lookup now falls back to
externalFormIdwhen resolving the numeric form id, so tracked forms still match if saved settings lose associative keys.
Version 5.3.10
No database schema changes; schemaVersion remains 5.3.0.
Fixed
- Commerce order status lifecycle handler was registered on
OrderStatuses::EVENT_ORDER_STATUS_CHANGE, which Craft Commerce does not define. Status changes are dispatched fromOrderHistories::EVENT_ORDER_STATUS_CHANGE; the listener is now attached there soecommerce.order.fulfilled,refunded, andcancelledfire when CP status changes.
Changed
- Lifecycle event timestamps use the order element’s
dateUpdated(Craft’s persisted save time), normalized through the existingdateValue()helper for ISO-8601 transport, instead ofgmdate('c')at handler runtime.
Version 5.3.9
No database schema changes; schemaVersion remains 5.3.0.
Fixed
- Commerce backfill: exclude incomplete carts. The backfill query now requires
isCompleted(true)in addition toisPaid(), filtering out carts that had a payment recorded but were never submitted through checkout. These incomplete carts had no Commerce order status and were inflating order counts (~41 extra orders in YTD testing).
Added
- Order lifecycle events. The plugin now emits
ecommerce.order.fulfilled,ecommerce.order.refunded, andecommerce.order.cancelledevents when an order's status changes in Craft Commerce. This enables time-to-ship metrics and accurate net-revenue reporting in Burrow. - Order status mapping in onboarding. The Commerce setup step now shows all of the store's order statuses and lets you map each one to a lifecycle state (Fulfilled / Shipped, Refunded, Cancelled). Statuses not mapped are treated as active placed orders. Custom Commerce statuses are fully supported.
- Lifecycle events in backfill. Ecommerce backfill now emits the appropriate lifecycle event alongside
order.placedwhen an order's current status maps to fulfilled, refunded, or cancelled. - Backfill probe: status breakdown. The diagnostics probe now shows a per-status order count and revenue table, plus a Year to date window preset.
- Canonical
shippingTotalproperty.ecommerce.order.placedevents now includeproperties.shippingTotal(numeric) as the canonical shipping amount, set natively via the SDK builder. The legacyproperties.shippingfield andproperties.shippingMethodduplication have been removed;shippingMethodremains in tags only. - Replay-safe
externalEventId. All order lifecycle events (placed,fulfilled,refunded,cancelled) now carry a stableexternalEventId(e.g.craft_order_123_placed) so Burrow can deduplicate on replay.externalEntityId(craft_order_123) continues to link events for the same order entity.
Version 5.3.8
No database schema changes; schemaVersion remains 5.3.0.
Fixed
- Freeform
custom_fields: Stopped merging the full Freeform submissiontoArray()payload into Burrowproperties. Events now include only the minimal envelope (formId,submissionId,submittedAt,isBackfill) plus field-contract mappings (tags/properties).providerandformNameremain in tags only, not duplicated inproperties.
Added
- Formie parity with Freeform: Per-form Off / Count-only / Custom fields in onboarding,
getFormieFields()for the mapping table, contract sync with realcustom_fields/fieldMappings, live submission events, and historical backfill all follow the same rules as Freeform (minimal envelope, mapped fields only).
Version 5.3.7
No database schema changes; schemaVersion remains 5.3.0.
Fixed
- Commerce ecommerce backfill now limits imported orders to those Craft Commerce considers paid (
OrderQuery::isPaid()), so unpaid carts and abandoned checkouts are no longer sent as order backfill events. The paid-only filter is shared with the commerce probe used for discovery counts.
Version 5.3.6
No database schema changes; schemaVersion remains 5.3.0.
Added
- CleanupOutboxRetentionJob: Saving outbox retention (including force purge with 0 days) now queues cleanup on Craft’s queue (15-minute TTR) instead of running large deletes during the CP request, avoiding PHP/web timeouts.
- Reset stuck backfill: When backfill status is Queued or Running but no queue job is actually processing (worker stopped, timeout, deploy), the dashboard offers Reset stuck backfill to mark the run failed and allow a new start.
Version 5.3.5
No database schema changes; schemaVersion remains 5.3.0.
Added
- Outbox retention
0(force purge): Saving operations settings with 0 days removes allsentandfailedoutbox rows immediately, truncatesburrow_outbox_sent(send dedupe index), and leavespending/retryinguntouched. The stored retention window is not saved as 0; the previous schedule (or default 30 days) remains.
Version 5.3.4
No database schema changes; schemaVersion remains 5.3.0.
Fixed
ecommerce.order.placedevents now includeshippingTotalandshippingMethodonproperties(Burrow activity UIs that surfacepropertieswere missing them; the PHP SDK only emits tax/subtotal there by default). Commerce payloads already carried shipping intags/ internal fields but they were not merged intoproperties.- Commerce shipping amount is read from
totalShippingCostonly (removedadjustmentSubtotalfallback, which was not shipping-specific and could misreport totals). Applies to live order tracking and historical backfill.
Version 5.3.3
No database schema changes; schemaVersion remains 5.3.0.
Changed
- During
BackfillChunkJob, outbox mirror elements are saved with Craft search indexing deferred; at the end of each job run, accumulated outbox elements are indexed once viaSearch::indexElementAttributes(), reducing search-index churn on large backfills.
Added
.gitignoreentries for.DS_Store.
Version 5.3.2
No database schema changes; schemaVersion remains 5.3.0.
Added
BackfillChunkJob— historical backfill runs through Craft’s queue in bounded chunks (configurable query pages per job) so long windows and all-time runs no longer rely on a single Control Panel HTTP request and are far less likely to hit timeouts.
Changed
- Dashboard backfill action queues the first chunk job, shows Queued / Running status, blocks overlapping starts, and reminds operators to keep a queue worker running.
forms.submission.receivedevents (live and backfill): tags emphasize the form title (formName);properties.formIdis the numeric Craft form id instead of a provider prefix (FF/FRM), for clearer context in Burrow.
Version 5.3.1
No database schema changes; schemaVersion remains 5.3.0.
Fixed
- SDK-built ecommerce envelopes (cart abandonment, cart/checkout funnel, order placed, line items, etc.) now set
sourcetocraft-pluginafter canonical builders run, so payloads and Burrow UI no longer incorrectly showwordpress-pluginfor Craft Commerce.
Changed
- Historical backfill loads submissions and orders in fixed batches, streams events to the API in submit chunks, and avoids building a single giant in-memory event list (reduces PHP memory exhaustion on large datasets).
- Backfill probe uses lightweight DB counts for form submission totals instead of materializing full event lists; ecommerce event counts still follow the same eligibility rules as backfill.
Version 5.3.0
Added
- Runtime state columns
connectionBaseUrlandconnectionApiKey(migration) so Control Panel connection can be saved whenallowAdminChangesisfalse. Plugin::getBurrowBaseUrl(),getBurrowApiKey(),getConnectionSettingsForDisplay(),canDispatchToBurrow(),runtimeStateHasIngestionKey(), andclearAccountApiKeyFromProjectConfigIfAllowed()for consistent credential resolution across CP, queue jobs, and the snapshot API.helpers/CredentialCrypto— encryptsingestionKey.keyandconnectionApiKeyat rest viaCraft::$app->getSecurity()->encryptByKey()/decryptByKey()with distinct HKDF info strings; legacy plaintext values are read until the next save re-seals them.
Changed
- Connection step persists credentials to the database first; project-config plugin settings are updated only when admin changes are permitted.
- After a successful project link, the account-level API key is cleared from runtime state (short-lived bootstrap); project ingestion key remains for ongoing API use. When
allowAdminChangesistrue, the pluginapiKeysetting is also cleared after link. getBurrowApiKey()no longer falls back to project-configapiKeywhen an ingestion key exists, so stale YAML cannot override project-scoped auth.- Forms contract submission uses ingestion-first SDK client auth (same pattern as event dispatch).
- Snapshot, heartbeat, abandoned-cart jobs, and the stack-snapshot API gate on
canDispatchToBurrow()so ingestion-only installs work without a stored account key.
Fixed
- Control Panel connection save no longer hard-depends on
allowAdminChanges; production environments with project config frozen can complete onboarding using DB-backed credentials.
Version 5.2.0
Added
- Ecommerce funnel event:
ecommerce.cart.abandoned— queue job scans for idle Commerce carts past a configurable threshold (default 120 min), emitted as a lifecycle event with deduplication onexternalEntityId. - Ecommerce funnel event:
ecommerce.payment.failed— hooks CommerceEVENT_AFTER_PROCESS_PAYMENTfor unsuccessful transactions with gateway-provided failure reasons. - Ecommerce funnel event:
ecommerce.checkout.started— detects checkout initiation when an email is first populated on an incomplete order with line items, deduped per cart. - Ecommerce funnel event:
ecommerce.cart.recovered— emitted at order completion when a prior cart or checkout abandonment signal exists for the customer. - Four new envelope builders in
BurrowApiServicewith SDK canonical builder pass-through and manual fallback. DetectAbandonedCartsJobscheduled alongside existing system jobs (30-minute cadence), gated byecommerce_funnelcapability.
Version 5.1.0
Added
- Realtime event tracking for Freeform and Formie form submissions.
- Realtime commerce hooks for completed orders and cart removal events.
- Durable Outbox pipeline — all realtime events now route through the Outbox for delivery guarantees.
- Native Craft Element Index UI for the Outbox page with condition rules, channel/event name query filters, and status badges.
- Outbox slideout detail view with configurable provider prefix for form IDs.
- Public API endpoint for remote snapshot refresh.
- CP breadcrumbs across all control panel pages.
Changed
- Aligned backfill and event assembly around SDK boundaries.
- Tightened forms backfill filtering and normalized Formie mode handling.
- Hardened Freeform realtime submission matching and field mapping.
- Populated full commerce order tags to match SDK and WordPress parity.
- Cleaned up dashboard layout and persisted project name from SDK link result.
- Refined onboarding defaults and plugin branding.
- Simplified CP page titles to avoid redundant plugin name prefix.
Fixed
- Ecommerce order envelope parity with SDK contracts.
- Outbox element index virtual attribute errors.
- Outbox slideout click handling and detail view polish.
Version 5.0.0
Added
- Initial Craft CMS 5 release of the Burrow bridge plugin.
- 5-step Control Panel onboarding flow for connection, project linking, integration setup, review, and finish.
- Burrow SDK-based discovery and link workflow for connecting a Craft site to a Burrow project.
- Integration support for
Freeform,Formie, andCraft Commerce. - Forms contract generation and contract sync to Burrow.
- System snapshot collection and publish flow for Craft and installed plugin version visibility.
- Dashboard view for linked project status, integrations, sync state, snapshot health, logs, and backfill actions.
- Outbox management screen with queue statistics plus retry and delete actions.
- Manual historical backfill workflow for form submissions and ecommerce orders/items.
- Plugin database tables for runtime state, outbox records, sent-event dedupe tracking, and operational event logs.