The '@/' import alias needs this plugin; debug builds hid the gap because they bundle lazily via Metro. Release (standalone) bundling now succeeds. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|---|---|---|
| .gitea/workflows | ||
| app | ||
| docs | ||
| parksmarter-client | ||
| .gitignore | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
BigBrainParking
An unofficial, de-Googled client for the ParkSmarter (IPS Group) parking system, built to run on GrapheneOS with UnifiedPush notifications and distributed via Obtainium — no Google Play Services, no Firebase, no app store.
Monorepo layout
bigbrainparking/
├── parksmarter-client/ # Zero-dep TypeScript API client (reverse-engineered, live-verified)
├── app/ # Expo / React Native app (BigBrainParking)
└── .gitea/workflows/ # CI: build signed APK -> publish release for Obtainium
parksmarter-client— the API layer. All ~40 endpoints, the custom-header auth model, and response models (most verified against production). Runs anywhere; the app imports it directly. See its own README for the API details.app— the phone app. React Native (Expo prebuild), MapLibre maps, VisionCamera QR scanning, expo-secure-store token storage, local session-expiry reminders, and UnifiedPush wiring.
Features
| Feature | Status | Notes |
|---|---|---|
| Phone + password login | ✅ wired | tokens in OS keystore |
| Map of nearby meters (clickable, zoom, live GPS) | ✅ wired | MapLibre + OpenFreeMap tiles (no key) |
| "Near my last location" proximity search | ✅ wired | caches last GPS fix |
| QR kiosk scan → meter lookup | ✅ wired | on-device VisionCamera |
| Save / share kiosks | ✅ wired | local (no server favorites API exists) |
| Active / past sessions | ✅ wired | list views |
| Start a paid session | 🟡 gated | flow wired to postStartParkingSession, disabled pending review (real charge) |
| Session-expiry reminders | ✅ wired | local notifications — no FCM needed |
| UnifiedPush (ntfy) | 🟡 partial | endpoint registration done; server→ntfy bridge still needed (see below) |
Build & run (dev)
Requires Node 20, JDK 17, Android SDK, and a GrapheneOS device (or any Android device) with USB debugging.
npm install # installs both workspaces
npm run build --workspace parksmarter-client # compile the client
cd app
npx expo prebuild --platform android # generate native project
npx expo run:android # build + install a dev client
The app talks to prod (apiv2.parksmarter.com) by default — change extra.psEnvironment
in app/app.json to point elsewhere.
Notifications on GrapheneOS
Session-expiry reminders are scheduled locally from each session's end time, so they
need no push infrastructure and work fully offline of Google. app/src/notifications/
also wires UnifiedPush (distributor: ntfy) for any genuinely server-initiated push —
but note the ParkSmarter backend only pushes via FCM, so server push requires a small
FCM→ntfy bridge (a service holding an FCM token that forwards to your ntfy topic, then
registered via PUT /api/Device). Until that exists, local reminders cover the main case.
Distribution via Obtainium (self-hosted)
Tag a release and CI builds a signed APK and publishes it to this repo's releases; your
phone's Obtainium tracks the repo and offers updates. See
docs/DISTRIBUTION.md for the full server + CI + keystore setup.