Catering budgets are saved** (#1508). A budget entered on the storefront catering form was stored as $0. The field is now "Budget ($)" and takes a single amount (up to two decimals), which is saved as typed; a range such as "$500 - $1000" is refused with a message instead of being saved as $0. Product import, the onboarding price step and the seeders also pass Money now, with no change in behaviour.
Past-due grace counts from the first failed renewal** (#1510). A bakery whose subscription renewal fails keeps access for 7 days. Before, the 7 days restarted whenever Stripe sent any later update for that subscription (a retry, a card change), so the grace could run on indefinitely. A new `subscriptions.past_due_since` column records when the subscription first went past due; it is cleared when the subscription is paid or ends.
Catering deposits recorded to the exact cent** (#1509). Deposits paid through Stripe Checkout (both the success page and the Connect webhook) are now passed as whole cents instead of converted to dollars and back, so the recorded amount always matches what Stripe charged.
No hard-coded Forge server for custom domains** (#1503, #1502, #1505). The bakery custom-domain settings no longer fall back to the old server's IDs and IP when a value is missing; production sets all five `FORGE_*` values. The operations docs now describe production on the company Forge server, and the test suite has its own Forge server IP.
Shared code-quality package** (#1506, #1507). Pint, Rector, PHPStan and the Pest quality plugins now come from `infinity-digital-llc/laravel-code-quality` 0.4 (development only). The `StripTagsCast` tests now save and reload each column instead of reading the model's cast list, and there is a new `composer test:profile` script.
Stripe webhook tests** (#1511). Requests with no Stripe signature are proven refused on both webhooks, and a catering deposit paid through a bakery's Connect account is proven recorded. Tests only.
Migrations:** one central migration, `2026_11_03_100000_add_past_due_since_to_subscriptions_table`: adds a nullable `past_due_since` timestamp to `subscriptions` and fills it from `updated_at` for subscriptions that are past due now (none in production on 2026-11-03). No tenant migrations.
Dependencies:** development tooling only (`infinity-digital-llc/laravel-code-quality` ^0.4 replaces the individual Pint, Rector, Larastan and Pest plugin entries). No production package changes.
Configuration:** `config/services.php` `forge.*` no longer has defaults. Production already sets `FORGE_API_TOKEN`, `FORGE_ORGANIZATION`, `FORGE_SERVER_ID`, `FORGE_SITE_ID` and `FORGE_SERVER_IP` (checked 2026-11-03). `.env.example` lists them. `VERSION` changes to `v1.62.4`.
Follow the standard deployment checklist in [Operations](../operations.md#deployment-and-release).
After deploying: `/up`, `current/VERSION` reads `v1.62.4`, `php artisan migrate:status` shows no pending central migrations, and the `subscriptions` table has the `past_due_since` column.
v1.62.3Nov 1, 2026
v1.62.3 - Tax Export downloads work again
Tax Export downloads** (#1504). Pressing "Download CSV Export" on Finance → Tax Export failed for every bakery with "A valid tax year and export type are required" (an error page), whichever type was chosen. It had done this since v1.34.0 (#668). The "What to Export" choice reaches the page as one of the export types, and the download only accepted plain text. It now accepts both, and the form starts on "All" the same way. New tests press the real button for every export type; the old ones called the download directly with plain text, so they never saw the bug.
Migrations:** none.
No new environment variables, configuration values or dependencies. `VERSION` changes to `v1.62.3`.
Hotfix: squash-merged into `main` from `hotfix/tax-export-download`; `develop` is left alone and receives the fix at the next release.
Follow the standard deployment checklist in [Operations](../operations.md#deployment-and-release); production is promoted with a Forge deployment of `main` on the company server `infinity-digital`.
After deploying: `/up`, `current/VERSION` reads `v1.62.3`, and a bakery's Tax Export downloads a CSV.
Hotfix PR #1504: 9 of 9 checks green on `e8fa699`; independent review passed (the new tests fail without the fix). Push CI on `main` (`0571318`) green.
Production: Forge deployment 81769581 on infinity-digital finished; `VERSION` reads v1.62.3 at `0571318`; `/up` returns 200; queue worker and Nightwatch restarted on the new release.
A bakery Tax Export generated on production with the form's enum value: `tax-export-2026-all.csv`, 200.
The first deployment (81769523) activated the release but stopped on a deploy-script comment that named a Forge macro; the comment was reworded and the redeploy ran to the end.
v1.62.2Oct 31, 2026
v1.62.2 - Security updates and exact-cent money
Security update** (#1496). `symfony/mime`, which builds every email the app sends, moves from 8.1.7 to 8.1.10, the first version with the fix for CVE-2026-45070 (medium, published 2026-10-28). Emails look and send the same.
npm security update** (#1501). `follow-redirects` (pulled in by `axios`, used only to build the frontend) moves from 1.16.1 to 1.16.2 for GHSA-mrwp-f3q8-3g9p (high, published 2026-10-31). `package-lock.json` only; the built app is unchanged.
Backwards dates are refused with a message** (#1495). On the Reports page, the sales, customer and product reports now show "The end date must be on or after the start date." when the end date is before the start date (or a date is blank), and clear the old report. Before, they silently showed an empty report. The Tax Export page makes the same check on its "To" field; a blank date there still falls back to 1 Jan or 31 Dec of the tax year.
Money kept in exact cents** (#1492). Coupon discounts, catering deposits, gift card redemptions and credits, and discount reversals on deleted orders now pass whole cents instead of decimal dollars. One deliberate rounding fix: a percentage that lands exactly on a half cent now rounds up (10% off $0.35 is $0.04, was $0.03). About 0.3% of percentage discounts and suggested catering deposits move by one cent, almost always one cent more off. A subtotal sent with a fraction of a cent is rounded to whole cents before a coupon's minimum-order check.
Changelog reads from the renamed repository** (#1497). The public changelog now asks GitHub for releases from `Infinity-Digital-LLC/kneadit-webapp` directly instead of relying on two redirects from the old name.
Internal cleanup** (#1493, #1494, #1498, #1499). Four result classes moved from `app/ValueObjects` to `app/Data`, a stray file from #1360 and the unused `bin/agent-verify` script were removed, and the agent skills were trimmed to KneadIt-specific rules. No behaviour change.
No new environment variables or configuration values. `VERSION` changes to `v1.62.2`.
Production now runs on the company Forge server (`infinity-digital`), moved 2026-10-31; push-to-deploy is off there, so production is promoted with a Forge deploy after the release merges.
Follow the standard deployment checklist in [Operations](../operations.md#deployment-and-release).
After deploying: `/up`, `current/VERSION` reads `v1.62.2`, `composer show symfony/mime` on the server reports 8.1.10, a bakery's Reports page shows the message for a backwards sales report range, and the public `/changelog` page loads.
v1.62.1Oct 26, 2026
v1.62.1 - One checkout session per order
One checkout session per order** (#1489). Pressing Pay now again (a second tab, the back button, a retried request) or opening the catering deposit link twice could create two Stripe checkout sessions. Only the last one was matched to the order, so paying the other charged the customer while the order stayed unpaid. A short lock per bakery and order now lets one request at a time find or create the session, and the second request reuses it. A request that waits more than 10 seconds gets the same answer as when Stripe is unavailable. Production logs showed no case of this having happened.
Coverage and TIA baseline on the Mac Studio runner** (#1488). Both jobs had stopped running on GitHub's hosted runners. They now run on the Studio with Herd's bundled Xdebug. The nightly TIA job reads its workflow from `main`, so it starts passing with this release.
Tests** (#1487, #1490). The setup wizard browser test puts the weekly schedule back afterwards (it closed Sundays for the order-form tests and failed Browser Smoke on v1.62.0's tag). The Stripe webhook controller tests send signed events through the real routes and Actions instead of faking them.
Migrations:** none.
No new environment variables, configuration values or dependencies. `VERSION` changes to `v1.62.1`.
The checkout lock uses the cache store's locks (Redis in production); nothing to configure.
Follow the standard deployment checklist in [Operations](https://github.com/Infinity-Digital-LLC/kneadit/blob/v1.62.1/docs/operations.md#deployment-and-release).
After deploying: `/up`, `current/VERSION` reads `v1.62.1`, a bakery's order confirmation page with an unpaid card order still opens Stripe checkout from Pay now, and the next Pest TIA Baseline run on `main` succeeds.
v1.62.0Oct 25, 2026
v1.62.0 - Customer fixes and maintenance mode
Signed-in customers** who open a guest-only page (sign in, register, password reset) on a bakery site now go to their account page instead of the platform's billing page (#1467).
Favourites** of products a bakery has switched off no longer show on the storefront or the account dashboard (#1466).
Reviews API** honours `product_id`; an empty value means no filter (#1468).
Opening hours** must close after they open, and an open day needs both times (#1476). The hours entered during onboarding now fill in the weekly schedule (#1485).
Gift card codes** match whatever the case, spaces or dashes (#1470).
Expenses** accept only whole-number business percentages (#1472).
Money** shows negative amounts as `-$1.50`, and on-screen money is formatted one way everywhere (#1474).
Bakery health** scores the same on the comparison page, the Bakery Insights health tab and the churn alert, using the latest staff activity (#1473).
Storefront home page** visits are now counted in analytics (#1447). The rewards page loads free-product rewards correctly (#1452).
Tools menu:** the two "Shopping List" pages are now **Ingredient Needs** and **Supplier Orders** (#1420).
robots.txt** is served by the app, so bakery sites no longer point crawlers at the platform sitemap (#1479).
Percentages** must be between 0 and 100; an out-of-range sale, deposit or birthday setting falls back to its default with a warning. Production had none (#1478).
Maintenance mode** now works: the central Maintenance Mode page can take the storefront, bakery admin or API offline on bakery sites with a 503. The platform host, webhooks and links from emails (unsubscribe, invitations, deliveries) are never blocked (#1448).
Local tenant auto-heal** recreates a missing tenant database in local development without warnings (#1449).
Console commands** (#1445): `tenants:change-subdomain`, `customers:backfill-referral-codes`, `activity-log:redact-secrets`, `images:copy-private-to-public`, `tenant:import-legacy-bakery`, `stripe:create-products` and `platform:create-promo` refuse to run without `--dry-run` or `--force`. `images:copy-private-to-public --apply` is now `--force`. Only staff run these; no bakery is affected.
Code conventions (#1426–#1442, #1450–#1459): data objects in `app/Data`, builders, actions with `handle()`, order guards and locks in `app/Lifecycle`, services that only read, Stripe/PayPal/checkout/engagement/loyalty writes moved into actions, observer side effects dispatched as after-commit events, renamed listeners and mailables, final exceptions, rules in domain folders.
Tests (#1443–#1446, #1460–#1465, #1471, #1481, #1482): middleware and controller Feature tests through real routes, a frozen clock, no framework in Unit tests, factories everywhere, `Double::for` instead of Mockery.
CI runs on the self-hosted Mac Studio runner (#1483); dependency security updates (#1432, #1435) and Livewire 4.4.8 were already shipped in v1.61.5.
Migrations:** none.
No new environment variables, configuration values or dependencies. `VERSION` changes to `v1.62.0`.
Before deploying:** in Forge, change the `location = /robots.txt` line in `app.getkneadit.app`'s nginx config to `location = /robots.txt { try_files $uri /index.php?$query_string; access_log off; log_not_found off; }`. Without it `/robots.txt` answers 404 once `public/robots.txt` is gone (see [Operations](https://github.com/Infinity-Digital-LLC/kneadit/blob/v1.62.0/docs/operations.md#runtime-services)).
Deploy with the queue empty.** Listeners and mailables were renamed (#1437, #1438) and digest data changed, so a job queued under an old class name would fail. Deploy away from the top of the hour, when the scheduler queues sends.
Follow the standard deployment checklist in [Operations](https://github.com/Infinity-Digital-LLC/kneadit/blob/v1.62.0/docs/operations.md#deployment-and-release).
After deploying: `/up`, `current/VERSION` reads `v1.62.0`, `https://app.getkneadit.app/robots.txt` answers 200 and lists the app sitemap, a bakery's `/robots.txt` returns 404, and the bakery Tools menu shows Ingredient Needs and Supplier Orders.
v1.61.5Oct 25, 2026
v1.61.5 — Recipe tools and reorder totals
Reorder Reminders** (Growth plan). Each customer's "Total Spent" and the "Revenue at Risk" figure now show real dollars. Orders of $25 and $35 appeared as $6,000.00 and now show $60.00.
Recipe Cost Calculator** (Growth plan). Choosing a recipe now shows its ingredients, total cost, current margin and suggested price instead of an error. When a product has several recipes, the calculator uses the recipe you picked, and changing the target margin updates the suggested price. The recipe list no longer re-queries each product for every row.
Price Suggestion** (Pro plan). Choosing a recipe now shows the pricing table, including profit per unit at each margin, instead of an error. When a product has several recipes, the current margin and profit use the recipe you picked.
Recipe costs.** The calculator and Price Suggestion now use a recipe's saved cost when it has one, and add up its ingredients otherwise. Until April they always added up the ingredients.
Dependency updates.** Livewire moves from 4.4.5 to 4.4.8, a patch release with a security fix. The build tools also take two security updates already on `develop`: follow-redirects 1.16.1 and Vite 7.3.7.
Checks.** Automated checks now run on a self-hosted machine instead of GitHub's hosted runners. Nothing changes in the app.
Migrations:** none.
No new environment variables or configuration values. `composer install` picks up Livewire 4.4.8. `VERSION` changes to `v1.61.5`.
Follow the standard deployment checklist in [Operations](../operations.md#deployment-and-release).
After deploying: `/up`, `current/VERSION` reads `v1.61.5`, and a Growth bakery can open Reorder Reminders, Recipe Cost Calculator and Price Suggestion and select a recipe.
Hotfix PR #1475: all 9 checks green on 27bad3d6; independent review passed.
`main` CI on 84ee5569: Tests, PHPStan, Pint, Type Coverage, FilaCheck and Security Scan passed (Pest TIA Baseline, a hosted-runner record job, did not run).
Production (2026-10-25 12:26 UTC): `current` is 84ee5569, `VERSION` reads v1.61.5, `/up` 200, no pending migrations, queue worker, scheduler and Nightwatch agent on the new release, no new errors or failed jobs.
v1.35.0Aug 30, 2026
v1.35.0 — application and CI hardening
Application, tenancy, storage, and deployment improvements
Expanded Pest coverage and consolidated validation matrices
PHPStan, Rector, type coverage, security, and CI hardening
v1.33.1May 5, 2026
v1.33.1 — settings persistence patches
fix(settings): persist paypal credentials regardless of payment method by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/569
fix(settings): persist 10 keys silently dropped by SaveTenantSettings by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/570
test(settings): regression guard for form ↔ action key parity by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/571
chore(types): restore 100% type coverage on closure parameters by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/572
release: v1.33.1 — settings persistence patches by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/573
fix: post-release nitpick sweep — Chart.js, Alpine pin, throttle limiters, CSP -elem/-attr, restock test by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/562
test(register): tighten central tenant-registration coverage end-to-end by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/563
fix(tenants): make CreateTenant atomic across the central + tenant-DB boundary by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/564
release: v1.32.1 — CreateTenant atomicity + registration hardening by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/565
v1.32.0May 5, 2026
v1.32.0 — broad test coverage sweep + security/perf/refactor consolidation
refactor(admin): brand-token rebrand for Referral Program + Page Content by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/536
refactor(admin): structured delivery-tier repeater + dashboard-config brand rebrand by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/537
fix: deep-review ship-blockers (money-cast × 2 + email XSS) by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/538
perf(storefront): eager-load primaryImage and seasonalItems in category builders by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/539
security(filament): wire ->authorize() on tenant-admin destructive actions by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/540
refactor(storefront): extract storefront-controller queries onto builders by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/541
perf(central): eager-load tenant on central admin tables to fix N+1 by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/542
security(filament): add missing CustomerCampaignPolicy by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/543
refactor: sweep inline where() onto Customer/Cart builder methods by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/544
refactor(filament): drop ->value on enum defaults; SelectFilter -> TernaryFilter for booleans by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/545
test(filament): smoke coverage for 4 manager-facing analytics/billing pages by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/546
test(filament): smoke coverage for the last two untested tenant pages by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/547
test(http-requests): validation coverage for 5 high-traffic storefront FormRequests by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/548
fix(tests): clear 63 failing/errored tests across the suite by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/549
test(http-requests): validation coverage for the 5 Order/* FormRequests by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/550
test(http-requests): validation coverage for the 4 password-flow FormRequests by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/551
test(http-requests): validation coverage for the remaining 9 storefront/central FormRequests by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/552
test(http-requests): validation coverage for the 10 Api/* FormRequests by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/553
test: feature coverage for CateringStripeSuccessController by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/554
test(api): deepen coverage on the 4 thinnest API controller tests by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/555
test: feature coverage for CustomerDashboardController by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/556
test(filament): end-to-end bulk-delete coverage on three representative tables by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/557
test: cover the hash-mismatch branch in CustomerEmailVerificationRequest by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/558
refactor(filament): extract ManageSettingsForm sections into per-topic classes by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/559
fix(events): wire NotifyBakerOfWaitlistJoinListener so the baker actually gets notified by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/560
release: v1.32.0 — broad test coverage sweep + security/perf/refactor consolidation by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/561
feat(contact-messages): in-app reply thread + admin polish by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/532
fix(dashboard): TodaysOrdersWidget slot collision + admin polish by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/533
fix(homepage-builder): pad collapsed count selects by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/534
release: v1.31.0 — contact-message reply thread + dashboard hotfix by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/535
v1.30.0May 5, 2026
v1.30.0 — catering quote line items + dashboard redesign
chore: merge v1.29.0 release into develop by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/524
feat(catering): line-item editor for quotes by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/525
feat(catering): line-item editor for quotes by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/526
fix(catering/inquiry): hide quote/booking/deposit actions on cancelled inquiries by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/527
feat(dashboard): finish widget thumbnail-parity initiative by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/528
feat(dashboard): full redesign — surface palette, new widgets, audit log, ARPU, label generator rebuild by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/529
release: v1.30.0 — catering quote line items + dashboard redesign by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/530
v1.10.3 — full audit pass + UseFactory attribute migration
#171** migrate all 62 models from the legacy `newFactory()` static method to the declarative `#[UseFactory(SomeFactory::class)]` attribute (Laravel 11+). Net diff: 62 files, +124/−310.
Models are strictly relationships + casts + factory wiring.** No business logic, no routing concerns, no factory boilerplate.
All 6 presenters use the same `Presenter::for($model)->method()` shape.**
ViewModel scope is now codified in arch tests** so future regressions can't sneak past CI.
Test organization is clean** — Unit really means "no DB" now, enforced by an arch test.
TenantSettings sub-DTO migration is fully complete** with `GiftCardSettings` as the last holdout.
#153 move LoyaltyPageViewModel construction into named factories
#154 ReviewsPageViewModel owns assembly; controller becomes a one-liner
#155 GalleryController passes loose vars directly; no ViewModel
#156 drop ReviewsPageViewModel::build() factory
#157 move Loyalty reward query out of VM factories into controller
#158 standardize all presenters on `Presenter::for($model)->method()` pattern
ViewModels stay pure.** `build()` static factories that ran DB queries are gone. Controllers reclaim ownership of data fetching; VMs are data shapes (no DB inside).
`GalleryPageViewModel` deleted entirely** — it was a typed struct with no display computation, which the Laravel community (Roose, Pichler, De Deyne) does not consider VM-worthy.
Single Presenter pattern across the codebase.** All six classes in `app/Presenters/` are now invoked the same way: `Presenter::for($model)->method()`. The model-accessor delegation pattern is retired — it required per-method boilerplate on the model and was already an outlier.
`LoyaltyReward` model is now strictly relationships + casts + factory** — matching the project's "clean models" rule.
v1.10.1Apr 20, 2026
v1.10.1 — widget caching, DTO finalization, factory state sweep
FinancialCalculator::monthlyBreakdown reduced from 36 queries to 3 (#94)
DB-doing accessors removed from Product and Recipe (#75)
Unused `hasAccess` accessor dropped from User (#80)
Boost project skills extracted from CLAUDE.md (kneadit-filament-5, kneadit-tenant-settings, kneadit-mailables); CLAUDE.md trimmed by ~50 lines
7 preexisting PHPStan errors fixed (#82)
DescriptionGeneratorService templates moved to config (#78)
ManageSettings defaults centralized (#84)
v1.0.0Apr 18, 2026
v1.0.0
refactor: apply audit cleanups to User model, analytics writes, and central stats view by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/46
refactor: replace LogsActivity trait with LogsActivityObserver by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/47
refactor: move Customer metrics to CustomerPresenter by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/48
refactor: replace OrderStatusEffectDispatcher with domain events by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/49
refactor: remove no-op eventTypeLabel accessor on CateringInquiry by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/50
refactor: extract SlideOverEditAction for tenant tables by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/51
fix: close loyalty credit race and dedupe inline margin calcs by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/52
refactor: split ProductFinancialService into three focused services by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/53
fix(phpstan): resolve model Builder docblock class-not-found errors by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/54
fix(phpstan): drop unnecessary nullsafe operators by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/55
fix(phpstan): drop stale `@method` factory() docblocks on all models by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/56
fix(phpstan): resolve property.notFound via docblocks and type narrowing by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/57
fix(phpstan): narrow route-binding unions and nullable-return accesses by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/58
fix(phpstan): misc type fixes from the remaining long tail by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/59
fix(phpstan): drain the long tail — Str::replace, Category with(), custom-builder closures by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/60
fix(phpstan): zero baseline — project is clean at level 8 by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/61
feat(api): render API exceptions as JSON:API 1.1 error documents by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/62
feat(api): convert StoreInfoResource to JSON:API format by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/63
chore: post-refactor audit cleanups (plans 13/14/15) by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/65
feat(api): convert remaining read endpoints to JSON:API by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/66
feat(api): complete JSON:API migration — write endpoints + missed reads by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/67
chore: remove legacy landing/ folder, migrate contact form to Laravel by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/68
chore: add brand mascot SVG to public/images/ by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/69
feat: printable compliance labels with allergen disclosure by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/70
feat: customer accounts on the storefront by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/71
feat: password reset for customer accounts by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/72
feat: email verification + guest-order claim flow by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/73
Release: JSON:API migration, customer accounts, allergen labels, PHPStan zero baseline by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/74
v0.5.0Apr 18, 2026
v0.5.0
feat: add customizable email templates for Pro tenants by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/32
feat: make gift card preset amounts configurable per tenant by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/39
feat: make catering event types configurable per tenant by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/40
feat: make order journey steps configurable per tenant by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/41
feat: configurable storefront microcopy (#36) by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/42
feat: make hero tagline and CTA button text configurable by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/43
feat: add minimum order amount settings for pickup and delivery by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/44
Release: catering event types, gift card presets, and Pro email templates by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/45
v0.4.0Apr 18, 2026
v0.4.0
chore: add ui.sh MCP server configuration by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/29
Improve storefront UI accessibility, theming, and polish by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/30
v0.3.0Apr 18, 2026
v0.3.0
refactor: full app audit — test reorganization and CI workflows by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/28
v0.2.0Apr 18, 2026
v0.2.0
Laravel 13.x Shift by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/18
Fix registration checkbox styling and SubscriptionTier casting by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/19
Fix SubscriptionTier enum casting issues by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/20
Add HasIcon to OrderStatus, CateringInquiryStatus, and SocialPostStatus enums by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/21
Extract SendEmailListener base class to reduce listener boilerplate by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/24
fix: merge duplicate birthday engagements into single flow with coupon toggle by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/22
refactor: full application architecture audit (rounds 1-12) by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/25
feat: extract hardcoded strings into lang files for auth, error, and invitation pages by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/26
Merge develop into main by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/27
v0.1.0Apr 18, 2026
v0.1.0
Fix Ward security scan findings by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/3
Auto-confirm pre-paid orders when payment succeeds by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/2
Add discount ledger with coupon transactions and gift card tracking by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/5
Reverse coupon and gift card discounts on order cancellation by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/6
Classify order status effects as critical or non-critical by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/7
Add Cache::flexible() to expensive dashboard widgets by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/8
Centralize tenant context switching through TenancyManager by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/9
feat: discount system follow-ups from unified ledger work by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/11
refactor: extract Onboarding wizard into self-contained step classes by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/12
Test suite audit, coverage, and bug fixes by @JeffreyDavidson in https://github.com/JeffreyDavidson/kneadit/pull/17