rmt-box.organizer.inventory/box-organizer-prompt-sv.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

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:

  1. Slutför EN hel fas innan du går vidare till nästa.
  2. I slutet av varje fas, STANNA och fråga programmeraren att kompilera och testa.
  3. 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 // TODO bara i intern logik, aldrig i UI.
  4. Om något inte kompilerar, fixa det innan du fortsätter. Godkänn aldrig något som ger fel.
  5. Maximal 700 rader per .kt-fil. Om en fil växer mer, dela upp den i mindre klasser med tydliga ansvarsområden.
  6. Förklara allt utförligt i kodkommentarer. Anta inte att programmeraren förstår varför du gör något.
  7. 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:

  1. Öppna det befintliga projektet i Android Studio.

  2. I Project-panelen (Android-vy), expandera app > java.

  3. Högerklicka på com.roundingmobile.boxorganizerinventoryRefactor > Rename.

  4. Skriv boi och bekräfta. Android Studio döper om paketet i alla filer.

  5. Öppna app/build.gradle.kts och verifiera att applicationId = "com.roundingmobile.boi".

  6. Öppna AndroidManifest.xml och verifiera att inga referenser till det gamla namnet finns kvar.

  7. Gör Build > Clean Project följt av Build > Rebuild Project.

  8. 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 boxorganizerinventory och ersätta med boi i 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:

  1. 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
  2. Konfigurera libs.versions.toml med ALLA versioner.

  3. Konfigurera båda build.gradle.kts (projekt och app) med alla beroenden.

  4. 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" />
    
  5. 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")
    
  6. Skapa AppConfig.kt med alla freemium-konstanter.

  7. Skapa Application-klassen med @HiltAndroidApp.

  8. 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:

  1. Skapa alla Room-entiteter i data/local/entity/:

    • LocationEntity.kt
    • RoomEntity.kt (använd namnet StorageRoom för att undvika krock med android.room)
    • BoxEntity.kt
    • ItemEntity.kt
    • ItemPhotoEntity.kt
    • TagEntity.kt
    • ItemTagEntity.kt (pivottabell, @Entity(primaryKeys = ["itemId", "tagId"]))
  2. Skapa DAOs i data/local/dao/:

    • LocationDao.kt — CRUD + Flow<List>
    • StorageRoomDao.kt — CRUD + Flow per locationId
    • BoxDao.kt — CRUD + Flow per roomId
    • ItemDao.kt — CRUD + Flow per boxId + räkna totalt antal föremål (för freemium-gräns)
    • ItemPhotoDao.kt — CRUD per itemId
    • TagDao.kt — komplett CRUD
    • SearchDao.kt — FTS4 för global sökning
  3. Skapa AppDatabase.kt med SQLCipher:

    // VIKTIGT: SQLCipher kräver SupportFactory
    // Nyckeln genereras slumpmässigt och sparas i EncryptedSharedPreferences
    val factory = SupportFactory(passphrase)
    Room.databaseBuilder(...)
        .openHelperFactory(factory)
        .build()
    
  4. Skapa DatabaseModule.kt i Hilt med databasprovidern.

  5. 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:

  1. Skapa DatabaseModule.kt — tillhandahåller databasen och alla DAOs.
  2. Skapa RepositoryModule.kt — kopplar gränssnitt till implementationer.
  3. Skapa PreferencesModule.kt — tillhandahåller DataStore.
  4. Annotera MainActivity med @AndroidEntryPoint.
  5. 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:

  1. Skapa gränssnitt i domain/repository/:

    • LocationRepository
    • StorageRoomRepository
    • BoxRepository
    • ItemRepository
    • TagRepository
  2. Skapa implementationer i data/repository/ som:

    • Mappar Entity ↔ Domänmodell
    • Exponerar Flow<> för reaktiva data
    • Använder suspend fun för skrivoperationer
    • Hanterar fel med Result<T>
  3. Skapa ProStatusRepository som 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:

  1. Konfigurera Navigation Compose med en NavHost och NavController i MainActivity.

  2. 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()
  3. Konfigurera MainActivity med Scaffold + NavigationBar från Compose med 4 flikar:

    • 🏠 Hem
    • 🔍 Sök
    • 📷 Skanna QR
    • ⚙️ Inställningar
  4. 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:

  1. Implementera HomeScreen med:

    • 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ål alltid synlig i verktygsfältet (FREE) eller ∞ föremål (PRO)
  2. Implementera HomeViewModel med:

    • StateFlow<List<Location>> för listan
    • StateFlow<Int> för totalt antal föremål
    • StateFlow<Boolean> för att veta om det är PRO
  3. FAB (+) navigerar till AddEditLocationScreen.

  4. Att trycka på en plats navigerar till LocationDetailScreen med 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:

  1. 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
  2. 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?"
  3. 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)
  • AddEditRoomScreen med namn, beskrivning, foto
  • RoomDetailScreen med 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:

  1. 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
  2. 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
  3. 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
    
  4. "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:

  1. 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
  2. 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
    }
    
  3. ItemDetailScreen:

    • HorizontalPager (Compose) med foton
    • All föremålsdata
    • Tagg-chips (grundläggande implementation nu, kompletta taggar i fas 12)
    • Meny redigera / ta bort
  4. 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
