From 075706f162766737e1cbe3dfe6888061378518d2 Mon Sep 17 00:00:00 2001 From: Koda Date: Sun, 22 Mar 2026 18:31:56 +0000 Subject: [PATCH] docs: add CLAUDE.md updated for new modular architecture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reflects Schwifty's rebuild — modular provisioners, actor-based API, secure storage, QR scanner, and updated project structure. Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..60fd29b --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,101 @@ +# 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, BlueCharm, KBeacon, Unknown +│ ├── Business.swift Business model +│ └── ServicePoint.swift Service point model +├── Provisioners/ +│ ├── ProvisionerProtocol.swift Protocol — all provisioners implement this +│ ├── DXSmartProvisioner.swift DX-Smart CP28 GATT provisioner (24-step write sequence) +│ ├── BlueCharmProvisioner.swift BlueCharm BC037 provisioner +│ ├── KBeaconProvisioner.swift KBeacon provisioner +│ ├── FallbackProvisioner.swift Unknown device fallback +│ └── 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 + +- **Modular provisioners**: Each beacon manufacturer has its own provisioner conforming to `ProvisionerProtocol`. No more monolithic `BeaconProvisioner.swift`. +- **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.