~cytrogen/vbhelper

ref: e9d2cce8024f3fd3bacb258c183c31f59d3f4b40 vbhelper/CLAUDE.md -rw-r--r-- 4.4 KiB
e9d2cce8 — Cytrogen Add UnifiedPush notification system with Ktor server a month ago

#CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

#Project Overview

VBHelper is an Android app (Kotlin + Jetpack Compose) for interacting with Vital Bracelet series devices (VB, VH, VBC, VBBE) via NFC. It reads/writes characters, manages cards, tracks adventures, and handles cryptographic secrets for device communication.

#Build & Development Commands

All Gradle commands require JDK 17. Set JAVA_HOME before building:

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
# Build the project
./gradlew build

# Run unit tests
./gradlew test

# Run a single unit test class
./gradlew testDebugUnitTest --tests "com.github.nacabaro.vbhelper.ExampleUnitTest"

# Run instrumented (Android device) tests
./gradlew connectedAndroidTest

# Install debug APK
./gradlew installDebug

# Lint check (has baseline in lint-baseline.xml)
./gradlew lint

Single-module project — all Gradle tasks target :app.

#Architecture

Pattern: Controller-based screens with Repository data access and a manual service locator for DI.

Data flow: Screen composables → Controller (interface + impl) → Repository → Room DAO → SQLite

Key architectural decisions:

  • DefaultAppContainer (in di/) is the DI root — lazily creates the Room DB, DataStore instances, and all repositories. Accessed via (application as VBHelper).container.
  • Each major screen has a Controller interface and ControllerImpl. Controllers hold business logic and expose state via Kotlin Flow.
  • Cryptographic secrets (AES keys, HMAC keys, ciphers for device communication) are stored in Protocol Buffers via DataStore, not Room.
  • NFC operations use vb-nfc-reader library (0.2.0-SNAPSHOT from mavenLocal). Card parsing uses vb-dim-reader.
  • Pre-loaded item data ships in app/src/main/assets/items.db.

Source layout (app/src/main/java/com/github/nacabaro/vbhelper/):

Directory Purpose
di/ App-level DI container and Application class
database/ Room database, DAOs (11 DAOs, 17 entities)
domain/ Domain model classes (card, characters, device_data, items)
source/ Repositories (8) for data access
screens/ Compose UI screens, each with its own Controller
navigation/ Compose NavHost, route definitions, bottom nav bar
components/ Shared UI components
dtos/ Data transfer objects for screen-layer queries
utils/ DeviceType enum, bitmap helpers
proto/ Protobuf definitions for secrets

#Key Technical Details

  • Kotlin 2.3.0, JVM target 11, Min SDK 28, Target/Compile SDK 36
  • Room for structured data; DataStore + Protobuf for secrets; DataStore Preferences for currency/settings
  • Compose Material 3 with dynamic color on Android 12+
  • KSP for Room annotation processing; Protobuf Gradle plugin generates Java lite classes
  • vb-nfc-reader is resolved from mavenLocal() — must be installed locally to build
  • Version catalog in gradle/libs.versions.toml

#Conventions

  • No ViewModel — screens use the Controller pattern (interface + impl), not Android ViewModel
  • No DI framework — manual DI via AppContainer/DefaultAppContainer. Do not introduce Hilt, Dagger, or Koin
  • Controller callback pattern — Controllers expose callbacks (lambdas) to composables for user actions, and Flow for observable state
  • Version catalog — all dependency versions are declared in gradle/libs.versions.toml, never inline in build.gradle.kts

#Dangerous Operations

The following modifications carry high risk and require careful consideration:

  • app/src/main/assets/items.db — Pre-loaded item database. Must stay in sync with Room schema. A mismatch crashes the app on fresh install.
  • app/src/main/proto/*.proto — Protobuf definitions for cryptographic secret storage. Changing field numbers or removing fields can make existing user secrets unreadable, effectively bricking their device pairing.
  • vb-nfc-reader version — Resolved from mavenLocal() as a SNAPSHOT. Changing the version requires the new version to be installed locally. Version mismatches cause build failures with confusing error messages.
  • gradlew / gradle/wrapper/ — Managed by Gradle. Manual edits can break the build for all developers. Use ./gradlew wrapper --gradle-version=X.Y to upgrade.