rmt-box.organizer.inventory/docs/PROJECT_OVERVIEW.md
Quiver d1d64c3854 Complete Box Organizer Inventory app implementation
- Full Clean Architecture + MVVM with Hilt DI throughout all layers
- Room v6 with SQLCipher encryption and 5 migrations (no destructive)
- Items can be placed directly in a room or location (not just in a box)
- Reactive detail screens: name changes update instantly via ObserveById flows
- Camera permission flow: always-clickable button with proper rationale handling
- Soft keyboard: imePadding on AddEditItemScreen so Notes field stays visible
- Clickable items in BoxDetailScreen navigating to ItemDetailScreen
- FTS4 full-text search, QR code scanning, CameraX photos with UCrop
- Google Drive encrypted backup via WorkManager, Excel/PDF export
- Biometric + PIN app lock, Google Play Billing freemium model
- Home screen widgets: 4x1 search widget and 2x2 recent items widget
- Updated docs/PROJECT_OVERVIEW.md to reflect current codebase state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 16:31:47 +02:00

10 KiB
Raw Permalink Blame History

Box Organizer Inventory — Projektöversikt

Uppdaterad: 2026-04-05 Package: com.roundingmobile.boi Min SDK: 27 (Android 8.1) · Target SDK: 36 Databas: Room v6 · SQLCipher AES-256


Arkitektur

Clean Architecture + MVVM med Single-Activity och Jetpack Compose Navigation.

Presentation (Compose)
  20 Screens + ViewModels + UiState
       ↓ lambdas
Domain (ren Kotlin)
  47 UseCases · 8 Repository-interfaces · 12 modeller
       ↓ Result<T> / Flow<T>
Data (Android)
  11 RepositoryImpl · 8 DAOs · AppDatabase v6
       ↓
  SQLite (SQLCipher) + Google Drive + Play Billing + ML Kit

DI: Hilt genomförd i alla lager (6 moduler: App, Database, Preferences, Repository, Backup, WidgetEntryPoint).


Databas

Version 6 — ingen fallbackToDestructiveMigration.

Migration Ändring
1 → 2 photoPath på locations
2 → 3 photoPath på storage_rooms
3 → 4 color + photoPath på boxes
4 → 5 FTS4-tabell items_fts + triggers
5 → 6 boxId nullable; roomId + locationId FK:ar på items; FTS återskapad

Entiteter

Tabell Nyckelfält
locations id, name, description, photoPath, createdAt, updatedAt
storage_rooms id, locationId (FK→locations), name, description, photoPath
boxes id, roomId (FK→storage_rooms), name, qrCode (UNIQUE), color, photoPath
items id, boxId? (FK), roomId? (FK), locationId? (FK), name, description, quantity, value, unit, notes
item_photos id, itemId (FK), filePath, sortOrder
tags id, name (UNIQUE), colorHex
item_tags itemId + tagId (composite PK, båda CASCADE DELETE)
items_fts FTS4 virtual table — name, description, notes; synkad via triggers

Exakt ett av boxId, roomId, locationId är non-null per föremål. Alla FK-relationer har CASCADE DELETE. Index på alla WHERE/ORDER BY-kolumner.


Hierarki

Plats (Location)
└── Rum (StorageRoom)
│   └── Låda (Box)
│   │   └── Föremål (Item)  ← item.boxId
│   └── Föremål (Item)      ← item.roomId
└── Föremål (Item)          ← item.locationId

Föremål kan ligga direkt i en låda, ett rum eller en plats.


Skärmar (20 st)

