Location privacy

Your location is never pinpointed

This was a founding constraint. Everything around location was designed to ensure the precise place where you lost or found something cannot be inferred by other users.

You submit a report

The device location is captured at submit time. It is a precise GPS coordinate at this point.

Server coarsens it

A server-side function rounds the coordinate to a grid cell and runs reverse geocoding to produce a neighbourhood-level label.

Only the label is public

Discovery shows the coarse label — a neighbourhood, district, or city block. The precise coordinate is never returned by any public query.

Precise point is deleted

After an item is returned or closed, a scheduled job nulls the precise coordinate after the retention window. The coarse label stays.

Privacy architecture

Four pillars

Two-tier location

Your precise coordinates are captured once — at the moment you submit a report — and stored server-side. What other users see is a coarse neighbourhood-level label, never a pinpoint. After the item is returned or closed, the precise coordinate is automatically deleted after a configurable retention window. The coarse label stays for reference.

Ownership verification, kept private

When you report a found item, you write a private description that only the true owner would know. When someone claims it, they answer your questions privately. Your "answer key" is never shown to the public, other claimants, or anyone except you. A claimant's answers are visible only to you, the reviewer.

Three data privacy tiers

Every item has three distinct layers of data. The first layer is public: category, approximate area, date, title, description, photos. The second layer is private: the detailed verification information. The third layer is private-to-owner: your contact details, precise location, and account info. Layers two and three are enforced at the database level, not just the application.

Chat only after acceptance

Private messages exist only once a claim is accepted. You cannot send an unsolicited message about any item. Once opened, the chat is visible only to the two participants, and it closes automatically once the return is confirmed.

Authorization is enforced at the database, not the app

Every table in the Lost&Found database has Row Level Security (RLS) enabled with a default-deny policy. The app code cannot bypass it. If the database rule says a user cannot read a row, no application path — regardless of whether it contains a bug — can return that row. Private verification details, exact coordinates, and private conversations each have their own narrowly scoped policies.

This approach, called "defense in depth," means we do not rely on the app never making a mistake. The database is the final, enforced gate.

Stack

What it's built with

Layer Technology Note
App React Native + Expo (iOS & Android) TypeScript throughout, strict mode
Navigation Expo Router — file-based routing Typed deep links for claims and conversations
Backend Supabase (Postgres + Auth + Storage + Realtime) Single managed backend for V1
Database PostgreSQL + PostGIS All authorization enforced via Row Level Security
Auth Email OTP — no passwords, no phone Session stored in device keychain / keystore
Geocoding Mapbox (server-side only) App never calls Mapbox; token is server-only
File storage Supabase Storage, private buckets Short-lived signed URLs; direct public links do not exist

Map data attribution

Neighbourhood-level area labels are derived from Mapbox and OpenStreetMap data. Reverse geocoding runs server-side only — the app itself never calls Mapbox, and the Mapbox API key is never present in the client.