- 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>
43 KiB
📦 Box Organizer Inventory — Super Prompt för Claude Code (Svenska)
ALLMÄNNA INSTRUKTIONER TILL CLAUDE CODE
Du ska bygga Android-appen Box Organizer Inventory steg för steg, i numrerade faser.
REGLER SOM MÅSTE FÖLJAS UTAN UNDANTAG:
- Slutför EN hel fas innan du går vidare till nästa.
- I slutet av varje fas, STANNA och fråga programmeraren att kompilera och testa.
- Det finns inga "knappar utan åtgärd". Varje UI-element som syns måste ha riktig kod bakom sig. Om det ännu inte är implementerat, lägg inte till det i gränssnittet. Använd
// TODObara i intern logik, aldrig i UI. - Om något inte kompilerar, fixa det innan du fortsätter. Godkänn aldrig något som ger fel.
- Maximal 700 rader per .kt-fil. Om en fil växer mer, dela upp den i mindre klasser med tydliga ansvarsområden.
- Förklara allt utförligt i kodkommentarer. Anta inte att programmeraren förstår varför du gör något.
- Generera aldrig partiell kod — varje fil du skapar måste vara komplett och kompilerbar.
HUR VARJE FAS AVSLUTAS:
I slutet av varje fas, skriv exakt detta (ersätt punkterna med riktiga tester):
─────────────────────────────────────────
✅ SLUT PÅ FAS [N] — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
Innan vi fortsätter behöver du göra detta:
KOMPILERING:
□ Gör Build > Make Project i Android Studio
□ Bekräfta att det inte finns några röda fel i Build-panelen
MANUELLA TESTER:
□ [Konkret test 1]
□ [Konkret test 2]
□ [Konkret test 3]
När du har gjort ALLT ovan, skriv till mig:
"Fas [N] OK" → och jag fortsätter med fas [N+1]
"Fas [N] FEL: [beskrivning]" → och jag fixar det innan vi fortsätter
─────────────────────────────────────────
PROJEKTKONTEXT
App: Box Organizer Inventory
Syfte: Organisera fysiska föremål i lådor, rum och hus. Användaren tar foton, genererar QR per låda, söker efter föremål och exporterar inventarier.
Plattform: Android native (Kotlin)
Min SDK: 27 (Android 8.1) — täcker 95%+ av marknaden
Target SDK: 36
Komplett teknisk stack:
| Bibliotek | Version | Användning |
|---|---|---|
| Kotlin | 2.0+ | Huvudspråk |
| Room | 2.6+ | ORM-databas |
| SQLCipher | 4.5+ | Kryptering av databas på disk |
| Hilt | 2.51+ | Dependency injection |
| Jetpack Compose BOM | 2024.12+ | Deklarativt UI (inget XML) |
| Material3 Compose | - | Material You-komponenter |
| Compose Navigation | 2.7+ | Navigation mellan skärmar |
| CameraX | 1.3+ | Kamera + fotoinsamling |
| ML Kit Image Labeling | 18+ | Auto-taggar från foto |
| ML Kit Barcode Scanning | 17+ | Skanna QR och streckkoder |
| WorkManager | 2.9+ | Automatisk backup i bakgrunden |
| DataStore Preferences | 1.1+ | Spara användarinställningar |
| Coil | 2.7+ | Ladda bilder effektivt |
| Apache POI Android | 5.2+ | Generera Excel-filer |
| iTextPDF / PdfDocument | - | Generera PDF-filer |
| Google Play Billing | 6.2+ | In-app köp (PRO) |
| Google Drive API | 3.0+ | Molnbackup (PRO) |
| ViewModel + StateFlow | - | MVVM + reaktivt tillstånd |
| Coroutines | 1.8+ | Asynkrona operationer |
| UCrop | 2.2+ | Fotobeskärning i appen |
| ZXing / QR Generate | - | Generera QR-bilder |
Arkitektur:
app/
├── data/
│ ├── local/
│ │ ├── database/ ← Room DB + SQLCipher
│ │ ├── dao/ ← Room DAOs
│ │ └── entity/ ← Room entiteter
│ ├── repository/ ← Repository-implementationer
│ └── preferences/ ← DataStore
├── domain/
│ ├── model/ ← Domänmodeller (inte Room)
│ ├── repository/ ← Repository-gränssnitt
│ └── usecase/ ← Use cases
├── presentation/
│ ├── home/ ← Huvuddashboard (Composable)
│ ├── location/ ← Hem/Platser (Composable)
│ ├── room/ ← Rum (Composable)
│ ├── box/ ← Lådor (Composable)
│ ├── item/ ← Föremål (Composable)
│ ├── search/ ← Global sökning (Composable)
│ ├── settings/ ← Inställningar + PRO (Composable)
│ └── common/ ← Delade Composables
├── di/ ← Hilt-moduler
└── util/ ← Hjälpklasser
Komplett datamodell:
// Hierarki: Location → Room → Box → Item
// En Box kan ha parentBoxId (låda i låda)
Location: id, name, description, photoPath, createdAt
Room: id, locationId(FK), name, description, photoPath, createdAt
Box: id, roomId(FK), parentBoxId(FK nullbar), name, description,
colorHex, coverPhotoPath, qrCodeData, createdAt
Item: id, boxId(FK), name, description, quantity, estimatedValue,
createdAt, updatedAt
ItemPhoto: id, itemId(FK), photoPath, sortOrder
Tag: id, name, colorHex
ItemTag: itemId(FK), tagId(FK) ← pivottabell
Freemium-modell:
// AppConfig.kt — ENDA stället att ändra gränser
object AppConfig {
const val FREE_ITEM_LIMIT = 500
const val FREE_PHOTOS_PER_ITEM = 3
const val FREE_MAX_LOCATIONS = Int.MAX_VALUE // obegränsat
const val FREE_MAX_ROOMS = Int.MAX_VALUE // obegränsat
const val FREE_MAX_BOXES = Int.MAX_VALUE // obegränsat
// PRO-funktioner
const val FEATURE_BACKUP = "feature_backup"
const val FEATURE_EXPORT = "feature_export"
const val FEATURE_UNLIMITED_PHOTOS = "feature_unlimited_photos"
const val FEATURE_ADVANCED_SEARCH = "feature_advanced_search"
// Play Store
const val PRO_PRODUCT_ID = "box_organizer_pro"
}
FÖRBEREDELSESTEG — BYT NAMN PÅ BEFINTLIGT PROJEKTPAKET
Projektet finns redan med paketet com.roundingmobile.boxorganizerinventory. Innan du börjar Fas 1, döp om det till com.roundingmobile.boi så här:
-
Öppna det befintliga projektet i Android Studio.
-
I Project-panelen (Android-vy), expandera
app > java. -
Högerklicka på
com.roundingmobile.boxorganizerinventory→ Refactor > Rename. -
Skriv
boioch bekräfta. Android Studio döper om paketet i alla filer. -
Öppna
app/build.gradle.ktsoch verifiera attapplicationId = "com.roundingmobile.boi". -
Öppna
AndroidManifest.xmloch verifiera att inga referenser till det gamla namnet finns kvar. -
Gör Build > Clean Project följt av Build > Rebuild Project.
-
Bekräfta att det kompilerar utan fel innan du börjar Fas 1.
Obs: Om Android Studio inte döper om korrekt, använd Edit > Find > Replace in Files för att söka efter
boxorganizerinventoryoch ersätta medboii hela projektet.
UTVECKLINGSFASER
FAS 1 — Projektinställning och beroenden
Mål: Nytt Android-projekt med alla beroenden konfigurerade och kompilerande.
Vad du ska göra:
-
Skapa ett nytt Android-projekt i Android Studio med:
- Namn:
BoxOrganizerInventory - Paket:
com.roundingmobile.boi - Kotlin DSL (build.gradle.kts)
- Min SDK 27, Target SDK 36
- Empty Compose Activity
- Namn:
-
Konfigurera
libs.versions.tomlmed ALLA versioner. -
Konfigurera båda
build.gradle.kts(projekt och app) med alla beroenden. -
Lägg till nödvändiga behörigheter i
AndroidManifest.xml:<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.USE_BIOMETRIC" /> <uses-permission android:name="android.permission.INTERNET" /> -
Lägg till dessa viktiga Compose-beroenden i
app/build.gradle.kts:val composeBom = platform("androidx.compose:compose-bom:2024.12.01") implementation(composeBom) implementation("androidx.compose.ui:ui") implementation("androidx.compose.material3:material3") implementation("androidx.compose.ui:ui-tooling-preview") implementation("androidx.activity:activity-compose:1.9.0") implementation("androidx.navigation:navigation-compose:2.7.7") implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0") debugImplementation("androidx.compose.ui:ui-tooling") -
Skapa
AppConfig.ktmed alla freemium-konstanter. -
Skapa
Application-klassen med@HiltAndroidApp. -
Registrera Application i Manifest.
─────────────────────────────────────────
✅ SLUT PÅ FAS 1 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
KOMPILERING:
□ Build > Make Project — inga fel
□ Kör på emulator eller enhet — appen öppnar tom skärm utan krasch
MANUELLA TESTER:
□ Appen öppnar utan krasch
□ Inga röda fel i Logcat vid start
Skriv till mig: "Fas 1 OK" eller "Fas 1 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 2 — Room-databas + SQLCipher
Mål: Krypterad databas med alla entiteter och DAOs.
Vad du ska göra:
-
Skapa alla Room-entiteter i
data/local/entity/:LocationEntity.ktRoomEntity.kt(använd namnetStorageRoomför att undvika krock medandroid.room)BoxEntity.ktItemEntity.ktItemPhotoEntity.ktTagEntity.ktItemTagEntity.kt(pivottabell,@Entity(primaryKeys = ["itemId", "tagId"]))
-
Skapa DAOs i
data/local/dao/:LocationDao.kt— CRUD + Flow<List>StorageRoomDao.kt— CRUD + Flow per locationIdBoxDao.kt— CRUD + Flow per roomIdItemDao.kt— CRUD + Flow per boxId + räkna totalt antal föremål (för freemium-gräns)ItemPhotoDao.kt— CRUD per itemIdTagDao.kt— komplett CRUDSearchDao.kt— FTS4 för global sökning
-
Skapa
AppDatabase.ktmed SQLCipher:// VIKTIGT: SQLCipher kräver SupportFactory // Nyckeln genereras slumpmässigt och sparas i EncryptedSharedPreferences val factory = SupportFactory(passphrase) Room.databaseBuilder(...) .openHelperFactory(factory) .build() -
Skapa
DatabaseModule.kti Hilt med databasprovidern. -
Skapa en tom migreringsstrategi redo att användas:
// Lägg alltid till migreringar här innan du ändrar schemat val MIGRATION_1_2 = object : Migration(1, 2) { override fun migrate(db: SupportSQLiteDatabase) { // TODO: framtida migreringar här } }
─────────────────────────────────────────
✅ SLUT PÅ FAS 2 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
KOMPILERING:
□ Build > Make Project — inga fel
□ Room genererar filer i build/generated — bekräfta att de finns
MANUELLA TESTER:
□ Appen öppnar utan krasch
□ I Device Explorer (Android Studio), hitta den krypterade databasen:
/data/data/com.roundingmobile.boi/databases/
Filen box_organizer.db ska finnas
Skriv till mig: "Fas 2 OK" eller "Fas 2 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 3 — Hilt DI komplett
Mål: All dependency injection konfigurerad.
Vad du ska göra:
- Skapa
DatabaseModule.kt— tillhandahåller databasen och alla DAOs. - Skapa
RepositoryModule.kt— kopplar gränssnitt till implementationer. - Skapa
PreferencesModule.kt— tillhandahåller DataStore. - Annotera
MainActivitymed@AndroidEntryPoint. - Verifiera att Hilt-grafen kompilerar utan cirkulära beroenden.
─────────────────────────────────────────
✅ SLUT PÅ FAS 3 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
KOMPILERING:
□ Build > Make Project — Hilt genererar kod utan fel
□ Sök "Hilt" i Build-utdata — inga kritiska varningar
MANUELLA TESTER:
□ Appen öppnar utan krasch
□ Ingen NullPointerException i Logcat
Skriv till mig: "Fas 3 OK" eller "Fas 3 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 4 — Repository-lager
Mål: All datalogik inkapslad i repositories.
Vad du ska göra:
-
Skapa gränssnitt i
domain/repository/:LocationRepositoryStorageRoomRepositoryBoxRepositoryItemRepositoryTagRepository
-
Skapa implementationer i
data/repository/som:- Mappar Entity ↔ Domänmodell
- Exponerar
Flow<>för reaktiva data - Använder
suspend funför skrivoperationer - Hanterar fel med
Result<T>
-
Skapa
ProStatusRepositorysom hanterar om användaren är PRO eller FREE och verifierar 500-föremålsgränsen.
─────────────────────────────────────────
✅ SLUT PÅ FAS 4 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
KOMPILERING:
□ Build > Make Project — inga fel
MANUELLA TESTER:
□ Skriv ett enkelt enhetstest som infogar en Location och hämtar den
□ Eller använd Database Inspector i Android Studio för att verifiera att databasen finns
Skriv till mig: "Fas 4 OK" eller "Fas 4 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 5 — Navigation + tomma skärmar
Mål: Hela navigationsstrukturen kompilerar. Tomma men tillgängliga skärmar.
Vad du ska göra:
-
Konfigurera Navigation Compose med en
NavHostochNavControlleriMainActivity. -
Skapa tomma Composable-skärmar (med en Text med skärmnamnet) för:
HomeScreen()LocationListScreen()LocationDetailScreen()AddEditLocationScreen()RoomListScreen()BoxListScreen()BoxDetailScreen()AddEditBoxScreen()ItemListScreen()ItemDetailScreen()AddEditItemScreen()SearchScreen()SettingsScreen()ProUpgradeScreen()QrScannerScreen()
-
Konfigurera
MainActivitymedScaffold+NavigationBarfrån Compose med 4 flikar:- 🏠 Hem
- 🔍 Sök
- 📷 Skanna QR
- ⚙️ Inställningar
-
VIKTIGT: Varje flik i BottomNavigation måste navigera till sitt riktiga fragment. Det får inte finnas en flik som inte gör något.
─────────────────────────────────────────
✅ SLUT PÅ FAS 5 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
KOMPILERING:
□ Build > Make Project — inga fel
MANUELLA TESTER:
□ Öppna appen — du ser NavigationBar från Compose med 4 flikar
□ Tryck på VARJE flik — varje navigerar till en annan skärm (även om den är tom)
□ Bakåtknappen fungerar korrekt
□ Ingen flik lämnar ingen respons vid tryck
Skriv till mig: "Fas 5 OK" eller "Fas 5 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 6 — Hem Dashboard + Platslista
Mål: Riktigt startskärm med lista över hus/platser.
Vad du ska göra:
-
Implementera
HomeScreenmed:- LazyColumn av Locations
- Kort per plats med: foto (eller platshållare), namn, antal lådor, antal föremål
- FAB (+) för att lägga till ny plats
- Tomt tillstånd med illustration när det inte finns några platser
- Räknare
X / 500 föremålalltid synlig i verktygsfältet (FREE) eller∞ föremål(PRO)
-
Implementera
HomeViewModelmed:StateFlow<List<Location>>för listanStateFlow<Int>för totalt antal föremålStateFlow<Boolean>för att veta om det är PRO
-
FAB (+) navigerar till
AddEditLocationScreen. -
Att trycka på en plats navigerar till
LocationDetailScreenmed ID.
─────────────────────────────────────────
✅ SLUT PÅ FAS 6 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
KOMPILERING:
□ Build > Make Project — inga fel
MANUELLA TESTER:
□ Hemskärmen visas med tom LazyColumn och snyggt tomt tillstånd
□ Räknaren "0 / 500 föremål" visas i verktygsfältet
□ FAB (+) svarar vid tryck (navigerar, även om formuläret är tomt än)
□ Inga synliga knappar som inte gör något
Skriv till mig: "Fas 6 OK" eller "Fas 6 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 7 — Komplett CRUD för Platser
Mål: Skapa, visa, redigera och ta bort platser fungerar 100%.
Vad du ska göra:
-
AddEditLocationScreen:- Namnfält (obligatoriskt, validering i realtid)
- Beskrivningsfält (valfritt)
- Fotoknapp: öppnar kamera med CameraX eller galleri (användaren väljer)
- Förhandsvisning av vald bild med knapp för att ta bort den
- Spara-knapp: aktiverad bara när namnet inte är tomt
- Avbryt-knapp: bekräftar om det finns osparade ändringar
- Redigeringsläge: laddar befintliga data automatiskt
-
LocationDetailScreen:- Visar foto, namn, beskrivning
- Lista över rum i denna plats
- FAB för att lägga till rum
- Meny (⋮) med alternativ: Redigera, Ta bort
- Vid borttagning: bekräftelsedialog "Ta bort denna plats och ALLT dess innehåll?"
-
Fotohantering:
- Spara i appens interna lagring (inte extern)
- Komprimera till max 1080px och kvalitet 85%
- Ta bort gammalt foto vid byte
─────────────────────────────────────────
✅ SLUT PÅ FAS 7 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
MANUELLA TESTER — GÖR VARJE EN:
□ Skapa en plats "Mitt Hem" med beskrivning och foto
□ Verifiera att den visas på Hem med fotot
□ Räknaren är fortfarande "0 / 500 föremål"
□ Redigera platsen — ändra namn — spara — verifiera ändringen
□ Skapa en andra plats "Förråd"
□ Ta bort "Förråd" — bekräfta dialogen — försvinner från listan
□ Försök spara en plats utan namn — Spara-knappen är inaktiverad
Skriv till mig: "Fas 7 OK" eller "Fas 7 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 8 — Komplett CRUD för Rum
Mål: Komplett hantering av rum inom en plats.
Samma som Fas 7 men för Rum. Implementera:
- Lista över rum i
LocationDetailScreen(behållaren finns redan) AddEditRoomScreenmed namn, beskrivning, fotoRoomDetailScreenmed lista över lådor + FAB + meny redigera/ta bort- Korrekt dubbelriktad navigation (back stack)
─────────────────────────────────────────
✅ SLUT PÅ FAS 8 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
MANUELLA TESTER:
□ Gå in i "Mitt Hem" → skapa rum "Vardagsrum"
□ Skapa "Kök" och "Vind"
□ Redigera "Vardagsrum" → döp om det till "Allrum"
□ Ta bort "Kök" med bekräftelse
□ Tillbaka från RoomDetail återgår korrekt till LocationDetail
Skriv till mig: "Fas 8 OK" eller "Fas 8 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 9 — Komplett CRUD för Lådor + QR
Mål: Lådhantering med generering av unikt QR per låda.
Vad du ska göra:
-
AddEditBoxScreen:- Namn, beskrivning, färgväljare (8 fördefinierade färger)
- Omslagsfoto för lådan
- Vid SKAPANDE: generera automatiskt ett unikt QR (
UUID.randomUUID().toString()) - QR genereras EN gång och ändras aldrig
-
BoxDetailScreen:- Visar omslagsfoto, namn, färg
- Knapp "Visa QR" → öppnar dialog med stor QR-bild + knapp "Skriv ut etikettPDF"
- Lista över föremål i lådan
- FAB för att lägga till föremål
-
Generera QR-bild:
// Använd ZXing för att generera Bitmap av QR val writer = QRCodeWriter() val bitMatrix = writer.encode(qrData, BarcodeFormat.QR_CODE, 512, 512) // Konvertera BitMatrix till Bitmap och spara -
"Skriv ut etikettPDF":
- Generera en enkel PDF med: lådnamn, QR-bild, rum- och platsnamn
- Öppna PDF med Android ShareSheet för utskrift eller delning
─────────────────────────────────────────
✅ SLUT PÅ FAS 9 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
MANUELLA TESTER:
□ I "Allrum" → skapa låda "Böcker" med blå färg och foto
□ Gå in i lådan → knappen "Visa QR" → QR-bild visas
□ QR är stor och läsbar i dialogen
□ Knappen "Skriv ut etikett" → genererar PDF → ShareSheet öppnas
□ Skapa låda "Verktyg" — har annat QR än "Böcker"
□ FAB för att lägga till föremål finns och svarar
Skriv till mig: "Fas 9 OK" eller "Fas 9 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 10 — Komplett CRUD för Föremål + Foton (CameraX)
Mål: Lägga till objekt i lådor med foton. Appens kärna.
Vad du ska göra:
-
AddEditItemScreen:- Namn (obligatoriskt), beskrivning, antal (standard 1), uppskattat värde (valfritt)
- Fotosektion: rutnät av tillagda foton + knapp "+" för att lägga till foto
- Knapp "+" foto: visar bottom sheet med alternativen "Kamera" / "Galleri"
- FREE-gräns: max 3 foton per föremål — om FREE och redan har 3 visar "+" ett SnackBar: "Uppgradera till PRO för obegränsade foton"
- Beskärning med UCrop (externt bibliotek, startas som Activity från Compose med rememberLauncherForActivityResult)
- Omordning av foton med drag & drop (ReorderableList eller LazyColumn med detectDragGestures)
- Validering: namn obligatoriskt, antal minst 1
-
FREEMIUM-GATE — MYCKET VIKTIGT:
// Verifiera gränsen innan ett nytt föremål sparas val totalItems = itemRepository.getTotalItemCount() if (!proStatusRepository.isPro() && totalItems >= AppConfig.FREE_ITEM_LIMIT) { // Spara INTE föremålet // Navigera till ProUpgradeFragment med animation showUpgradeDialog() return } -
ItemDetailScreen:- HorizontalPager (Compose) med foton
- All föremålsdata
- Tagg-chips (grundläggande implementation nu, kompletta taggar i fas 12)
- Meny redigera / ta bort
-
Fotohantering:
- Spara i
filesDir/items/{itemId}/photo_{order}.jpg - Komprimera till max 1080px, kvalitet 80
- Vid borttagning av föremål, ta bort alla dess foton från disken
- Spara i
─────────────────────────────────────────
✅ SLUT PÅ FAS 10 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
MANUELLA TESTER:
□ I lådan "Böcker" → lägg till föremål "Sagan om Ringen"
□ Lägg till 2 foton (kamera eller galleri) — de syns i rutnätet
□ Beskär ett foto med UCrop — sparas beskärt
□ Spara föremålet — det visas i lådans lista
□ Räknaren på Hem ändras till "1 / 500 föremål"
□ Redigera föremålet — ändra antal — spara — verifiera
□ Lägg till 10 föremål till för att testa räknaren
□ Verifiera att räknaren på Hem uppdateras i realtid
□ Försök lägga till ett 4:e foto — uppgraderingsmeddelande visas
Skriv till mig: "Fas 10 OK" eller "Fas 10 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 11 — ML Kit Auto-taggar
Mål: När ett foto tas av ett föremål föreslår appen taggar automatiskt.
Vad du ska göra:
-
Efter att ha tagit/valt foto i
AddEditItemScreen, starta ML Kit Image Labeling:val labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS) labeler.process(InputImage.fromFilePath(context, photoUri)) .addOnSuccessListener { labels -> // Filtrera etiketter med confidence > 0.75 // Mappa till svenska (skapa en översättningsordbok) // Visa föreslagna chips som användaren kan trycka för att acceptera } -
Visa föreslagna taggar som chips med bock: "✓ Bok", "✓ Elektronik"...
-
Användaren trycker på chips för att acceptera eller avvisa dem.
-
Accepterade chips blir till föremålets taggar.
-
Minimal översättningsordbok EN→SV för de vanligaste etiketterna.
-
Om ML Kit inte hittar något med tillräcklig säkerhet visas ingenting (inget synligt fel).
─────────────────────────────────────────
✅ SLUT PÅ FAS 11 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
MANUELLA TESTER:
□ Lägg till ett föremål och ta foto på en bok — föreslagna chips visas
□ Acceptera ett chip — det läggs till som tagg på föremålet
□ Avvisa ett chip — det läggs inte till
□ Om ML Kit inte hittar något visas inget fel
□ Accepterade taggar syns i föremålsdetaljen
Skriv till mig: "Fas 11 OK" eller "Fas 11 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 12 — Global sökning (Room FTS4)
Mål: Omedelbar sökning i hela appen.
Vad du ska göra:
-
Lägg till FTS4-tabell i Room för sökning:
@Fts4(contentEntity = ItemEntity::class) @Entity(tableName = "items_fts") data class ItemFtsEntity( val name: String, val description: String, val tags: String ) -
SearchScreen:- Compose TextField som sökfält med realtidssökning (debounce 300ms)
- Resultat grupperade: först Föremål, sedan Lådor, sedan Platser
- Varje resultat visar: miniatyrbild, namn, fullständig plats (Hem > Rum > Låda)
- Trycka på resultat navigerar direkt till föremålet/lådan/platsen
- Tomt tillstånd med text "Sök efter föremål, lådor eller platser"
- Inga resultat med text "Inga resultat för '[sökning]'"
-
Grundläggande sökning FREE: söker bara på namn och beskrivning.
-
Avancerad sökning PRO: ytterligare filter per tagg, värde, datum. (Implementera UI men med PRO-gate.)
─────────────────────────────────────────
✅ SLUT PÅ FAS 12 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
MANUELLA TESTER:
□ Fliken Sök → skriv "ringen" → "Sagan om Ringen" visas
□ Resultatet visar i vilken låda och vilket rum det finns
□ Tryck på resultatet → navigerar direkt till föremålet
□ Sök efter något som inte finns → meddelande "Inga resultat"
□ Rensa texten → återgår till initialtillståndet
□ Sökningen är omedelbar (ingen synlig fördröjning)
Skriv till mig: "Fas 12 OK" eller "Fas 12 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 13 — QR-skanner
Mål: Skanna QR på en låda och navigera direkt till den.
Vad du ska göra:
-
QrScannerScreen(flik 3 i BottomNav):- Kameraförhandsvisning i realtid med ML Kit Barcode Scanner
- Animerad skanningsram (röd linje som rör sig upp och ned)
- Vid QR-detektering: sök i databasen efter lådan med det qrCodeData
- Om hittas: navigera till
BoxDetailScreenmed animation - Om EJ hittas: visa Snackbar "Detta QR tillhör ingen låda"
- X-knapp för att stänga skannern
-
Begär kamerabehörighet om den inte beviljats (med tydlig förklaring till användaren).
─────────────────────────────────────────
✅ SLUT PÅ FAS 13 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
MANUELLA TESTER:
□ Fliken Skanna → kameran öppnas med skanningsramen
□ Skriv ut eller visa QR-koden för lådan "Böcker" på skärmen
□ Skanna den → navigerar direkt till lådan "Böcker"
□ Skanna ett slumpmässigt QR från internet → "Detta QR tillhör ingen låda"
□ X-knappen stänger skannern och återgår till Hem
Skriv till mig: "Fas 13 OK" eller "Fas 13 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 14 — Kompletta Freemium-gates
Mål: 500-föremålsgränsen fungerar perfekt på alla ställen.
Vad du ska göra:
-
Permanent räknare i verktygsfältet på Hem:
- FREE:
"487 / 500 föremål"normal färg →"490 / 500 föremål"orange →"500 / 500 föremål"röd - PRO:
"1 243 föremål ∞"
- FREE:
-
Vid försök att skapa föremål nummer 501:
- Spara INTE föremålet
- Öppna
ProUpgradeScreenmed animation nedifrån - Användaren kan stänga och återgå utan att förlora det de höll på med
-
Subtil förloppsindikator på Hem (bara FREE):
[████████░░] 487/500 -
ProUpgradeScreen:- Tydlig lista över vad PRO inkluderar
- Pris (hämtas från Play Billing i nästa fas — visa "Laddar..." för nu)
- Knapp "Uppgradera till PRO" (ansluts i fas 15)
- Knapp "Kanske senare" — stänger fragmentet
─────────────────────────────────────────
✅ SLUT PÅ FAS 14 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
MANUELLA TESTER:
□ Föremålsräknaren syns alltid på Hem
□ Lägg till föremål tills du når 498 → räknaren blir orange
□ Nå 500 → räknaren blir röd
□ Försök skapa föremål 501 → uppgraderingsskärmen öppnas
□ Stäng uppgraderingen → du kan fortsätta navigera normalt
□ ProUpgrade-skärmen visar PRO-funktionslistan korrekt
Skriv till mig: "Fas 14 OK" eller "Fas 14 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 15 — Google Play Billing v6
Mål: Riktig PRO-köp fungerar.
Vad du ska göra:
-
Implementera
BillingRepositorymed Play Billing v6:- Anslut till BillingClient vid appstart
- Hämta produktdetaljer för
box_organizer_pro - Kontrollera väntande köp vid start
- Hantera hela flödet: initiera köp → bekräfta → spara tillstånd
-
Spara PRO-tillståndet i DataStore (bevaras mellan sessioner).
-
I
ProUpgradeScreen: visa det riktiga priset från Play Billing. -
Knappen "Uppgradera till PRO" startar Google Play-köpflödet.
-
VIKTIGT för tester: Konfigurera en intern testare i Google Play Console för att testa utan betalning.
-
Efter lyckat köp: räknaren på Hem ändras till
∞, alla PRO-gates låses upp.
─────────────────────────────────────────
✅ SLUT PÅ FAS 15 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
MANUELLA TESTER (kräver konfiguration i Play Console):
□ PRO-skärmen visar produktens riktiga pris
□ Knappen "Uppgradera till PRO" öppnar Googles köpdialog
□ Med testarkonto: slutför köpet
□ Efter köp: räknaren på Hem visar "∞"
□ Du kan lägga till föremål 501 utan gate
□ Stäng och öppna appen igen — du är fortfarande PRO
Skriv till mig: "Fas 15 OK" eller "Fas 15 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 16 — Exportera Excel + PDF (PRO)
Mål: Exportera komplett inventarie till Excel och PDF.
Vad du ska göra:
-
I
SettingsScreen(eller meny på Hem), PRO-knappar:- "Exportera till Excel" — med hänglåsikon om FREE
- "Exportera till PDF" — med hänglåsikon om FREE
- Om FREE och trycker: navigerar till
ProUpgradeScreen
-
Excel-export med Apache POI:
- Ett blad per plats
- Kolumner: Rum, Låda, Föremål, Beskrivning, Antal, Värde, Taggar
- Grundläggande stil: rubrik i fetstil, kanter
-
PDF-export:
- En sektion per Plats → Rum → Låda
- Föremål listade med miniatyrbild (max 100px), namn, beskrivning
- Generera med Androids
PdfDocument(kräver inget externt bibliotek)
-
Efter generering: öppna Android ShareSheet för att spara eller dela
─────────────────────────────────────────
✅ SLUT PÅ FAS 16 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
MANUELLA TESTER (kräver PRO eller simulering):
□ Exportera Excel → genererar .xlsx → ShareSheet öppnas
□ Öppna Excel i Google Sheets — data visas korrekt
□ Exportera PDF → genererar PDF → ShareSheet öppnas
□ PDF visar foton och föremål korrekt
□ I FREE-läge har knapparna hänglås och öppnar uppgradering
Skriv till mig: "Fas 16 OK" eller "Fas 16 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 17 — Krypterad Google Drive-backup (PRO)
Mål: Automatisk krypterad backup på Google Drive med 1-trycks återställning.
Vad du ska göra:
-
Backupflöde:
- Serialisera hela databasen till JSON (platser, rum, lådor, föremål, foton)
- Kryptera JSON med AES-256 med en nyckel härledd från användarens Google-konto
- Ladda upp till en Drive-mapp kallad "BoxOrganizerBackup"
- Spara tidsstämpel för senaste backup i DataStore
-
WorkManager för automatisk backup:
- Körs var 24:e timme om det finns WiFi och batteri > 20%
- Tyst notis om "Backup slutförd"
- Vid fel: notis med knapp "Försök igen"
-
I
SettingsScreen(PRO):- "Senaste backup: för 2 timmar sedan" eller "Aldrig"
- Knapp "Säkerhetskopiera nu"
- Knapp "Återställ från backup" → lista tillgängliga backuper i Drive
-
Återställning:
- Visar lista över backuper med datum
- Bekräftelse: "Återställa? ALL nuvarande data kommer att ersättas"
- Dekryptera, deserialisera, importera till Room
─────────────────────────────────────────
✅ SLUT PÅ FAS 17 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
MANUELLA TESTER:
□ Anslut Google-konto → "Säkerhetskopiera nu" → laddas upp till Drive
□ Öppna Google Drive på mobilen → mapp BoxOrganizerBackup → filen finns
□ Filen är INTE direkt läsbar (den är krypterad)
□ "Senaste backup" visar korrekt datum i Inställningar
□ Radera all data manuellt i appen
□ Återställ från backup → all data återkommer
□ Automatisk backup visas i WorkManager (App Inspection i Android Studio)
Skriv till mig: "Fas 17 OK" eller "Fas 17 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 18 — Export/Import fil (Familjedelning v1)
Mål: Exportera komplett inventarie till en fil för import på annan enhet.
Vad du ska göra:
-
Exportera:
- Generera en
.boxorg-fil (omdöpt ZIP) med JSON + alla komprimerade foton - Öppna ShareSheet: användaren kan skicka via WhatsApp, e-post, Drive etc.
- Generera en
-
Importera:
- I Inställningar: knapp "Importera inventarie"
- Öppnar filväljare för att välja
.boxorg-fil - Visar dialog: "Importera? Du kan välja: Sammanfoga med nuvarande data / Ersätt allt"
- Importerar och visar förlopp
-
Tydlig information till användaren: "Data importeras precis som den exporterades. Foton ingår i filen."
─────────────────────────────────────────
✅ SLUT PÅ FAS 18 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
MANUELLA TESTER:
□ Inställningar → "Exportera inventarie" → genererar .boxorg-fil
□ Filen har rimlig storlek (inkluderar komprimerade foton)
□ Skicka filen till dig själv via e-post eller Drive
□ På samma eller annan enhet: "Importera inventarie" → välj filen
□ Välj "Sammanfoga" → data läggs till utan att radera befintliga
□ Välj "Ersätt" → data ersätts helt
Skriv till mig: "Fas 18 OK" eller "Fas 18 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 19 — Biometri / PIN
Mål: Appen låses och låses upp med fingeravtryck, ansikts-ID eller PIN.
Vad du ska göra:
-
Första gången appen öppnas: be inte om biometri (opt-in i Inställningar).
-
I Inställningar: växla "Skydda app med biometri/PIN".
-
Vid aktivering: be om att konfigurera en reserv-PIN med 4-6 siffror.
-
När aktiverat: vid öppning av appen (eller återkomst från bakgrunden efter 60 sekunder) begärs autentisering.
-
Använd
BiometricPromptmed fallback till egna PIN:val promptInfo = BiometricPrompt.PromptInfo.Builder() .setTitle("Lås upp Box Organizer") .setSubtitle("Använd fingeravtryck eller PIN") .setNegativeButtonText("Använd PIN") .build() -
SQLCipher-nyckeln härleds från PIN + salt lagrat i EncryptedSharedPreferences.
─────────────────────────────────────────
✅ SLUT PÅ FAS 19 — OBLIGATORISK VERIFIERING
─────────────────────────────────────────
MANUELLA TESTER:
□ Inställningar → aktivera skydd → konfigurera PIN "1234"
□ Lägg appen i bakgrunden → vänta 60s → återgå → autentisering begärs
□ Använd fingeravtryck → låser upp
□ Avbryt fingeravtryck → knapp "Använd PIN" → ange PIN → låser upp
□ Fel PIN → felmeddelande, låser inte upp
□ Inaktivera skydd från Inställningar → ingen autentisering begärs längre
Skriv till mig: "Fas 19 OK" eller "Fas 19 FEL: [beskrivning]"
─────────────────────────────────────────
FAS 20 — Slutpolering: UI, Android Widget, Mörkt läge
Mål: Polerad app med hemskärmswidget och perfekt mörkt läge.
Vad du ska göra:
-
Android Widget (viktigast i denna fas):
- Widget 4x1: snabbsökare av föremål
- Att skriva i widgeten → öppnar appen direkt i
SearchScreenmed texten - Widget 2x2: visar de 4 senast tillagda föremålen
-
Mörkt läge: kontrollera ALLA skärmar i mörkt läge. Rätta till hårdkodade färger som inte anpassar sig.
-
Övergångsanimationer mellan skärmar (Material Motion):
- Shared Element Transition på foton
- Fade + slide vid normal navigation
-
Laddningstillstånd: varje skärm som laddar data från databasen visar ett skelett eller spinner under laddning.
-
Synlig felhantering: om något misslyckas (korrupt databas, Drive frånkopplat) ser användaren ett tydligt meddelande — aldrig en tom skärm eller krasch.
-
Slutlig tillgänglighetsgenomgång:
- Alla ImageView har
contentDescription - Minst 48dp tryckytor
- Korrekt färgkontrast i ljust och mörkt läge
- Alla ImageView har
─────────────────────────────────────────
✅ SLUT PÅ FAS 20 — KOMPLETT SLUTVERIFIERING
─────────────────────────────────────────
KOMPLETTA MANUELLA TESTER:
□ Widget på hemskärmen — sökning öppnar appen
□ Aktivera mörkt läge — hela appen ser bra ut
□ Navigera genom ALLA skärmar i mörkt läge — inga trasiga färger
□ Widgeten för senaste föremål visar riktiga data
□ Mjuka övergångar mellan skärmar
□ Inga kraschar i något normalt användarflöde
□ TalkBack aktiverat — alla element är tillgängliga
🎉 GRATTIS! Appen är klar.
Nästa steg: förbered för uppladdning till Google Play (signering, skärmdumpar, beskrivning).
Skriv till mig: "Fas 20 OK - APPEN KLAR" 🚀
─────────────────────────────────────────
SLUTLIGA ANTECKNINGAR TILL CLAUDE CODE
- Generera aldrig kod som inte kompilerar. Om du är osäker på ett API, använd det enklaste alternativet som fungerar.
- Varje .kt-fil du skapar måste vara komplett — utan saknade imports, utan referenser till klasser som ännu inte skapats.
- Om programmeraren rapporterar ett fel, fixa det helt och hållet innan du fortsätter till nästa fas.
- Programmeraren är QA — om de säger att något inte fungerar har de rätt. Ifrågasätt det inte, fixa det.
- Dokumentera "varför" i kommentarer, inte bara "vad".
Lycka till med projektet! 📦