Week 019 — Routing Exposes an Architecture Problem

A feature that looks simple on the surface required digging into how the whole application handles routing.

Week of March 24, 2025

Progress

The found item flow needs a clean URL — when a finder scans a QR code, they should land on a page like /found/1234-5678-ABCD, not a query string. That required .htaccess configuration to route requests through a root entry point, plus a found page that can display the item's image to confirm to the finder what they've picked up.

By Thursday, the found page was loading and showing the item image. The QR code validation logic and routing rules were in place. Absolute paths replaced relative ones in CSS and image references, which had been breaking when the URL didn't start from the expected directory.

Also fixed a bug in the owner-finds-own-item flow: the item was being marked as "found" rather than "safe" when the owner reported it themselves. Found means it's been picked up by someone else but not yet returned. If the owner finds their own item, it goes straight to safe. That distinction hadn't been applied correctly to the self-found case.

The refactoring continued — more code converted to the DTO/Service/Repository pattern, the Database singleton class adopted more broadly.

The Hard Part

Getting the routing right took most of the week. The .htaccess file in the API directory that was tested first turned out not to be the right place — the relevant routes needed to be in the root. Once that was clear, the actual configuration was straightforward: a rewrite rule that sends unknown paths to index.php, which then dispatches based on the URL pattern.

But routing exposed a bigger issue. The login check lives in the header file, which every page includes. The header checks the URL to determine whether to enforce login. Under the new routing model, the URL path no longer contains the page name — it's just /found/... — so the check fails. The header can't tell what page it's on.

Decision Made

Session validation is being distributed to each page and API individually rather than handled centrally in the header. The central approach was convenient but fragile — it meant the header needed to understand every possible URL pattern in the application, which gets worse as the app grows. Individual page-level checks are more maintenance to write initially, but they're explicit and can't be broken by routing changes they don't know about.

Next Week

Routing is working. Session validation is being migrated to individual pages. Once that's stable, the full found item flow — from QR code scan through the found page through owner notification — can be tested end to end.