TL;DR On a deployment platform: added a real nginx reverse-proxy tier with health gating, provider capability enforcement, a standard blueprint library, and release rollback. On a CRM app: shipped email automations (journeys) — trigger-based sequences with enrollment and send tracking — plus organisation member management. Squashed a sharp multi-tenancy bug: self-registered users were created without a tenant, so they couldn't create anything. Two repos, same class of fix. Two products moved meaningfully today (plus a dependency bump elsewhere). Honest rundown below. Deployment platform: routing and safety rails The headline is a tier-3 reverse proxy — a real nginx layer in front of workloads, with routing gated on workload health so traffic only reaches something that's actually up. Around it: infra providers now enforce capabilities (a provider advertises what it can do via a checklist, and the platform refuses operations it can't back), a standard blueprint library with MySQL/MariaDB provisioners, and release rollback so a bad deploy has a way home. I also fixed two gotchas from spawning docker/kubectl out of PHP — the 30s web-request timeout and the empty-environment trap. That earned its own focused post today, so I won't repeat it here. CRM: email journeys The big feature is email automations — call them journeys or sequences. A contact hits a trigger (a tag added, a form submitted), gets enrolled, and walks through timed email steps. The design leans on the usual suspects: Piece Role Enums (SequenceTrigger, SequenceStepType, SequenceSendStatus) Typed state with label()/color() Listeners on domain events Enroll a contact when a tag is added Send-status sync from mail events Keep each step's delivery state honest Modelling the send as its own tracked entity — not just "fired and forgot" — is what makes the sequence auditable later. The bug worth naming: a missing tenant Same shape landed in two apps today. Self-registered users were being created without a tenant assignment, so downstream every "create a record" call failed — the record had nowhere to live. The fix is to make tenant assignment part of user creation, not an afterthought. // in the create-user action, not left to chance later $user->tenants()->attach($tenant->id, ['role' => 'owner']); Enter fullscreen mode Exit fullscreen mode Lesson I keep relearning: in a multi-tenant app, "which tenant?" is not a later question. If a user can exist without one, some code path will find that gap. What's next Wire the reverse-proxy tier to real health checks end-to-end, and put the email-journey enrollment under a proper Pest suite before it touches live contacts.
Dev Log: 2026-08-05 — reverse proxies, email journeys, and a tenant that wasn't there
Full Article
Original Source
Read the full article at Dev →KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.