Există o aplicație internă Android pentru inventarierea în teren a echipamentelor din depozite și șantiere. Acum funcționează doar online: scanarea QR/coduri de bare, vizualizarea cardurilor, crearea de acte și realizarea de fotografii. Adesea, site-urile nu au o rețea, forțând angajații să ia notițe în notele de la terți și apoi să transfere manual datele. Trebuie să adăugăm un mod offline cu drepturi depline, cu sincronizare fiabilă atunci când apare internetul. Mediul tehnic: Kotlin, Android 10+, MVVM, Retrofit, Room este deja parțial utilizat, API-ul serverului nu poate fi schimbat. Autorizare prin OAuth2, jetonul de acces durează 30 de minute, jetonul de reîmprospătare este disponibil. Backend-ul oferă puncte finale REST: GET /items?updatedSince=timestamp, POST /acts, PATCH /items/{id}, încărcarea fotografiilor ca punct final separat. Serverul are un câmp versiune (int) și updatedAt (ISO) pentru entitățile Item și Act, dar nu există niciun conflict de rezolvare pe server. Ce trebuie implementat: - Stocare locală: extindeți schema Room pentru Item, Act, Attachment, precum și tabelele operațiuni în așteptare și metadatele de sincronizare. Datele (inclusiv câmpurile sensibile și căile pentru atașamente) trebuie să fie stocate criptat pe dispozitiv. Este acceptabil să utilizați Jetpack Security (EncryptedFile/EncryptedSharedPreferences) și/sau SQLCipher pentru Android; justificați-vă alegerea într-un comentariu către PR. - Modificare coadă: toate acțiunile utilizatorului offline ar trebui să fie înregistrate ca operațiuni idempotente (crearea de acte, schimbarea stărilor, legarea fotografiilor, editarea câmpurilor), cu posibilitatea de a retrimite fără duplicate. Fiecare operațiune necesită un clientOperationId (UUID) și reguli de retrimitere deterministe. - Sincronizare în fundal: prin WorkManager (constrângeri: rețea conectată, bateria nu este descărcată). Implementați sincronizarea bidirecțională: extrageți actualizări de pe server prin updatedSince, apoi împingeți operațiunile locale. Suport off-off, erori parțiale, timeout-uri de rețea și reîmprospătare token. - Rezolvarea conflictului pe client: dacă Itemul a fost modificat local și s-a schimbat și pe server (versiune/updatedAt), trebuie să aplicați o strategie: modificarea locală are prioritate pentru un anumit set de câmpuri (remediați lista), dar dacă există un conflict prin stare/responsabil - arătați utilizatorului un ecran de comparație cu selectarea unei opțiuni și înregistrarea soluției. Ecranul ar trebui să apară numai pentru entitățile care într-adevăr sunt în conflict. - Atașamente (fotografii): salvați fotografiile local cu o coadă de descărcare, supraviețuiți la repornirea aplicației. Limitare: nu mai mult de 50 MB în total în coadă; dacă este depășit, afișați o notificare clară și blocați adăugarea de noi atașamente până la sincronizare/ștergere. - Telemetrie: adăugați un jurnal de sincronizare local (la un fișier) cu niveluri, fără a-l trimite afară. Jurnalul trebuie să conțină numărul de operațiuni, timpul de sincronizare, numărul de conflicte și erorile API. Rezultat specific: PR la un depozit cu un mod offline de lucru, migrări de baze de date, teste și instrucțiuni scurte despre cum să verificați dispozitivul. Limitări: nu modificați API-ul serverului, adăugați biblioteci noi doar atunci când este necesar și cu o amprentă minimă, suportați Android 10-14, aplicația trebuie să funcționeze corect fără Servicii Google Play. Criterii de acceptare (măsurabile): 1) În modul avion, puteți: scana 30 de poziții, schimba cel puțin 20 de câmpuri pentru articole diferite, creați 5 acte și atașați 10 fotografii - toate datele sunt salvate local și afișate după repornirea aplicației. 2) După pornirea internetului, sincronizarea este finalizată fără duplicate: pe server apar exact 5 acte noi, articolul nu are modificări duplicate, toate cele 10 fotografii sunt legate. 3) În cazul unui conflict creat artificial (articolul este schimbat pe server după ultima extragere, iar același articol este schimbat local), aplicația detectează conflictul și afișează un ecran de comparație; după ce utilizatorul selectează rezultatul se potrivește cu versiunea selectată, conflictul dispare cu următoarea sincronizare. 4) Sincronizarea în fundal prin WorkManager nu se efectuează mai mult de o dată la 15 minute, dar lansarea manuală din ecranul de setări inițiază sincronizarea imediat. 5) Datele locale sunt cu adevărat criptate: este imposibil să citiți conținutul bazei de date/fișierelor atașate în text clar atunci când sunt copiate de pe dispozitiv (este suficient să specificați metoda de verificare). Etape așteptate: auditul arhitecturii actuale și al schemei de date, proiectarea unui model de sincronizare și conflict, implementarea stocării/cozii, implementarea motorului de sincronizare, conflicte de UI, testare și stabilizare. Voi oferi acces la: surse Android, colectare Swagger/request, banc de testare API, mai multe conturi de testare și scenarii de utilizare pe teren.