payfrit-beacon-ios/CLAUDE.md
Schwifty 5eebf00aa0 refactor: strip all non-CP-28 beacon code
Remove BlueCharmProvisioner, KBeaconProvisioner, and FallbackProvisioner.
Simplify BeaconType enum to DX-Smart only. Simplify BLE detection to only
show CP-28 beacons. Remove multi-type provisioner factory from ScanView.

-989 lines of dead code removed. Other beacon types will be re-added
when we start using different hardware.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 03:04:07 +00:00

4.9 KiB

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.