GPS (latitude/longitude) and photo_path are now NEVER set by seed
import pipelines, even if empty. GPS comes only from field tech
check-ins via the main app.
- db_writer.py: FIELDS_NEVER_FROM_SEED set, GPS always None in
_extract_row_values, skipped in update mode
- sync.py: latitude/longitude set to None in asset_data
- FIELD_MAP.md: updated policy table
Changes behavior: ALL fields now use ONLY_IF_EMPTY
policy for existing assets. Previously, AUTO fields (name, make, model,
company, place, building_name, floor, etc.) always overwrote existing
data, clobbering MSFS-synced and manually-cleaned records.
- db_writer.py: update() treats every field as 'skip if existing
value non-null' — same as old PRESERVE behavior but universal
- sync.py: UPDATE path now fetches current values and only sets
fields that are currently NULL/empty
- New assets (not found by machine_id) still insert with full seed data
- sync.py docstring and stats output updated to reflect new policy
Closes#13 — seed import no longer overwrites MSFS data
- New sync.py: reads seed import's 39-col schema, maps to main app's
customers/locations/assets schema with foreign keys
- New POST /api/sync endpoint (target=dev|prod, dry_run=true/false)
- New GET /api/sync/targets endpoint
- Category mapping: Bev→Beverage, Snack→Snack, Food→Food, etc.
- Automatically creates customers and locations from company/place
- Idempotent: updates existing assets by machine_id
- Dry-run mode: preview changes without writing
- Add DISNEY_AREA_MAP in parser.py mapping 40+ Disney properties to 8 resort areas
- Add disney_area to parse_customer() output, resolver after disney_park
- Update db_writer.py schema: ORDERED_COLUMNS, AUTO_COLUMNS, COLUMN_TYPES
- Add /api/status endpoint query for by_disney_area distribution
- Add area row to web dashboard UI
- Auto-migration adds column to existing databases
Parser enhancements:
- Add SUITE_PATTERNS: extract Suite, Ste, STE (case-insensitive)
- Add ROOM_PATTERNS: extract Room, RM, Mailroom, Showroom, etc.
- Add TRAILER_PATTERNS: extract Trailer, TRLR, MASH, Safari, etc.
- Add _extract_suite(), _extract_room(), _extract_trailer() functions
- Update _parse_pattern_a() to extract and strip new fields
- Update parse_place() result dict to include suite/room/trailer
- Add correct_class_by_machine_id() post-processing:
- Bev model in Bev ID range with Snack class → fix to Bev
- Unknown class in 9x range → set to Bev
- Unknown class in 6x-7x range → set to Snack
- Update parse_excel() to include new fields and apply correction
DB writer:
- Add suite, room, trailer to ALL_COLUMNS and COLUMN_TYPES
- Add ALTER TABLE migration for existing databases
- Fix backup.py PRESERVED_FIELDS column names (lat/lng -> latitude/longitude)
to match actual DB schema (pre-existing bug)
- Add backup_gps() and restore_gps() dedicated GPS-only functions
- Add /api/gps/backup and /api/gps/restore API endpoints
- Add /api/gps/restore/upload for restoring from uploaded backup files
- Add /api/db/wipe endpoint to clear all asset records
- Update UI with GPS-only Backup button, Restore GPS from File picker,
and Wipe All Assets with double-confirmation dialog
- Fix backup listing to scan both seed-data/ and project root