Skärm Route Funktion
HomeScreen home Dashboard: platser med rum/föremål-räkningar, PRO-indikator
LocationListScreen locations Lista alla platser
LocationDetailScreen location/{id} Platsdetaljer: rum-lista + lösa föremål
AddEditLocationScreen add_location, edit_location/{id} Skapa/redigera plats (namn, beskrivning, foto)
RoomListScreen rooms/{locationId} Rum inom en plats
RoomDetailScreen room/{id} Rumsdetaljer: låd-lista + lösa föremål
AddEditRoomScreen add_room/{locationId}, edit_room/{id} Skapa/redigera rum
BoxListScreen boxes/{roomId} Lådor i ett rum
BoxDetailScreen box/{id} Låddetaljer: föremål, QR-kod, etikettgenerering
AddEditBoxScreen add_box/{roomId}, edit_box/{id} Skapa/redigera låda (namn, färg, foto)
ItemListScreen items/{boxId} Föremål i en låda
ItemDetailScreen item/{id} Föremålsdetaljer: foton, taggar, anteckningar, värde
AddEditItemScreen add_item/{boxId}, edit_item/{id}, add_item_to_room/{roomId}, add_item_to_location/{locationId} Skapa/redigera föremål
CameraScreen camera CameraX-foto, returnerar sökväg via savedStateHandle
SearchScreen search Global FTS4-sökning, resultat grupperade per typ
QrScannerScreen qr_scanner Skanna QR → navigera direkt till rätt låda
ProUpgradeScreen pro_upgrade Google Play Billing-UI
RestoreBackupScreen restore_backup Återställ från Google Drive-backup
SettingsScreen settings Backup, export/import, app-lås PIN
LockScreen (modal overlay) Biometrisk/PIN-lås vid återgång till appen

Deep links: boi://search (sök-widget), boi://item/{id} (senaste-widget). Animationer: slide + fade 280 ms (framåt/bakåt).


UseCases (47 st)

Domän UseCases
Location Add, Update, Delete, GetById, GetAll, GetSummaries, ObserveById
StorageRoom Add, Update, Delete, GetById, GetByLocation, ObserveById
Box Add, Update, Delete, GetById, GetByRoom, GetByQrCode, ObserveById
Item Add, Update, Delete, GetById, GetByBox, GetByRoomDirect, GetByLocationDirect, GetTotalCount
ItemPhoto Add, Delete, GetByItem
Tag Add, Update, Delete, GetAll, AddToItem, RemoveFromItem, GetForItem
Search Search (FTS4)
Backup BackupNow, GetBackupList, RestoreFromBackup
Export/Import ExportInventory, ExportInventoryFile, ImportInventory
PRO GetProStatus, SetProStatus

Observe*-UseCaserna returnerar Flow<T?> och ser till att detail-skärmar uppdateras i realtid när namn ändras.


Reaktivt namnuppdatering

Varje detail-ViewModel (LocationDetailViewModel, RoomDetailViewModel, BoxDetailViewModel) använder combine(observeEntity(), children...) — inte one-shot suspend fun. Det innebär att namn-ändringar från redigera-skärmen syns direkt utan navigation.


Funktioner

Sökning

  • FTS4 full-text sökning på item name/description/notes
  • Resultat grupperade: Föremål · Lådor · Platser
  • SearchRepositoryImpl bygger korrekt sökväg oavsett om föremålet ligger i låda, rum eller plats

QR-koder

  • Varje låda får en unik QR-kod (ZXing)
  • Skanning navigerar direkt till rätt låda
  • PDF-etikett med QR-kod för utskrift

Foton & Kamera

  • CameraX för att ta foton
  • UCrop för bildbeskärning
  • Auto-komprimering: max 1080 px, kvalitet 80 %
  • Systemkamera via TakePicture() på plats/rum/låda-skärmar (FileProvider)
  • Alla foton i filesDir/photos/ — aldrig extern lagring

Kamerabehörighet

  • Kameraknappen alltid klickbar (aldrig enabled = false)
  • Vid klick: kontrollera behörighet → be om den vid behov
  • Mjuk nekad → Snackbar
  • Permanent nekad → dialog med länk till app-inställningar

Backup & Restore

  • Google Drive — automatisk backup var 24:e timme (WorkManager, WiFi + batteri)
  • Manuell backup från Inställningar
  • AES-krypterade backup-filer
  • Restore: ersätt allt eller slå ihop (merge)
  • Push-notiser vid lyckad/misslyckad backup

Export

  • Excel (.xlsx) via Apache POI
  • PDF — full inventarielista
  • PDF-etiketter med QR-koder

App-lås

  • BiometricPrompt med PIN-fallback
  • Lås aktiveras automatiskt när appen går till bakgrunden
  • PIN-inställning i Inställningar

