Room entities/DAOs/DB, PocketBase Retrofit client + auth interceptor, SyncEngine (push-then-pull, LWW, tombstones, client-generated ids), SettingsStore, AppContainer. Open Library + Google Books merge, ISBN validation, CameraX + ML Kit scanner plumbing. Verified by orchestrator: assembleDebug exit 0; testDebugUnitTest exit 0, 68 tests, 0 failures, 0 errors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016bThmkmyUUdqQpy3MXFFe5
68 lines
4.0 KiB
Plaintext
68 lines
4.0 KiB
Plaintext
You are Worker D on the Bookshelf project (~/bookshelf). Implement BOOK METADATA
|
|
LOOKUP + BARCODE SCANNING.
|
|
|
|
FIRST, READ THESE — they are the contract, follow them exactly, do not invent
|
|
alternative names or restate them back to me:
|
|
~/bookshelf/docs/SPEC.md (authoritative product/technical spec — see the
|
|
"Book metadata lookup" and "Barcode scanning"
|
|
sections especially)
|
|
~/bookshelf/docs/HANDOFF.md (operational state and gotchas already paid for)
|
|
|
|
## Your scope — these packages ONLY, under app/app/src/main/java/org/modg/bookshelf/
|
|
data.metadata
|
|
- IsbnUtils: ISBN-13 checksum validation, ISBN-10 -> 13 conversion,
|
|
normalization (strip hyphens/spaces, handle trailing X)
|
|
- OpenLibraryClient and GoogleBooksClient (Retrofit or OkHttp + kotlinx-
|
|
serialization; endpoints are in SPEC)
|
|
- BookMetadata (source-agnostic result model) and MetadataMerger implementing
|
|
SPEC's merge rule: prefer whichever has a title, fill blanks from the other,
|
|
return null if both miss
|
|
- MetadataRepository: the single entry point, `suspend fun lookup(isbn): BookMetadata?`
|
|
ui.scan — SCANNER PLUMBING ONLY, no finished screen (wave 3 builds the screen):
|
|
- a CameraX ImageAnalysis analyzer wrapping ML Kit BarcodeScanning
|
|
(EAN_13, EAN_8, UPC_A), validating the ISBN-13 checksum before emitting,
|
|
debouncing repeat reads of the same code
|
|
- a small stateful holder exposing scan results as a Flow, plus torch toggle
|
|
and camera-permission-denied states
|
|
|
|
## HARD BOUNDARIES — you share this repo with Worker C, running right now
|
|
- DO NOT create or edit anything under `data.local`, `data.remote`, `data.repo`,
|
|
`data.prefs`, `AppContainer`, or `BookshelfApplication.kt`. Those are Worker C's.
|
|
Touching them WILL cause a conflict.
|
|
- DO NOT edit any `ui.theme` or `ui.components` file — wave 1B finished those and
|
|
they are verified green. Reuse them; do not modify them.
|
|
- DO NOT edit `app/build.gradle.kts` or `gradle/libs.versions.toml`. Everything
|
|
you need (camerax core/camera2/lifecycle/view, mlkit barcode-scanning, retrofit,
|
|
kotlinx-serialization, okhttp, coroutines-test, robolectric) is ALREADY declared
|
|
and wired. If you think something is missing, DO NOT add it — report it instead.
|
|
- Your MetadataRepository must be a plain class with an explicit constructor
|
|
(e.g. taking OkHttpClient/Json). Do NOT wire it into AppContainer — Worker C owns
|
|
that file. In your final report, give the exact one-line wiring snippet needed.
|
|
|
|
## Build/verify — CRITICAL
|
|
Never run `./gradlew` directly; a second worker builds concurrently and you will
|
|
corrupt each other's build. ALWAYS build with the serialized wrapper:
|
|
~/bookshelf/tasks/gw assembleDebug
|
|
~/bookshelf/tasks/gw testDebugUnitTest
|
|
It takes the lock and may block until the other worker's build finishes. That is
|
|
expected — wait for it, do not bypass it.
|
|
|
|
## Definition of done — all must actually pass, verified by you, not assumed
|
|
1. `~/bookshelf/tasks/gw assembleDebug` exits 0.
|
|
2. `~/bookshelf/tasks/gw testDebugUnitTest` exits 0.
|
|
3. Real unit tests with real assertions (SPEC: "Do not write assertion-free tests"):
|
|
- ISBN-13 checksum: known-valid and known-invalid ISBNs, ISBN-10 conversion,
|
|
hyphen/space handling
|
|
- MetadataMerger: OL-only, GB-only, both, neither(-> null), and blank-filling
|
|
- client JSON parsing against CHECKED-IN SAMPLE JSON FIXTURES, not live network.
|
|
Tests must pass offline with no network access.
|
|
4. Network code must never be called on the main thread and must fail soft
|
|
(return null / empty) rather than throw on timeout or malformed JSON.
|
|
|
|
## Report back (keep it short — it is read by a token-constrained orchestrator)
|
|
- exact pass/fail of the two gradle commands above
|
|
- files created, one line each
|
|
- the one-line AppContainer wiring snippet for MetadataRepository
|
|
- anything in SPEC.md you could NOT satisfy, and why. Do not paper over gaps:
|
|
a truthfully reported gap is worth more than a false green.
|