# Payfrit Beacon iOS Native Swift iOS app for provisioning iBeacon hardware at restaurant tables. Repo: `payfrit-beacon-ios` on Forgejo. ## Purpose Utility app for restaurant setup staff to: 1. Scan for nearby BLE iBeacons (iBeacon + BLE + QR code) 2. Check UUID against known bulk manufacturer defaults (ban list) 3. Assign table names to beacons (smart-incremented) 4. Provision beacon hardware via BLE GATT (DX-Smart, BlueCharm, KBeacon) 5. Save beacon + auto-create service point records via API ## Environment - **Server**: dev.payfrit.com (DEBUG) / biz.payfrit.com (RELEASE) - **API Base**: `https://dev.payfrit.com/api` (dev) / `https://biz.payfrit.com/api` (prod) - **Config**: `APIConfig.swift` — uses `#if DEBUG` compiler flag - **OTP**: Dev server uses magic OTP `123456` (no Twilio) ## Database (via API — no direct SQL) | Table | PK | Key Columns | |-------|----|-------------| | Beacons | `ID` | `UUID`, `Name`, `BusinessID`, `IsActive` | | ServicePoints | `ID` | `BusinessID`, `Name`, `TypeID`, `Code`, `SortOrder`, `IsActive`, `BeaconID` | | Businesses | `ID` | `Name`, `ParentBusinessID` | **Note**: `POST /api/beacons/save.php` auto-creates a ServicePoint when saving a beacon. ## API Endpoints Used All endpoints are `.php`. Auth = `X-User-Token` header. | Method | Endpoint | Auth | Purpose | |--------|----------|------|---------| | POST | /auth/loginOTP.php | No | Send OTP to phone | | POST | /auth/verifyLoginOTP.php | No | Verify OTP, get token | | POST | /businesses/list.php | Yes | List user's businesses | | POST | /servicepoints/list.php | Yes | List service points for business | | POST | /servicepoints/save.php | Yes | Create/update service point | | POST | /servicepoints/delete.php | Yes | Delete service point | | POST | /beacon-sharding/allocate_business_namespace.php | Yes | Allocate UUID+Major shard | | POST | /beacon-sharding/get_beacon_config.php | Yes | Get complete beacon config | | POST | /beacon-sharding/allocate_servicepoint_minor.php | Yes | Auto-assign minor value | | POST | /beacon-sharding/resolve_business.php | Yes | Resolve business by UUID+Major | | POST | /beacons/list.php | Yes | List beacons for a business | | POST | /beacons/lookupByMac.php | Yes | Lookup beacon by MAC address | | POST | /beacons/wipe.php | Yes | Decommission a beacon | | GET | /users/profile.php | Yes | Get user profile | ## Build & Deploy Build in Xcode targeting iOS 17+. No local testing — deploy to device for BLE testing. ## Project Structure ``` PayfritBeacon/ ├── App/ │ ├── AppPrefs.swift UserDefaults keys │ ├── AppState.swift ObservableObject — auth state, nav, business selection │ └── PayfritBeaconApp.swift App entry point ├── Models/ │ ├── BeaconConfig.swift Provisioning config (UUID, major, minor, txPower, etc.) │ ├── BeaconType.swift Enum: DXSmart (CP-28 only) │ ├── Business.swift Business model │ └── ServicePoint.swift Service point model ├── Provisioners/ │ ├── ProvisionerProtocol.swift Protocol + CP-28 GATT constants │ ├── DXSmartProvisioner.swift DX-Smart CP-28 GATT provisioner (24-step write sequence) │ └── ProvisionError.swift Shared error types ├── Services/ │ ├── APIClient.swift Actor-based REST client, all API calls │ ├── APIConfig.swift Base URLs, timeouts, dev/prod toggle │ ├── BLEManager.swift CoreBluetooth scanning + beacon type detection │ └── SecureStorage.swift Keychain-based token storage ├── Utils/ │ ├── BeaconBanList.swift Known bad UUID prefixes (factory defaults) │ ├── BeaconShardPool.swift 64 Payfrit shard UUIDs │ └── UUIDFormatting.swift UUID string formatting extensions └── Views/ ├── BusinessListView.swift Business selection screen ├── DevBanner.swift Orange "DEV" banner overlay ├── LoginView.swift OTP login screen ├── QRScannerView.swift Camera-based QR code scanner for beacon pairing ├── RootView.swift Root navigation └── ScanView.swift Main scan + provision UI ``` ## Key Architecture Notes - **CP-28 only**: Only DX-Smart CP-28 beacons are supported. Other beacon types (KBeacon, BlueCharm) were removed — will be re-added when needed. - **Actor-based API**: `APIClient` is a Swift actor (thread-safe by design). - **Secure storage**: Auth tokens stored in Keychain via `SecureStorage`, not UserDefaults. - **BLE scanning**: `BLEManager` handles CoreBluetooth device discovery and beacon type identification. - **DX-Smart protocol**: 24-step write sequence including frames 3-6 disable (full Android parity). - **QR scanner**: Camera-based QR code scanning for beacon pairing workflows.