Week 023 — Found, Both Ways

The found flow now works regardless of whether the owner knew they'd lost something.

Week of April 21, 2025

Progress

The found API was completed Monday: both return options — leave in place with geolocation, and meet up — are handled end to end. Tuesday covered the harder case: a finder reports an item found that the owner hasn't marked as lost yet. The backend handles this by calling reportLost() first to generate the necessary records, then calling reportFound() — the found event triggers both.

The items page got visual updates: found badges, status-based sorting, and status-colored item borders. Thursday, work started on the owner's experience — what the item page shows after an item has been found.

Friday and Saturday: map integration. The goal is to show the owner where their item was found when the finder chose leave-in-place. By Sunday, the map was working.

The Hard Part

A recursive function call produced an infinite loop. The reportFound() function calls isItemLost() after calling reportLost() to check if the state updated correctly. The check was reading currentState from the POST data — which still said STATE_SAFE — causing the condition to fail and the recursion to spin. Fixed by updating ItemDTO->copyWithLostId() to explicitly set currentState to STATE_LOST when assigning the lost ID, rather than relying on the POST to carry that.

The submit button also accumulated event listeners. Each time the user selected a different return method, a new listener was attached to the submit button without the old ones being removed. Switching from leave-in-place to meet-up would fire both handlers. Fixed by using a single submit function that branches on the currently selected return method, rather than attaching individual handlers for each option.

The map coordinate retrieval had three bugs in sequence: using method call syntax without parentheses (getX instead of getX()), longitude and latitude reversed, and window.load initialization placed at the top of the file instead of the end. Each one hidden by the previous.

Decision Made

When a finder reports an item that hasn't been marked lost, the ItemService->reportFound() method handles that case internally. The API doesn't need to know about it — it just calls reportFound() and the service layer figures out what state the item is in and responds accordingly.

Next Week

Owner experience is started. The item page shows found information, but coordinates still need to be extracted correctly from the database, and the found image needs to be pulled in and displayed.