Construction workforce record — place comes from the reading at entry
The design started from a constraint: if the list of open sites cannot be kept current, the record cannot hang off that list. So in the data model a site is not a master row. It is two readings carried on the entry itself, one saying who scanned and one verifying where. Duration follows from a matched entry and exit, and an entry with no exit stays an incomplete row until it closes. Payment due is computed from those same pairs rather than held as a field, and hours at different points total apart. React Native (Expo) on the phone, Laravel receiving, MySQL holding.
Read the case study →