─────────────────────────────────────────
✅ 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:

  1. 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
        }
    
  2. Visa föreslagna taggar som chips med bock: "✓ Bok", "✓ Elektronik"...

  3. Användaren trycker på chips för att acceptera eller avvisa dem.

  4. Accepterade chips blir till föremålets taggar.

  5. Minimal översättningsordbok EN→SV för de vanligaste etiketterna.

  6. 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:

  1. 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
    )
    
  2. 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]'"
  3. Grundläggande sökning FREE: söker bara på namn och beskrivning.

  4. 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:

  1. 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 BoxDetailScreen med animation
    • Om EJ hittas: visa Snackbar "Detta QR tillhör ingen låda"
    • X-knapp för att stänga skannern
  2. 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:

  1. 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 ∞"
  2. Vid försök att skapa föremål nummer 501:

    • Spara INTE föremålet
    • Öppna ProUpgradeScreen med animation nedifrån
    • Användaren kan stänga och återgå utan att förlora det de höll på med
  3. Subtil förloppsindikator på Hem (bara FREE): [████████░░] 487/500

  4. 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:

  1. Implementera BillingRepository med 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
  2. Spara PRO-tillståndet i DataStore (bevaras mellan sessioner).

  3. I ProUpgradeScreen: visa det riktiga priset från Play Billing.

  4. Knappen "Uppgradera till PRO" startar Google Play-köpflödet.

  5. VIKTIGT för tester: Konfigurera en intern testare i Google Play Console för att testa utan betalning.

  6. 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:

  1. 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
  2. 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
  3. 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)
  4. 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:

  1. 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
  2. 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"
  3. 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
  4. Å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:

  1. 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.
  2. 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
  3. 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:

  1. Första gången appen öppnas: be inte om biometri (opt-in i Inställningar).

  2. I Inställningar: växla "Skydda app med biometri/PIN".

  3. Vid aktivering: be om att konfigurera en reserv-PIN med 4-6 siffror.

  4. När aktiverat: vid öppning av appen (eller återkomst från bakgrunden efter 60 sekunder) begärs autentisering.

  5. Använd BiometricPrompt med 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()
    
  6. 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:

  1. Android Widget (viktigast i denna fas):

    • Widget 4x1: snabbsökare av föremål
    • Att skriva i widgeten → öppnar appen direkt i SearchScreen med texten
    • Widget 2x2: visar de 4 senast tillagda föremålen
  2. Mörkt läge: kontrollera ALLA skärmar i mörkt läge. Rätta till hårdkodade färger som inte anpassar sig.

  3. Övergångsanimationer mellan skärmar (Material Motion):

    • Shared Element Transition på foton
    • Fade + slide vid normal navigation
  4. Laddningstillstånd: varje skärm som laddar data från databasen visar ett skelett eller spinner under laddning.

  5. Synlig felhantering: om något misslyckas (korrupt databas, Drive frånkopplat) ser användaren ett tydligt meddelande — aldrig en tom skärm eller krasch.

  6. Slutlig tillgänglighetsgenomgång:

    • Alla ImageView har contentDescription
    • Minst 48dp tryckytor
    • Korrekt färgkontrast i ljust och mörkt läge
─────────────────────────────────────────
✅ 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! 📦