TL;DR
- Fixed a package that ignored its own "configure your own model" setting.
- Reworked a membership signup into account-first, and squashed a UUID-vs-int comparison bug in tenant onboarding.
- Stopped a Livewire form from silently dropping data, and scrubbed PII out of gateway logs before indexing.
A busy day across a few codebases. Grouping by lesson, not by commit.
Resolve the configured model, don't hard-code it
An open-source package of mine, cleaniquecoders/media-manager, let you configure a custom media model but then called the default class statically everywhere — so your config did nothing. Fix: resolve the class-string from config at every query site, keep the base-class type hint. Full write-up in the focused post today.
Account-first beats data-first for signups
Reworked a membership application flow. Old way: collect data, create an account later. New way: account first — the applicant sets a password at apply time, and email verification becomes the signal reviewers wait on before activating. Cleaner state, fewer orphaned records, and the applicant can log back in to check status.
Related bug: a status page that never matched the reference it handed the user. If you show someone a reference number, the lookup must key on that exact value. Generate once, reuse — don't re-derive it in two places.
The classic: UUID public ID vs int internal ID
The sharpest bug of the day. A detach guard compared an int foreign key against a UUID, so it never matched and quietly did the wrong thing. This is the tax on the (good) pattern of exposing UUIDs publicly while keying relations on auto-increment ints.
public id (uuid) -> used in URLs, APIs
internal id (int) -> used in FKs, joins
bug: guard checked int_fk == uuid_string // always false
Rule of thumb: pick the identifier space per boundary and never compare across it. Route-model bind on UUID, resolve to the model, then compare on the int key.
Two more, quickly
| Area | Symptom | Fix |
|---|---|---|
| Livewire form | Data silently discarded before the action ran | Bind and pass the real form state into the invokable action; test it |
| Gateway logs | PII sitting in querystrings + upstream URIs | Redact params at ingest, derive a clean uri_path, index it as a keyword |
The logging one is a reminder that observability is a privacy surface too: scrub before it lands in the index, not after.
Takeaway
Most of today was one shape of bug in different clothes: two things that should be the same value drifting apart — config vs hard-coded class, shown reference vs looked-up reference, uuid vs int. Cheap to fix once you name it, expensive when it fails silently.
Top comments (0)