Widgets

Widget Storlek Funktion
Sökwidget 4×1 Öppnar sökskärmen via boi://search
Senaste föremål 2×2 Visar 4 senast tillagda föremål; uppdateras var 60:e minut

Freemium & In-App Purchase

  • Google Play Billing v7
  • Gräns-kontroll i UseCase-lagret — aldrig i UI
  • PRO-status sparas i DataStore

Freemium-gränser (AppConfig.kt)

Funktion Gratis Pro
Föremål totalt 500 Obegränsat
Foton per föremål 3 Obegränsat
Excel/PDF-export Nej Ja
Google Drive-backup Nej Ja
Avancerade filter Nej Ja

Säkerhet

Komponent Mekanism
Databas SQLCipher (AES-256)
DB-nyckel EncryptedSharedPreferences
Backup-filer AES-krypterade
Foton filesDir (ej åtkomlig för andra appar)
App-lås PIN + BiometricPrompt
Loggar if (BuildConfig.DEBUG) — aldrig i release
Manifest allowBackup="false", exported="false" på alla interna komponenter

Tekniker & Bibliotek

Kategori Bibliotek Version
Språk Kotlin 2.1.10
UI Jetpack Compose BOM 2024.12.01
UI Material3 via BOM
DI Hilt 2.59.2
Navigation Navigation Compose 2.8.5
ORM Room 2.7.1
DB-kryptering SQLCipher 4.5.4
Bilder Coil (Compose) 2.7.0
Kamera CameraX 1.4.2
Bildbeskärning UCrop 2.2.8
ML Kit Barcode Scanning + Image Labeling 17.3.0 / 17.0.9
QR-koder ZXing 3.5.3
Bakgrundsarbete WorkManager 2.10.0
Reaktiv data Kotlin Coroutines + Flow 1.8.1
Inställningar DataStore Preferences 1.1.3
Säker lagring Security Crypto 1.1.0-alpha06
Biometri androidx.biometric 1.2.0-alpha05
Köp Google Play Billing KTX 7.1.1
Backup Google Drive API v3 + Play Services Auth v3-rev197 / 21.3.0
Excel Apache POI 5.2.3
Lifecycle ViewModel + Runtime KTX 2.9.0

Filstruktur

Lager Filer
Presentation (Screens + ViewModels + UiState) ~65
Domain (UseCases + Models + Interfaces) ~60
Data (Entities + DAOs + RepositoryImpl) ~35
DI (Hilt-moduler) 6
Util ~10
Navigation 2
Totalt ~184

Vad man kan göra i appen

  • Skapa platser, rum, lådor och föremål i en hierarki
  • Lägga föremål direkt i ett rum eller en plats (utan låda)
  • Lägga till foton på föremål och platser/rum/lådor
  • Sätta färgkod och QR-kod på lådor
  • Tagga föremål med valfärgade taggar
  • Redigera namn → detaljskärmen uppdateras direkt (reaktivt)
  • Söka efter föremål med fulltextsökning
  • Skanna QR-kod för att navigera direkt till rätt låda
  • Exportera inventariet till Excel eller PDF
  • Skriva ut etiketter med QR-koder
  • Säkerhetskopiera till Google Drive (automatiskt + manuellt)
  • Återställa från backup (ersätt eller slå ihop)
  • Skydda appen med PIN + biometri
  • Uppgradera till Pro via Google Play

Möjliga nästa steg

  • ML Kit auto-taggning från foton (infrastruktur finns i ImageLabelAnalyzer.kt)
  • Flytta föremål/lådor mellan rum/platser
  • Sortering och filtrering i listor (per datum, värde, antal)
  • Statistikskärm (totalt värde, antal per plats)
  • Barcode-sökning (EAN/UPC) för produktidentifiering
  • Notiser för schemalagda inventariegranskningar
  • iCloud/Dropbox som backup-alternativ
  • CSV-import
  • Dela enskilda lådor/inventarier med andra användare
  • Fullständigt flerspråksstöd (i18n)
  • Enhetstester för UseCases
  • Instrumenterade tester för databas-migrationer