# Bounty Board — Android A native Android client for the [Bounty Board](../BountyBoard) consulting work-management platform. Built with **Kotlin + Jetpack Compose (Material 3)**, it covers the full role-based feature set — admin, consultant, and developer — over the server's cookie-session + CSRF API. The visual identity mirrors the web app's "ledger / bounty-poster" aesthetic: warm paper grounds, brown/amber ink, hard offset shadows (no blur), 2px corners, ◈ bounty chips, and the original **Fraunces / Schibsted Grotesk / Spline Sans Mono** typefaces (bundled, instanced from the web app's variable fonts). ## First run The app opens on a **Login** page. The default server is `https://bountyboard.anypreta.com/`. Expand **Server** on the login screen to point the app at any other Bounty Board instance — the base URL is persisted and every request is retargeted at runtime. Sign in with email/password, register a developer account, or use "Forgot password". A forced password change is handled automatically when the server requires it. ## Features - **Auth** — login (with configurable base URL), self-registration, forgot password, forced password change. Session + CSRF are handled transparently by a persistent cookie jar and a double-submit interceptor. - **Developer** — bounty board with search / project / min-bounty / sort filters and claim flow; My Tasks kanban (Assigned · In progress · In review · Done); per-task start / submit / abandon / withdraw; comments; time logging; metrics dashboard; leaderboard. - **Consultant** — atomization board (grouped by project, status filters, quick publish); subdivide / extend / edit / publish; reviews queue with an acceptance- criteria checklist; approve / decline claims; assign-to-AI; developer pool management; metrics. - **Admin** — users (roles, disable, force-reset, delete); projects/customers wizard (per-system credential fields, test connection, sync now); runtime settings; audit log; live service-status panel. - **Shared** — task detail with full role-aware action bar and timeline; real-time-feel messaging (DMs, group/project conversations, image + file attachments, read receipts); notification center with deep links; profile (avatar upload, bio/contact, theme picker with all six themes, leaderboard opt-out, sign-out-everywhere); public profile cards. ## Architecture ``` data/ AppContainer (manual DI) · Repository · SessionManager · SettingsStore (DataStore) net/ Retrofit ApiService · PersistentCookieJar · CSRF + dynamic-host interceptors · DTOs model/ wire data classes ui/ theme/ palette (6 themes) · typography · 2px shapes · hard-offset shadow modifier components/ BBButton · BBCard · BountyChip · StatusBadge · BBAvatar · BBTextField · dialogs · TaskCard nav/ AppRoot (bootstrap/auth gate) · MainShell (role drawer + NavHost) · Routes auth/ developer/ consultant/ admin/ task/ messaging/ shared/ profile/ feature screens + ViewModels ``` - **Networking**: OkHttp + Retrofit (Gson). The base URL is dynamic — a host-selection interceptor rewrites scheme/host/port per request, so changing the server on the login screen takes effect immediately without rebuilding Retrofit. Coil shares the OkHttp stack so `/files/{id}` image loads carry the session cookie. - **Auth**: cookie-session only. `bb_session` (httpOnly) and `bb_csrf` are persisted in a `PersistentCookieJar`; mutating requests echo `bb_csrf` into the `X-CSRF-Token` header. - **State**: ViewModels expose Compose `mutableStateOf` snapshots; screens are stateless and driven by `LocalAppContainer`. ## Building Requirements: **JDK 17 or 21** (AGP 8.5 does not support newer JDKs as the build JVM), the Android SDK with **platform 34** and **build-tools 34.0.0**, and Gradle 8.9+. The easiest path is to open the project in **Android Studio** (Koala / 2024.1+), let it sync, and Run. From the CLI (the Gradle wrapper is included; point `JAVA_HOME` at a JDK 17–21): ```bash cd BountyBoard_android JAVA_HOME=/path/to/jdk-21 ./gradlew assembleDebug # APK → app/build/outputs/apk/debug/ JAVA_HOME=/path/to/jdk-21 ./gradlew installDebug # install on a connected device/emulator ``` A prebuilt debug APK is committed at **`BountyBoard-debug.apk`** in the project root — `adb install -r BountyBoard-debug.apk` to side-load it directly. `local.properties` already points `sdk.dir` at `~/Android/Sdk`; adjust if your SDK lives elsewhere. The app allows cleartext traffic so you can point it at a local `http://` dev server. ### Sign-in Local email/password **and** OIDC SSO both work. "Sign in with SSO" opens the server's OIDC redirect flow in an in-app browser; once the IdP redirects back, the session cookies are captured into the app's HTTP stack and you're signed in. If the server has no OIDC configured, the app reports that instead of failing silently. ## Notes - `minSdk 26`, `targetSdk 34`. No proprietary services; the launcher icon, splash, and fonts are all bundled. - The server contract is documented in `../BountyBoard/api/openapi.yaml` and `../BountyBoard/specification.md`; this client implements the §6 application API.