Add comprehensive iOS unit and UI test suites for greenfield test plan

- Create unit tests: DataLayerTests (27 tests for DATA-001–007), DataManagerExtendedTests
  (20 tests for TASK-005, TASK-012, TCOMP-003, THEME-001, QA-002), plus ValidationHelpers,
  TaskMetrics, StringExtensions, DoubleExtensions, DateUtils, DocumentHelpers, ErrorMessageParser
- Create UI tests: AuthenticationTests, PasswordResetTests, OnboardingTests, TaskIntegration,
  ContractorIntegration, ResidenceIntegration, DocumentIntegration, DataLayer, Stability
- Add UI test framework: AuthenticatedTestCase, ScreenObjects, TestFlows, TestAccountManager,
  TestAccountAPIClient, TestDataCleaner, TestDataSeeder
- Add accessibility identifiers to password reset views for UI test support
- Add greenfield test plan CSVs and update automated column for 27 test IDs
- All 297 unit tests pass across 60 suites

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
treyt
2026-02-24 15:37:56 -06:00
parent fe28034f3d
commit fc0e0688eb
34 changed files with 6699 additions and 1 deletions

View File

@@ -0,0 +1,147 @@
"Test_ID","Domain","Feature","Scenario","Test_Method","Priority","Platforms","Preconditions","Steps","Expected_Result","Edge_Cases","Assumptions","Automation_Recommendation"
"AUTH-001","Authentication","App start routing","First launch routes to onboarding when hasCompletedOnboarding=false","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Fresh install, no token","Launch app","Onboarding welcome is shown, not login/main tabs","Corrupted local onboarding flag","Onboarding state is persisted locally","Automate (UI smoke)"
"AUTH-002","Authentication","App start routing","Returning user with onboarding complete and no token routes to login","Manual + E2E UI","P0","iOS, Android, Web, Desktop","hasCompletedOnboarding=true, token missing","Launch app","Login screen shown","Stale cached user object present","Token is source of truth","Automate"
"AUTH-003","Authentication","App start routing","Authenticated + verified user routes to main tabs","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Valid token, verified user","Launch app","Main tab shell displayed","Cached token exists but API fails","Current-user fetch determines validity","Automate"
"AUTH-004","Authentication","App start routing","Authenticated but unverified user routes to verify email","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Valid token, verified=false","Launch app","Verify email screen shown","User gets verified between launches","Verification status fetched from backend","Automate"
"AUTH-005","Authentication","Token invalidation","Invalid token at startup clears session and returns to login","Manual + Integration","P0","iOS, Android, Web, Desktop","Expired/invalid token stored","Launch app","Data cleared and login shown","Backend 500 vs 401 behavior","401/failed current-user means logout","Automate"
"AUTH-006","Authentication","Login","Valid username/password login success","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Existing verified account","Submit login form","Token persisted, lookups initialized, main shown","Slow network during login","Login API returns token+user","Automate"
"AUTH-007","Authentication","Login","Invalid credentials shows actionable error","Manual + E2E UI","P0","iOS, Android, Web, Desktop","No session","Submit wrong password","Error shown, user remains on login","Rate-limit or lockout responses","Error parser maps backend errors","Automate"
"AUTH-008","Authentication","Login validation","Empty username/password blocked client-side","Manual + UI","P1","iOS, Android, Web, Desktop","No session","Tap login with empty fields","Validation errors shown, no API call","Whitespace-only input","Client validation active","Automate"
"AUTH-009","Authentication","Registration","Create account success then verify-email step","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Unique email/username","Submit valid registration","Session established and verify-email screen appears","Existing email conflict","Register API auto-authenticates","Automate"
"AUTH-010","Authentication","Registration validation","Invalid email/password formats rejected","Manual + UI","P1","iOS, Android, Web, Desktop","No session","Try invalid email, short password, weak password","User-friendly validation errors","Unicode emails, long usernames","Validation rules are enforced consistently","Automate"
"AUTH-011","Authentication","Email verification","Valid 6-digit code verifies account","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged-in unverified user","Enter 6-digit numeric code","Account marked verified and app routes forward","Code already used","Code must be exactly 6 digits","Automate"
"AUTH-012","Authentication","Email verification","Non-numeric/short/long code blocked","Manual + UI","P1","iOS, Android, Web, Desktop","On verify-email screen","Enter invalid codes","Verify action disabled or error shown","Pasted with spaces","Code input sanitizes to digits","Automate"
"AUTH-013","Authentication","Logout","Logout clears token, user data, lookups, and returns to login","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Tap logout","Login shown; protected API calls fail without token","Logout API fails network-side","Client clears state even if API call fails","Automate"
"AUTH-014","Authentication","Forgot password","Request reset by email success path","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Known account email","Submit forgot-password email","Success message and next step available","Unknown email behavior privacy-safe","Backend may still return generic success","Automate"
"AUTH-015","Authentication","Reset code verification","Verify reset code success path","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Reset email submitted","Enter correct code","Reset-token available for password reset","Expired code","Code verification endpoint returns token","Automate"
"AUTH-016","Authentication","Password reset","Reset password success with matching confirmation","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Valid reset token","Enter new password + confirm","Password changed; user can log in (or auto-login flow)","Token expires mid-flow","Reset endpoint ignores confirm field","Automate"
"AUTH-017","Authentication","Password reset","Mismatched password confirmation blocked","Manual + UI","P1","iOS, Android, Web, Desktop","Reset password screen","Enter mismatch","Inline error; no reset request","Trailing spaces","Client validates before submit","Automate"
"AUTH-018","Authentication","Deep link reset","Password-reset deep link opens flow with token prefilled","Manual + E2E UI","P0","iOS, Android","Installed app with deep-link support","Open reset deep link","Forgot/reset flow opens and token is consumed","Malformed token in URL","Deep link token can be cleared on back","Automate"
"AUTH-019","Authentication","SSO Apple","Apple Sign-In success creates or signs in account","Manual + Integration","P1","iOS","Apple-capable test device/simulator","Complete Apple sign-in","Session established; verification state handled","User hides email, first-login only email scope","Apple credential mapped to backend request","Automate partially (mock)"
"AUTH-020","Authentication","SSO Google","Google Sign-In success path","Manual + Integration","P1","Android, Web, KMP UI","Google sign-in configured","Complete Google sign-in","Session established with backend token","Revoked Google token","Backend validates ID token","Automate partially"
"ONB-001","Onboarding","Intent split","Start Fresh path goes through value props and name residence","Manual + E2E UI","P0","iOS, Android (KMP)","Fresh install","Choose Start Fresh and continue","Step order matches intended flow","Back navigation at each step","Flow differs by intent","Automate"
"ONB-002","Onboarding","Intent split","Join Existing path skips value/name steps and goes to account creation","Manual + E2E UI","P0","iOS, Android (KMP)","Fresh install","Choose Join Existing","Expected condensed step order","User switches intent mid-flow","Intent persisted during onboarding","Automate"
"ONB-003","Onboarding","Navigation","Back button transitions and step history correctness","Manual + UI","P1","iOS, Android (KMP)","In onboarding multi-step flow","Navigate forward then back","Returns to correct previous step","Back from verify-email triggers logout on iOS","Back behavior is product-defined","Automate"
"ONB-004","Onboarding","Skip behavior","Skippable screens skip to next valid state","Manual + UI","P1","iOS, Android (KMP)","On skippable step","Tap Skip","Progress advances without corrupting state","Skip on terminal upsell step completes onboarding","Skip availability is step-dependent","Automate"
"ONB-005","Onboarding","Residence bootstrap","Start Fresh creates residence automatically after verification","Manual + Integration","P0","iOS, Android (KMP)","Onboarding start-fresh with residence name","Verify email and continue","Residence created or graceful fallback if creation fails","Blank residence name bypasses creation","Creation failure should not hard-block onboarding","Automate"
"ONB-006","Onboarding","Join residence","Join-existing flow joins via share code","Manual + E2E UI","P0","iOS, Android (KMP)","Valid join code","Submit code in onboarding","User added to shared residence","Expired/invalid/reused code","Join code endpoint enforces ownership rules","Automate"
"ONB-007","Onboarding","First task","First-task onboarding step can create selected tasks","Manual + Integration","P1","iOS, Android (KMP)","On first-task step","Select templates and continue","Tasks created; flow proceeds","Partial task creation failures","At least one success considered success in KMP VM","Automate"
"ONB-008","Onboarding","Completion persistence","Completing onboarding persists flag and bypasses onboarding next launch","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Completed onboarding once","Restart app","Onboarding is skipped","App data clear resets flag","Onboarding flag stored locally","Automate"
"RES-001","Residences","List","Residences list loads with empty and non-empty states","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Open residences tab","Correct list/empty UI shown","Slow API and stale cache","List can come from cache or network","Automate"
"RES-002","Residences","Create","Create residence with required fields only","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Fill minimum fields and save","Residence appears in list/detail","Duplicate name allowed/not allowed behavior","Name required; other fields optional","Automate"
"RES-003","Residences","Create validation","Prevent submit when required name missing","Manual + UI","P1","iOS, Android, Web, Desktop","Open add residence form","Submit blank name","Validation error, no API call","Whitespace-only name","Required validation trims input","Automate"
"RES-004","Residences","Create optional fields","All optional numeric/text/address fields persist correctly","Manual + Integration","P1","iOS, Android, Web, Desktop","Open add residence form","Fill all fields and save","Values round-trip correctly in detail/edit","Decimals for bathrooms/lot size","Type conversion preserves precision","Automate"
"RES-005","Residences","Edit","Edit residence updates list and detail views","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Existing residence","Modify fields and save","Updated values shown immediately","Concurrent edit from another user","DataManager updates local caches","Automate"
"RES-006","Residences","Delete","Delete residence removes related task/document cached subsets","Manual + Integration","P0","iOS, Android, Web, Desktop","Residence with tasks/docs exists","Delete residence","Residence gone; related cached sections removed","Delete primary/only residence","Server cascade semantics documented","Automate"
"RES-007","Residences","Primary residence","Set/retain primary residence behavior","Manual","P2","iOS, Android, Web, Desktop","Multiple residences","Mark one as primary and reload","Only intended residence is primary","Two rapid primary updates","Backend enforces uniqueness","Automate partially"
"RES-008","Residences","Summary","Residence summary counts derive from kanban columns correctly","Manual + Integration","P1","iOS, Android, Web, Desktop","Residence with mixed task statuses","Open summary cards","Counts match task column truth","No tasks state","Summary can be client-computed","Automate"
"RES-009","Residences","Join by code","Join residence from manual share code entry","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Valid share code from another account","Enter code in join flow","Membership granted and residence appears","Code expired or already member","Join endpoint returns reasoned errors","Automate"
"RES-010","Residences","Generate share code","Generate/refresh residence share code","Manual + Integration","P1","iOS, Android, Web, Desktop","Owner access to residence","Generate code","New valid code returned/visible","Repeated generation invalidates old codes","Access limited by role","Automate"
"RES-011","Residences","Share package export","Create residence .casera package and open share sheet","Manual","P1","Android","Residence exists, logged in","Tap share residence","Share sheet opens with file attachment","Filename sanitization with special chars","Backend generates package with shareCode","Automate partially"
"RES-012","Residences","Share package import","Import .casera residence file joins residence","Manual + Integration","P0","Android","Valid .casera file received","Open file via app/import handler and confirm","Join succeeds and success dialog shown","Invalid JSON/wrong extension/no auth","Import requires auth and parse success","Automate partially"
"RES-013","Residences","Task report","Generate residence tasks report with/without email","Manual + Integration","P2","iOS, Android, Web, Desktop","Residence exists","Trigger generate report","Report creation success feedback","Invalid email format optional field","Backend handles async report generation","Automate"
"RES-014","Residences","Manage users view","Residence users list loads with owner/member roles","Manual + E2E UI","P1","iOS, Android (KMP)","Residence with multiple users","Open manage users","Accurate users and role indicators displayed","Owner missing from response","Role data trusted from API","Automate"
"RES-015","Residences","Remove user","Owner removes a member successfully","Manual + Integration","P0","iOS, Android (KMP)","Owner logged in, target member exists","Remove member","Member removed and state refreshes","Attempt remove self/owner","API enforces permission rules","Automate"
"TASK-001","Tasks","All tasks load","Kanban columns load for all residences","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in with at least one residence","Open tasks tab","Columns and counts render correctly","Zero tasks across all columns","Columns include overdue/in-progress/due-soon/upcoming/completed/cancelled","Automate"
"TASK-002","Tasks","Residence filtering","Tasks by residence uses filtered allTasks cache correctly","Manual + Integration","P1","iOS, Android, Web, Desktop","Multiple residences with tasks","Open residence detail tasks","Only selected residence tasks shown","Residence cache stale while global cache fresh","Client-side filtering path exists","Automate"
"TASK-003","Tasks","Create task","Create minimal valid task","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Residence exists, lookups loaded","Submit task with required fields","Task appears in expected column","Missing lookups due to failed seed load","Category/frequency/priority are required","Automate"
"TASK-004","Tasks","Create from template","Create task from template browser","Manual + E2E UI","P1","iOS, Android, Web, Desktop","Templates available","Open templates, select one, save","Task prefilled and created","Template with long description/tags","Template data from seeded lookups","Automate"
"TASK-005","Tasks","Template search","Search templates requires >=2 chars and limits results","Manual + Unit","P2","iOS, Android, Web, Desktop","Templates loaded","Search with 1 char then 2+ chars","1 char returns empty, 2+ filtered max 10","Case-insensitive tag match","Search is local in DataManager","Automate"
"TASK-006","Tasks","Edit task","Edit task fields and persist updates","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Existing task","Change title/category/frequency/priority/due/cost","Task updates and remains consistent in caches","Invalid cost string conversion","Edit route passes serialized fields","Automate"
"TASK-007","Tasks","Mark in progress","Transition task to in-progress column","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Existing non-in-progress task","Tap mark in progress","Task moves to in-progress column","Already in progress idempotency","UpdateTask uses kanbanColumn target","Automate"
"TASK-008","Tasks","Clear in progress","Clear in-progress state returns task to scheduled column","Manual + Integration","P1","iOS, Android, Web, Desktop","Task currently in progress","Clear in-progress","Task leaves in-progress with correct new column","Due date past while clearing","Backend decides target column","Automate"
"TASK-009","Tasks","Cancel task","Cancel action moves task to cancelled state","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Active task exists","Cancel task","Task appears in cancelled column/state","Cancel already-cancelled task","Endpoint idempotency defined","Automate"
"TASK-010","Tasks","Uncancel task","Restore cancelled task to active lifecycle","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Cancelled task exists","Uncancel task","Task restored to appropriate column","Uncancel archived task","State transitions validated by API","Automate"
"TASK-011","Tasks","Archive/unarchive","Archive hides task from active flow; unarchive restores","Manual + Integration","P1","iOS, Android, Web, Desktop","Task exists","Archive then unarchive","Visibility toggles correctly","Archived + cancelled combined states","Archive APIs available and cached updates propagate","Automate"
"TASK-012","Tasks","Delete semantics","Task removal updates all cached columns and summaries","Manual + Integration","P1","iOS, Android, Web, Desktop","Task exists in cached data","Delete or server-remove task then refresh","Task absent in all views and counts updated","Task present in multiple cached views","DataManager removeTask updates all maps","Automate"
"TASK-013","Tasks","Due date handling","Past/now/future due dates map to correct columns","Manual + Integration","P1","iOS, Android, Web, Desktop","Tasks with boundary due dates","Load tasks around timezone boundaries","Kanban placement matches backend logic","DST transitions","Backend provides canonical kanban_column","Automate"
"TASK-014","Tasks","Cost fields","Estimated cost accepts numeric and rejects invalid formats","Manual + UI","P2","iOS, Android, Web, Desktop","Task form open","Enter valid/invalid cost strings","Valid persisted; invalid blocked or sanitized","Locale decimal separators","Cost parsed to Double","Automate"
"TASK-015","Tasks","Task detail navigation","Push/deep-link task navigation opens tasks tab and relevant task context","Manual + E2E UI","P0","iOS, Android","App receives task navigation ID","Tap notification/open intent","Tasks tab selected and task reachable","Task deleted before open","Main shell handles navigate_to_task contract","Automate"
"TASK-016","Tasks","Bulk state refresh","After any task CRUD/action, summary cards refresh immediately","Manual + Integration","P1","iOS, Android, Web, Desktop","Dashboard visible with summaries","Perform task action","Summary counts update without hard reload","Rapid consecutive actions","Summary derived from cached kanban","Automate"
"TASK-017","Tasks","Concurrency","Two users edit same task; conflict resolution UX","Manual","P2","iOS, Android, Web, Desktop","Same task open on two accounts","Save conflicting edits","Consistent final state and clear error/last-write behavior","Out-of-order responses","Server conflict strategy documented","Manual"
"TCOMP-001","Task completion","Complete task basic","Complete task with notes/cost/rating","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Active task exists","Open complete flow and submit","Completion created and task column updates","Null rating vs default value","Completion endpoint accepts optional fields","Automate"
"TCOMP-002","Task completion","Complete with images","Attach one or multiple images during completion","Manual + Integration","P0","iOS, Android","Camera/gallery permission granted","Submit completion with images","Images uploaded and linked to completion","Large image compression/failure mid-upload","Image compression and multipart upload enabled","Automate partially"
"TCOMP-003","Task completion","Validation","Required completed-by field enforced (iOS form state)","Manual + UI","P1","iOS","Open complete task form","Submit blank completed-by","Validation error shown","Whitespace-only value","CompletedBy required by client form","Automate"
"TCOMP-004","Task completion","Completion history","History list loads for task and sorted correctly","Manual + Integration","P1","iOS, Android, Web, Desktop","Task with multiple completions","Open completion history","Entries ordered and accurate","Missing images in older completion records","History endpoint returns full list","Automate"
"DOC-001","Documents","List","Load all documents and residence-filtered documents","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in with docs data","Open documents tab and residence detail docs","Correct sets shown","Residence with zero docs","List supports optional residence filter","Automate"
"DOC-002","Documents","Create document","Create generic document with required fields","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Residence exists","Create document with title/type/residence","Document appears in lists","Missing residence selection on create","Create requires title/type/residence","Automate"
"DOC-003","Documents","Create warranty fields","Create warranty/appliance with provider/dates metadata","Manual + Integration","P1","iOS, Android, Web, Desktop","Document form open","Enter warranty-specific fields and save","Fields persist and render in detail","End date before start date","Date validation expectations defined","Automate"
"DOC-004","Documents","Edit document","Edit existing document including type/category/tags","Manual + E2E UI","P1","iOS, Android, Web, Desktop","Document exists","Modify and save","Detail/list reflect updates","Switching types with stale fields","Backend accepts partial update","Automate"
"DOC-005","Documents","Delete document","Delete removes from global and residence caches","Manual + Integration","P0","iOS, Android, Web, Desktop","Document exists in caches","Delete document","Document removed everywhere","Delete while detail screen open","DataManager removeDocument updates both caches","Automate"
"DOC-006","Documents","Upload image","Upload document image from camera/gallery","Manual + Integration","P0","iOS, Android","Permissions granted","Add image to document","Thumbnail and full image accessible","Upload timeout","Upload endpoint returns image metadata","Automate partially"
"DOC-007","Documents","Delete image","Delete specific document image updates detail immediately","Manual + Integration","P1","iOS, Android, Web, Desktop","Document with multiple images","Delete one image","Remaining images preserved","Deleting last image","Image delete endpoint idempotency","Automate"
"DOC-008","Documents","Download","Download/open document file via URL","Manual","P1","iOS, Android, Web, Desktop","Document has downloadable URL","Tap download/open","File retrieved and usable","Expired signed URL","Download API wraps binary result","Automate partially"
"DOC-009","Documents","Validation","Claim email optional but must be valid if provided","Manual + UI","P2","iOS","Document form open","Enter invalid claim email","Validation error shown","Internationalized domains","Email regex defines valid format","Automate"
"DOC-010","Documents","Media viewer","Image viewer navigation, zoom, swipe, close behavior","Manual","P2","iOS, Android","Document with multiple images","Open viewer and interact","No crashes; correct index and gestures","Very large images","Viewer supports list index initialization","Manual"
"CON-001","Contractors","List","Load contractors with empty and populated states","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Open contractors tab","List/empty state correct","Large list pagination if any","API supports optional filters","Automate"
"CON-002","Contractors","Create","Create contractor minimal required fields","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Create contractor with name","Contractor appears in list/detail","Special characters in names","Name is required","Automate"
"CON-003","Contractors","Create optional data","Persist optional company/contact/address/specialties","Manual + Integration","P1","iOS, Android, Web, Desktop","Contractor form open","Fill optional fields and save","All values persist accurately","Invalid website URL format","Optional fields may be null","Automate"
"CON-004","Contractors","Email validation","Optional email must be valid if supplied","Manual + UI","P1","iOS, Android, Web, Desktop","Contractor form open","Enter invalid email","Validation error blocks save","Uppercase email + spaces","Validation trims and regex-checks","Automate"
"CON-005","Contractors","Edit","Edit contractor and verify list/detail sync","Manual + E2E UI","P1","iOS, Android, Web, Desktop","Existing contractor","Update fields and save","Updated across views","Concurrent remote update","DataManager updateContractor handles summary mapping","Automate"
"CON-006","Contractors","Delete","Delete contractor removes from caches and residence associations","Manual + Integration","P0","iOS, Android, Web, Desktop","Existing contractor","Delete contractor","Removed from all views","Deleting favorite contractor","Association cleanup server-side","Automate"
"CON-007","Contractors","Favorite toggle","Toggle favorite updates UI and persistence","Manual + E2E UI","P1","iOS, Android, Web, Desktop","Existing contractor","Toggle favorite twice","State toggles correctly and persists refresh","Rapid repeated taps","Endpoint supports idempotent toggles","Automate"
"CON-008","Contractors","By residence filter","Load contractors scoped to residence","Manual + Integration","P1","iOS, Android, Web, Desktop","Multiple residences and linked contractors","Open residence contractor section","Only related contractors shown","Contractor with null residence","Filtering done server-side","Automate"
"CON-009","Contractors","Share export","Share contractor as .casera file","Manual","P1","Android","Contractor exists","Tap share contractor","Share sheet opens with valid file payload","Name containing '/' and long length","Filename sanitization applied","Manual"
"CON-010","Contractors","Import .casera","Import contractor from valid file","Manual + Integration","P0","Android","Logged in, valid contractor file","Open file/import confirm","Contractor created and success dialog shown","Unknown specialty names in file","Specialties mapped by name to known IDs","Automate partially"
"CON-011","Contractors","Import invalid file","Invalid extension/JSON/auth state handled safely","Manual","P0","Android","Invalid file or logged out","Attempt import","Clear error shown; no partial creation","Huge malformed JSON","Import parser errors are surfaced","Manual"
"NOTIF-001","Notifications","Permission prompt","Notification permission request outcomes handled","Manual","P0","iOS, Android","Fresh install","Respond Allow and Deny in separate runs","App continues gracefully; state reflects permission","User changes setting later","Permission checked on foreground","Manual"
"NOTIF-002","Notifications","Device registration","Register device token after login only","Manual + Integration","P0","iOS, Android","Have APNs/FCM token","Login with token available","registerDevice called once and succeeds","Token arrives before auth","Auth gating prevents unauthenticated registration","Automate"
"NOTIF-003","Notifications","Token refresh","New push token triggers backend re-registration","Manual + Integration","P1","iOS, Android","Previously registered token","Simulate token rotation","Backend receives updated registration id","No token change should skip call","Last registered token cache used","Automate"
"NOTIF-004","Notifications","Foreground notification","Foreground notifications display banner/sound and update read state","Manual","P1","iOS, Android","Permission granted, send test push","Receive push while app active","Banner shown; notification handled","Malformed payload missing type","Foreground presentation explicitly enabled","Manual"
"NOTIF-005","Notifications","Notification tap navigation","Tap task push opens app and routes to tasks context","Manual + E2E","P0","iOS, Android","Task-linked push sent","Tap push from background/terminated","App opens on tasks flow for target task","Task no longer exists","Task id may be string or int","Automate partially"
"NOTIF-006","Notifications","Action buttons premium","Premium users see and can execute task action buttons","Manual + Integration","P0","iOS, Android","Premium subscription active","Receive actionable task notification, tap action","Action API executes and UI refreshes","Action timeout/network loss","Actions gated by premium/limitationsEnabled","Manual"
"NOTIF-007","Notifications","Action buttons free-tier gating","Free users with limitations enabled are routed home/not allowed actions","Manual","P0","iOS, Android","Free user limitationsEnabled=true","Tap actionable notification","No privileged task action executed","Subscription cache stale nil","Nil subscription defaults allow on iOS currently","Manual"
"NOTIF-008","Notifications","Preferences","Load and update notification preference toggles","Manual + Integration","P1","iOS, Android, Web, Desktop","Logged in","Open notification preferences, toggle settings, save","Preferences persist and affect server payloads","Partial update failures","Preferences API supports patch/update","Automate"
"NOTIF-009","Notifications","History/read state","Notification history list and mark-read operations","Manual + Integration","P2","iOS, Android, Web, Desktop","Notifications exist","Open history, mark one and mark all","Unread counts decrement correctly","Race with incoming push","Unread count endpoint consistent","Automate"
"SUB-001","Subscription","Status load","Subscription status loads at app launch/foreground","Manual + Integration","P0","iOS, Android, Web, Desktop","Logged in","Launch then background/foreground app","Status cache updates and UI gating accurate","Backend temporarily unavailable","Status refresh should be non-fatal","Automate"
"SUB-002","Subscription","Upgrade screen products","Load purchasable plans and pricing","Manual","P0","iOS, Android","Store config present","Open upgrade screen","Monthly/annual products displayed","Store connectivity issues","Product IDs configured as expected","Manual + mocked automation"
"SUB-003","Subscription","Purchase monthly","Complete monthly purchase and backend verification","Manual + Integration","P0","iOS, Android","Sandbox account, product available","Buy monthly plan","Entitlement granted, subscription status becomes pro","Pending transactions","Verification endpoint must return success","Manual"
"SUB-004","Subscription","Purchase annual","Complete annual purchase and backend verification","Manual + Integration","P0","iOS, Android","Sandbox account","Buy annual plan","Entitlement granted and reflected in app","Upgrade/downgrade from existing plan","Latest transaction determines tier","Manual"
"SUB-005","Subscription","Restore purchases","Restore on clean install/device migration","Manual + Integration","P0","iOS, Android","Existing prior subscription","Tap restore","Entitlements restored and backend synced","No previous purchases","Restore should not duplicate grants","Manual"
"SUB-006","Subscription","Purchase cancellation","User-cancelled purchase does not show fatal error","Manual","P1","iOS, Android","Open paywall","Start then cancel purchase","No entitlement changes; UX remains stable","Repeated cancel attempts","User cancel considered non-error","Manual"
"SUB-007","Subscription","Backend verification failure","Store purchase succeeds but backend verify fails","Manual","P0","iOS, Android","Force backend verify failure","Complete purchase","User sees recoverable state and can retry/restore","Receipt parsing mismatch","App should avoid false pro unlock","Manual"
"SUB-008","Subscription","Feature gating","Pro-only features hidden/disabled for limited users","Manual + E2E","P0","iOS, Android, Web, Desktop","Test free and pro accounts","Traverse gated features (actions, limits, upgrades)","Gating consistent across surfaces","Cache stale after plan change","Gating uses subscription status + limitationsEnabled","Automate"
"WID-001","Widgets","Small widget rendering","Small widget shows counts and opens app","Manual","P1","Android","Widget added, logged in","Place small widget and tap","Correct counts; tap opens app","No data cached yet","Widget reads from shared preferences state","Manual"
"WID-002","Widgets","Medium widget list","Medium widget shows top tasks and overdue badge","Manual","P1","Android","Tasks exist","Place medium widget","Task rows and overdue badge correct","Malformed tasks_json","JSON parse fallback to empty list","Manual"
"WID-003","Widgets","Large widget interactions","Large widget actions execute for pro users","Manual + Integration","P0","Android","Pro account, widget configured","Tap row and action controls","Opens task or executes action as expected","Free user should not see/execute pro actions","Widget passes task_id in intent","Manual"
"WID-004","Widgets","Widget refresh","Widgets refresh after task state changes","Manual","P1","Android","Widget present","Complete/cancel task in app","Widget counts/list update within expected interval","Background restrictions","Widget update manager triggers refresh","Manual"
"SHR-001","Sharing/Import","File association",".casera files open app import flow","Manual","P1","Android","Have .casera file","Open file from files app/share sheet","Import confirmation dialog shown","Multiple apps can open same MIME","Intent filter handles application/json with extension","Manual"
"SHR-002","Sharing/Import","Security","Import rejects when unauthenticated","Manual","P0","Android","Logged out, .casera file ready","Attempt import","Error shown, no data mutation","Stale token in storage","Auth check occurs before API call","Manual"
"SHR-003","Sharing/Import","Corrupt payload","Corrupt .casera payload fails safely without crash","Manual","P0","Android","Malformed JSON file","Attempt import","Graceful error dialog","Very large payload","Parser exceptions are caught","Manual"
"DATA-001","Data layer","Lookups init","Seeded lookup data loads once and marks initialized","Manual + Integration","P0","iOS, Android, Web, Desktop","Fresh login","Observe first data bootstrap","Lookups available for forms/templates","Slow network during bootstrap","initializeLookups has concurrency guard","Automate"
"DATA-002","Data layer","ETag refresh","Lookup refresh uses ETag and handles 304 not modified","Manual + Integration","P1","iOS, Android, Web, Desktop","Lookups already loaded + ETag","Foreground app or force refresh","No unnecessary data churn on 304","ETag lost between sessions","ETag persisted in storage","Automate"
"DATA-003","Data layer","Legacy fallback","If seeded-data endpoint fails, fallback static data path works","Manual + Integration","P1","iOS, Android, Web, Desktop","Mock seeded endpoint failure","Initialize lookups","Core lookups still available","Templates missing in fallback","Fallback endpoint still reachable","Automate"
"DATA-004","Data layer","Cache timeout","One-hour cache timeout triggers fresh fetch after expiry","Manual + Integration","P1","iOS, Android, Web, Desktop","Cached data older/newer than timeout","Request data with forceRefresh=false","Valid cache reused; stale cache refetched","Clock skew/device time changes","Timeout constant is 3600000 ms","Automate"
"DATA-005","Data layer","Cache invalidation on logout","Logout clears user data/cache/ETag but retains theme","Manual + Integration","P0","iOS, Android, Web, Desktop","Logged in with populated data","Logout then inspect next launch","No user data remains; theme preference retained","Persistence clear implementation drift","Theme stored separately from persistenceManager.clear","Automate"
"DATA-006","Data layer","Disk persistence","Current user and lookups reload correctly after app restart","Manual + Integration","P1","iOS, Android, Web, Desktop","Logged in and data loaded","Kill and relaunch app","State restored without full refetch where valid","Partial/corrupt persisted JSON","Deserializer ignoreUnknownKeys is enabled","Automate"
"DATA-007","Data layer","Map/list consistency","Lookup map IDs and list values remain consistent after updates","Unit + Integration","P2","iOS, Android, Web, Desktop","Lookup update operation","Compare list and map representations","No missing or mismatched IDs","Duplicate IDs from backend","Maps are built via associateBy(id)","Automate"
"OFF-001","Resilience","Offline launch","Offline launch with cached token/data behaves gracefully","Manual","P0","iOS, Android, Web, Desktop","Previously logged in with cached data","Launch with network off","No crash; clear messaging; cached UI where possible","Token validation cannot reach server","Current behavior may clear session on fetch failure","Manual"
"OFF-002","Resilience","Offline action handling","Create/update actions fail with retriable errors when offline","Manual","P0","iOS, Android, Web, Desktop","Network disabled","Attempt create/edit/delete flows","Errors shown; no phantom local success","Intermittent network flaps","No offline queue currently assumed","Manual"
"OFF-003","Resilience","Retry behavior","Retry from error dialogs succeeds without stale UI state","Manual + E2E","P1","iOS, Android, Web, Desktop","Force transient API failure","Tap retry then restore network","Action succeeds and loading/error states reset","Double-tap retry race","ApiResult state machine handles Idle/Loading/Error","Automate"
"OFF-004","Resilience","Idempotency UX","Double submit protection for create flows","Manual + UI","P1","iOS, Android, Web, Desktop","Open any create form","Rapid tap save","Single record created","Very slow API response","Buttons disabled during loading","Automate"
"SEC-001","Security","Auth boundaries","Protected endpoints reject without token and UI handles 401","Manual + Integration","P0","iOS, Android, Web, Desktop","No token","Attempt protected operations","Redirect/login prompt or clear error","Token injected but expired","APILayer checks token before API in many calls","Automate"
"SEC-002","Security","Session cleanup","Sensitive data not accessible after logout and app restart","Manual","P0","iOS, Android, Web, Desktop","Logged in then logout","Force close and relaunch","No protected screens/data accessible","Widget still showing stale data","Widget caches should be cleared on logout (iOS path)","Manual"
"SEC-003","Security","Import validation","Imported files cannot execute code or break parser boundaries","Manual","P1","Android","Craft malicious JSON payload","Import payload","App rejects safely, no crash","Oversized strings, deep nesting","Deserializer should throw and be caught","Manual"
"SEC-004","Security","PII exposure","Logs and analytics avoid leaking sensitive credential values","Manual + Code audit","P1","iOS, Android, Web, Desktop","Enable debug logging","Run auth/payment flows","No passwords/tokens in logs/events","Third-party SDK auto-capture risk","PostHog config reviewed","Manual"
"PERF-001","Performance","Cold start","Startup time within target for logged-out and logged-in states","Manual + Perf","P1","iOS, Android","Profile build with instrumentation","Measure cold launch","Meets agreed startup SLA","Slow network path for verified user","Auth check performs network call","Automate perf"
"PERF-002","Performance","Large data rendering","Task/document/contractor lists remain responsive with large datasets","Manual + Perf","P1","iOS, Android, Web, Desktop","Seed large dataset","Scroll and interact lists","No jank/crash; acceptable memory","Thousands of items and images","Virtualized list behavior depends on platform","Manual + benchmarks"
"PERF-003","Performance","Image handling","Large image capture/upload/compression memory stability","Manual + Perf","P0","iOS, Android","Use high-resolution photos","Attach multiple images","No OOM/crash; upload completes or fails gracefully","Low-memory device","ImageCompressor platform implementations are active","Manual"
"PERF-004","Performance","Background operations","Foreground/resume refresh does not block UI thread","Manual + Perf","P2","iOS, Android","App with valid session","Background then foreground repeatedly","UI remains interactive during refresh","Concurrent refresh and navigation","Lookups refresh runs async","Manual"
"A11Y-001","Accessibility","Basic semantics","All primary controls have accessible labels/identifiers","Manual","P0","iOS, Android, Web, Desktop","Screen reader on","Traverse major flows","Controls are announced clearly","Custom components lacking labels","Accessibility identifiers partly defined","Manual + lint"
"A11Y-002","Accessibility","Dynamic type","Text scales correctly without clipping in key screens","Manual","P1","iOS, Android","Large accessibility font settings","Open forms/lists/dialogs","Layout remains usable","Long localized strings","Design system supports flexible layout","Manual"
"A11Y-003","Accessibility","Keyboard navigation","Tab/focus order valid on web/desktop forms","Manual","P1","Web, Desktop","Hardware keyboard","Navigate forms using keyboard only","Logical focus traversal and visible focus states","Modal dialogs focus trap","Compose/web focus handling may differ","Manual"
"A11Y-004","Accessibility","Color contrast","Theme variants meet minimum contrast requirements","Manual + Tooling","P1","iOS, Android, Web, Desktop","Cycle themes","Inspect text/icon contrast","WCAG contrast thresholds met","Error/success states on tinted backgrounds","Multiple custom themes supported","Manual + automated audit"
"I18N-001","Localization","String coverage","No missing keys/placeholders across supported locales","Manual + Static check","P1","iOS, Android, Web, Desktop","Run app in each locale","Traverse major screens","No raw keys, no placeholder mismatches","Pluralization and gender strings","Locales include es/fr/de/it/ja/ko/nl/pt/zh etc.","Automate (lint + screenshot)"
"I18N-002","Localization","Layout expansion","Long translations do not break onboarding/forms/buttons","Manual","P1","iOS, Android, Web, Desktop","Switch to longest-string locale","Review high-density screens","No clipping/overlap","RTL future locale support","Current locales may be LTR only","Manual"
"THEME-001","Theming","Theme persistence","Theme choice persists across app restarts","Manual + Integration","P1","iOS, Android, Web, Desktop","Logged in or logged out","Change theme then relaunch","Selected theme reapplied","Theme ID missing/corrupt in storage","Theme stored separately from auth data","Automate"
"THEME-002","Theming","Theme switch live update","Changing theme updates active screen without broken states","Manual + UI","P2","iOS, Android, Web, Desktop","Open app on any tab","Change theme in profile/settings","Immediate UI recolor with legible components","Transition while modal open","Theme manager publishes updates","Manual"
"NAV-001","Navigation","Bottom tabs","Residences/Tasks/Contractors/Documents tabs navigate and preserve expected state","Manual + E2E UI","P0","iOS, Android","Logged in","Switch tabs repeatedly","Correct screens shown; no stuck navigation","Push navigation then tab switch back","Nested nav stacks differ per platform","Automate"
"NAV-002","Navigation","Back stack safety","Back from details/forms returns to correct parent","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Navigate into detail/edit screens","Use back gestures/buttons","Parent state intact and refreshed as expected","Direct deep-link entry without parent","Saved-state refresh flags used in KMP nav","Automate"
"NAV-003","Navigation","Duplicate routes","Avoid duplicate screen instances from repeated tap/navigation actions","Manual","P2","iOS, Android, Web, Desktop","Rapidly tap nav actions","Observe back stack and UI","No duplicate stacking or loops","Double tap race conditions","NavHost popUpTo rules applied","Manual"
"ANL-001","Analytics","Auth events","Login/register/logout/verify events fire once with correct properties","Manual + Integration","P2","iOS, Android","Analytics enabled in test env","Perform auth flows","Expected events emitted once","Retries causing duplicate events","Event taxonomy defined in analytics layer","Automate with mocked sink"
"ANL-002","Analytics","Core feature events","Residence/task/document/contractor create-edit-delete events tracked","Manual + Integration","P2","iOS, Android","Analytics test workspace","Perform CRUD actions","Events mapped to correct feature","Failed actions should not emit success","PostHog wrappers used consistently","Automate"
"ANL-003","Analytics","Subscription events","Upgrade prompt open, purchase, restore, verification outcomes tracked","Manual + Integration","P2","iOS, Android","Store sandbox + analytics","Run subscription flows","Lifecycle events present and correctly attributed","Purchase canceled path","No sensitive receipt data in events","Manual"
"QA-001","Cross-platform parity","Feature parity","Core flows behave equivalently between KMP UI and iOS native UI","Manual regression","P0","iOS, Android, Web, Desktop","Same seeded account","Run same scenarios on each platform","Equivalent outcomes and data integrity","Known UX differences documented","iOS native app is source for iOS UX","Manual"
"QA-002","Cross-platform parity","API contract consistency","All clients handle new/unknown JSON fields gracefully","Integration","P1","iOS, Android, Web, Desktop","Backend adds extra fields","Run major endpoints","No crash; fields ignored where unknown","Type changes breaking parsing","Kotlin serializers set ignoreUnknownKeys","Automate"
"QA-003","Release quality","Smoke suite","Minimal release gate across auth, residence, task, document, contractor, notification, subscription","Manual + Automated","P0","iOS, Android","Release candidate build","Run smoke checklist","No blockers before release","Environment instability","Smoke should run against stable test backend","Automate + manual signoff"
"QA-004","Release quality","Data migration","Upgrade app version preserves critical local state safely","Manual","P1","iOS, Android, Web, Desktop","Install old build with data then upgrade","Launch and use app","No corruption; expected resets only","Schema/key changes in persistence","Persistence keys remain compatible","Manual"
1 Test_ID Domain Feature Scenario Test_Method Priority Platforms Preconditions Steps Expected_Result Edge_Cases Assumptions Automation_Recommendation
2 AUTH-001 Authentication App start routing First launch routes to onboarding when hasCompletedOnboarding=false Manual + E2E UI P0 iOS, Android, Web, Desktop Fresh install, no token Launch app Onboarding welcome is shown, not login/main tabs Corrupted local onboarding flag Onboarding state is persisted locally Automate (UI smoke)
3 AUTH-002 Authentication App start routing Returning user with onboarding complete and no token routes to login Manual + E2E UI P0 iOS, Android, Web, Desktop hasCompletedOnboarding=true, token missing Launch app Login screen shown Stale cached user object present Token is source of truth Automate
4 AUTH-003 Authentication App start routing Authenticated + verified user routes to main tabs Manual + E2E UI P0 iOS, Android, Web, Desktop Valid token, verified user Launch app Main tab shell displayed Cached token exists but API fails Current-user fetch determines validity Automate
5 AUTH-004 Authentication App start routing Authenticated but unverified user routes to verify email Manual + E2E UI P0 iOS, Android, Web, Desktop Valid token, verified=false Launch app Verify email screen shown User gets verified between launches Verification status fetched from backend Automate
6 AUTH-005 Authentication Token invalidation Invalid token at startup clears session and returns to login Manual + Integration P0 iOS, Android, Web, Desktop Expired/invalid token stored Launch app Data cleared and login shown Backend 500 vs 401 behavior 401/failed current-user means logout Automate
7 AUTH-006 Authentication Login Valid username/password login success Manual + E2E UI P0 iOS, Android, Web, Desktop Existing verified account Submit login form Token persisted, lookups initialized, main shown Slow network during login Login API returns token+user Automate
8 AUTH-007 Authentication Login Invalid credentials shows actionable error Manual + E2E UI P0 iOS, Android, Web, Desktop No session Submit wrong password Error shown, user remains on login Rate-limit or lockout responses Error parser maps backend errors Automate
9 AUTH-008 Authentication Login validation Empty username/password blocked client-side Manual + UI P1 iOS, Android, Web, Desktop No session Tap login with empty fields Validation errors shown, no API call Whitespace-only input Client validation active Automate
10 AUTH-009 Authentication Registration Create account success then verify-email step Manual + E2E UI P0 iOS, Android, Web, Desktop Unique email/username Submit valid registration Session established and verify-email screen appears Existing email conflict Register API auto-authenticates Automate
11 AUTH-010 Authentication Registration validation Invalid email/password formats rejected Manual + UI P1 iOS, Android, Web, Desktop No session Try invalid email, short password, weak password User-friendly validation errors Unicode emails, long usernames Validation rules are enforced consistently Automate
12 AUTH-011 Authentication Email verification Valid 6-digit code verifies account Manual + E2E UI P0 iOS, Android, Web, Desktop Logged-in unverified user Enter 6-digit numeric code Account marked verified and app routes forward Code already used Code must be exactly 6 digits Automate
13 AUTH-012 Authentication Email verification Non-numeric/short/long code blocked Manual + UI P1 iOS, Android, Web, Desktop On verify-email screen Enter invalid codes Verify action disabled or error shown Pasted with spaces Code input sanitizes to digits Automate
14 AUTH-013 Authentication Logout Logout clears token, user data, lookups, and returns to login Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Tap logout Login shown; protected API calls fail without token Logout API fails network-side Client clears state even if API call fails Automate
15 AUTH-014 Authentication Forgot password Request reset by email success path Manual + E2E UI P0 iOS, Android, Web, Desktop Known account email Submit forgot-password email Success message and next step available Unknown email behavior privacy-safe Backend may still return generic success Automate
16 AUTH-015 Authentication Reset code verification Verify reset code success path Manual + E2E UI P0 iOS, Android, Web, Desktop Reset email submitted Enter correct code Reset-token available for password reset Expired code Code verification endpoint returns token Automate
17 AUTH-016 Authentication Password reset Reset password success with matching confirmation Manual + E2E UI P0 iOS, Android, Web, Desktop Valid reset token Enter new password + confirm Password changed; user can log in (or auto-login flow) Token expires mid-flow Reset endpoint ignores confirm field Automate
18 AUTH-017 Authentication Password reset Mismatched password confirmation blocked Manual + UI P1 iOS, Android, Web, Desktop Reset password screen Enter mismatch Inline error; no reset request Trailing spaces Client validates before submit Automate
19 AUTH-018 Authentication Deep link reset Password-reset deep link opens flow with token prefilled Manual + E2E UI P0 iOS, Android Installed app with deep-link support Open reset deep link Forgot/reset flow opens and token is consumed Malformed token in URL Deep link token can be cleared on back Automate
20 AUTH-019 Authentication SSO Apple Apple Sign-In success creates or signs in account Manual + Integration P1 iOS Apple-capable test device/simulator Complete Apple sign-in Session established; verification state handled User hides email, first-login only email scope Apple credential mapped to backend request Automate partially (mock)
21 AUTH-020 Authentication SSO Google Google Sign-In success path Manual + Integration P1 Android, Web, KMP UI Google sign-in configured Complete Google sign-in Session established with backend token Revoked Google token Backend validates ID token Automate partially
22 ONB-001 Onboarding Intent split Start Fresh path goes through value props and name residence Manual + E2E UI P0 iOS, Android (KMP) Fresh install Choose Start Fresh and continue Step order matches intended flow Back navigation at each step Flow differs by intent Automate
23 ONB-002 Onboarding Intent split Join Existing path skips value/name steps and goes to account creation Manual + E2E UI P0 iOS, Android (KMP) Fresh install Choose Join Existing Expected condensed step order User switches intent mid-flow Intent persisted during onboarding Automate
24 ONB-003 Onboarding Navigation Back button transitions and step history correctness Manual + UI P1 iOS, Android (KMP) In onboarding multi-step flow Navigate forward then back Returns to correct previous step Back from verify-email triggers logout on iOS Back behavior is product-defined Automate
25 ONB-004 Onboarding Skip behavior Skippable screens skip to next valid state Manual + UI P1 iOS, Android (KMP) On skippable step Tap Skip Progress advances without corrupting state Skip on terminal upsell step completes onboarding Skip availability is step-dependent Automate
26 ONB-005 Onboarding Residence bootstrap Start Fresh creates residence automatically after verification Manual + Integration P0 iOS, Android (KMP) Onboarding start-fresh with residence name Verify email and continue Residence created or graceful fallback if creation fails Blank residence name bypasses creation Creation failure should not hard-block onboarding Automate
27 ONB-006 Onboarding Join residence Join-existing flow joins via share code Manual + E2E UI P0 iOS, Android (KMP) Valid join code Submit code in onboarding User added to shared residence Expired/invalid/reused code Join code endpoint enforces ownership rules Automate
28 ONB-007 Onboarding First task First-task onboarding step can create selected tasks Manual + Integration P1 iOS, Android (KMP) On first-task step Select templates and continue Tasks created; flow proceeds Partial task creation failures At least one success considered success in KMP VM Automate
29 ONB-008 Onboarding Completion persistence Completing onboarding persists flag and bypasses onboarding next launch Manual + E2E UI P0 iOS, Android, Web, Desktop Completed onboarding once Restart app Onboarding is skipped App data clear resets flag Onboarding flag stored locally Automate
30 RES-001 Residences List Residences list loads with empty and non-empty states Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Open residences tab Correct list/empty UI shown Slow API and stale cache List can come from cache or network Automate
31 RES-002 Residences Create Create residence with required fields only Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Fill minimum fields and save Residence appears in list/detail Duplicate name allowed/not allowed behavior Name required; other fields optional Automate
32 RES-003 Residences Create validation Prevent submit when required name missing Manual + UI P1 iOS, Android, Web, Desktop Open add residence form Submit blank name Validation error, no API call Whitespace-only name Required validation trims input Automate
33 RES-004 Residences Create optional fields All optional numeric/text/address fields persist correctly Manual + Integration P1 iOS, Android, Web, Desktop Open add residence form Fill all fields and save Values round-trip correctly in detail/edit Decimals for bathrooms/lot size Type conversion preserves precision Automate
34 RES-005 Residences Edit Edit residence updates list and detail views Manual + E2E UI P0 iOS, Android, Web, Desktop Existing residence Modify fields and save Updated values shown immediately Concurrent edit from another user DataManager updates local caches Automate
35 RES-006 Residences Delete Delete residence removes related task/document cached subsets Manual + Integration P0 iOS, Android, Web, Desktop Residence with tasks/docs exists Delete residence Residence gone; related cached sections removed Delete primary/only residence Server cascade semantics documented Automate
36 RES-007 Residences Primary residence Set/retain primary residence behavior Manual P2 iOS, Android, Web, Desktop Multiple residences Mark one as primary and reload Only intended residence is primary Two rapid primary updates Backend enforces uniqueness Automate partially
37 RES-008 Residences Summary Residence summary counts derive from kanban columns correctly Manual + Integration P1 iOS, Android, Web, Desktop Residence with mixed task statuses Open summary cards Counts match task column truth No tasks state Summary can be client-computed Automate
38 RES-009 Residences Join by code Join residence from manual share code entry Manual + E2E UI P0 iOS, Android, Web, Desktop Valid share code from another account Enter code in join flow Membership granted and residence appears Code expired or already member Join endpoint returns reasoned errors Automate
39 RES-010 Residences Generate share code Generate/refresh residence share code Manual + Integration P1 iOS, Android, Web, Desktop Owner access to residence Generate code New valid code returned/visible Repeated generation invalidates old codes Access limited by role Automate
40 RES-011 Residences Share package export Create residence .casera package and open share sheet Manual P1 Android Residence exists, logged in Tap share residence Share sheet opens with file attachment Filename sanitization with special chars Backend generates package with shareCode Automate partially
41 RES-012 Residences Share package import Import .casera residence file joins residence Manual + Integration P0 Android Valid .casera file received Open file via app/import handler and confirm Join succeeds and success dialog shown Invalid JSON/wrong extension/no auth Import requires auth and parse success Automate partially
42 RES-013 Residences Task report Generate residence tasks report with/without email Manual + Integration P2 iOS, Android, Web, Desktop Residence exists Trigger generate report Report creation success feedback Invalid email format optional field Backend handles async report generation Automate
43 RES-014 Residences Manage users view Residence users list loads with owner/member roles Manual + E2E UI P1 iOS, Android (KMP) Residence with multiple users Open manage users Accurate users and role indicators displayed Owner missing from response Role data trusted from API Automate
44 RES-015 Residences Remove user Owner removes a member successfully Manual + Integration P0 iOS, Android (KMP) Owner logged in, target member exists Remove member Member removed and state refreshes Attempt remove self/owner API enforces permission rules Automate
45 TASK-001 Tasks All tasks load Kanban columns load for all residences Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in with at least one residence Open tasks tab Columns and counts render correctly Zero tasks across all columns Columns include overdue/in-progress/due-soon/upcoming/completed/cancelled Automate
46 TASK-002 Tasks Residence filtering Tasks by residence uses filtered allTasks cache correctly Manual + Integration P1 iOS, Android, Web, Desktop Multiple residences with tasks Open residence detail tasks Only selected residence tasks shown Residence cache stale while global cache fresh Client-side filtering path exists Automate
47 TASK-003 Tasks Create task Create minimal valid task Manual + E2E UI P0 iOS, Android, Web, Desktop Residence exists, lookups loaded Submit task with required fields Task appears in expected column Missing lookups due to failed seed load Category/frequency/priority are required Automate
48 TASK-004 Tasks Create from template Create task from template browser Manual + E2E UI P1 iOS, Android, Web, Desktop Templates available Open templates, select one, save Task prefilled and created Template with long description/tags Template data from seeded lookups Automate
49 TASK-005 Tasks Template search Search templates requires >=2 chars and limits results Manual + Unit P2 iOS, Android, Web, Desktop Templates loaded Search with 1 char then 2+ chars 1 char returns empty, 2+ filtered max 10 Case-insensitive tag match Search is local in DataManager Automate
50 TASK-006 Tasks Edit task Edit task fields and persist updates Manual + E2E UI P0 iOS, Android, Web, Desktop Existing task Change title/category/frequency/priority/due/cost Task updates and remains consistent in caches Invalid cost string conversion Edit route passes serialized fields Automate
51 TASK-007 Tasks Mark in progress Transition task to in-progress column Manual + E2E UI P0 iOS, Android, Web, Desktop Existing non-in-progress task Tap mark in progress Task moves to in-progress column Already in progress idempotency UpdateTask uses kanbanColumn target Automate
52 TASK-008 Tasks Clear in progress Clear in-progress state returns task to scheduled column Manual + Integration P1 iOS, Android, Web, Desktop Task currently in progress Clear in-progress Task leaves in-progress with correct new column Due date past while clearing Backend decides target column Automate
53 TASK-009 Tasks Cancel task Cancel action moves task to cancelled state Manual + E2E UI P0 iOS, Android, Web, Desktop Active task exists Cancel task Task appears in cancelled column/state Cancel already-cancelled task Endpoint idempotency defined Automate
54 TASK-010 Tasks Uncancel task Restore cancelled task to active lifecycle Manual + E2E UI P0 iOS, Android, Web, Desktop Cancelled task exists Uncancel task Task restored to appropriate column Uncancel archived task State transitions validated by API Automate
55 TASK-011 Tasks Archive/unarchive Archive hides task from active flow; unarchive restores Manual + Integration P1 iOS, Android, Web, Desktop Task exists Archive then unarchive Visibility toggles correctly Archived + cancelled combined states Archive APIs available and cached updates propagate Automate
56 TASK-012 Tasks Delete semantics Task removal updates all cached columns and summaries Manual + Integration P1 iOS, Android, Web, Desktop Task exists in cached data Delete or server-remove task then refresh Task absent in all views and counts updated Task present in multiple cached views DataManager removeTask updates all maps Automate
57 TASK-013 Tasks Due date handling Past/now/future due dates map to correct columns Manual + Integration P1 iOS, Android, Web, Desktop Tasks with boundary due dates Load tasks around timezone boundaries Kanban placement matches backend logic DST transitions Backend provides canonical kanban_column Automate
58 TASK-014 Tasks Cost fields Estimated cost accepts numeric and rejects invalid formats Manual + UI P2 iOS, Android, Web, Desktop Task form open Enter valid/invalid cost strings Valid persisted; invalid blocked or sanitized Locale decimal separators Cost parsed to Double Automate
59 TASK-015 Tasks Task detail navigation Push/deep-link task navigation opens tasks tab and relevant task context Manual + E2E UI P0 iOS, Android App receives task navigation ID Tap notification/open intent Tasks tab selected and task reachable Task deleted before open Main shell handles navigate_to_task contract Automate
60 TASK-016 Tasks Bulk state refresh After any task CRUD/action, summary cards refresh immediately Manual + Integration P1 iOS, Android, Web, Desktop Dashboard visible with summaries Perform task action Summary counts update without hard reload Rapid consecutive actions Summary derived from cached kanban Automate
61 TASK-017 Tasks Concurrency Two users edit same task; conflict resolution UX Manual P2 iOS, Android, Web, Desktop Same task open on two accounts Save conflicting edits Consistent final state and clear error/last-write behavior Out-of-order responses Server conflict strategy documented Manual
62 TCOMP-001 Task completion Complete task basic Complete task with notes/cost/rating Manual + E2E UI P0 iOS, Android, Web, Desktop Active task exists Open complete flow and submit Completion created and task column updates Null rating vs default value Completion endpoint accepts optional fields Automate
63 TCOMP-002 Task completion Complete with images Attach one or multiple images during completion Manual + Integration P0 iOS, Android Camera/gallery permission granted Submit completion with images Images uploaded and linked to completion Large image compression/failure mid-upload Image compression and multipart upload enabled Automate partially
64 TCOMP-003 Task completion Validation Required completed-by field enforced (iOS form state) Manual + UI P1 iOS Open complete task form Submit blank completed-by Validation error shown Whitespace-only value CompletedBy required by client form Automate
65 TCOMP-004 Task completion Completion history History list loads for task and sorted correctly Manual + Integration P1 iOS, Android, Web, Desktop Task with multiple completions Open completion history Entries ordered and accurate Missing images in older completion records History endpoint returns full list Automate
66 DOC-001 Documents List Load all documents and residence-filtered documents Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in with docs data Open documents tab and residence detail docs Correct sets shown Residence with zero docs List supports optional residence filter Automate
67 DOC-002 Documents Create document Create generic document with required fields Manual + E2E UI P0 iOS, Android, Web, Desktop Residence exists Create document with title/type/residence Document appears in lists Missing residence selection on create Create requires title/type/residence Automate
68 DOC-003 Documents Create warranty fields Create warranty/appliance with provider/dates metadata Manual + Integration P1 iOS, Android, Web, Desktop Document form open Enter warranty-specific fields and save Fields persist and render in detail End date before start date Date validation expectations defined Automate
69 DOC-004 Documents Edit document Edit existing document including type/category/tags Manual + E2E UI P1 iOS, Android, Web, Desktop Document exists Modify and save Detail/list reflect updates Switching types with stale fields Backend accepts partial update Automate
70 DOC-005 Documents Delete document Delete removes from global and residence caches Manual + Integration P0 iOS, Android, Web, Desktop Document exists in caches Delete document Document removed everywhere Delete while detail screen open DataManager removeDocument updates both caches Automate
71 DOC-006 Documents Upload image Upload document image from camera/gallery Manual + Integration P0 iOS, Android Permissions granted Add image to document Thumbnail and full image accessible Upload timeout Upload endpoint returns image metadata Automate partially
72 DOC-007 Documents Delete image Delete specific document image updates detail immediately Manual + Integration P1 iOS, Android, Web, Desktop Document with multiple images Delete one image Remaining images preserved Deleting last image Image delete endpoint idempotency Automate
73 DOC-008 Documents Download Download/open document file via URL Manual P1 iOS, Android, Web, Desktop Document has downloadable URL Tap download/open File retrieved and usable Expired signed URL Download API wraps binary result Automate partially
74 DOC-009 Documents Validation Claim email optional but must be valid if provided Manual + UI P2 iOS Document form open Enter invalid claim email Validation error shown Internationalized domains Email regex defines valid format Automate
75 DOC-010 Documents Media viewer Image viewer navigation, zoom, swipe, close behavior Manual P2 iOS, Android Document with multiple images Open viewer and interact No crashes; correct index and gestures Very large images Viewer supports list index initialization Manual
76 CON-001 Contractors List Load contractors with empty and populated states Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Open contractors tab List/empty state correct Large list pagination if any API supports optional filters Automate
77 CON-002 Contractors Create Create contractor minimal required fields Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Create contractor with name Contractor appears in list/detail Special characters in names Name is required Automate
78 CON-003 Contractors Create optional data Persist optional company/contact/address/specialties Manual + Integration P1 iOS, Android, Web, Desktop Contractor form open Fill optional fields and save All values persist accurately Invalid website URL format Optional fields may be null Automate
79 CON-004 Contractors Email validation Optional email must be valid if supplied Manual + UI P1 iOS, Android, Web, Desktop Contractor form open Enter invalid email Validation error blocks save Uppercase email + spaces Validation trims and regex-checks Automate
80 CON-005 Contractors Edit Edit contractor and verify list/detail sync Manual + E2E UI P1 iOS, Android, Web, Desktop Existing contractor Update fields and save Updated across views Concurrent remote update DataManager updateContractor handles summary mapping Automate
81 CON-006 Contractors Delete Delete contractor removes from caches and residence associations Manual + Integration P0 iOS, Android, Web, Desktop Existing contractor Delete contractor Removed from all views Deleting favorite contractor Association cleanup server-side Automate
82 CON-007 Contractors Favorite toggle Toggle favorite updates UI and persistence Manual + E2E UI P1 iOS, Android, Web, Desktop Existing contractor Toggle favorite twice State toggles correctly and persists refresh Rapid repeated taps Endpoint supports idempotent toggles Automate
83 CON-008 Contractors By residence filter Load contractors scoped to residence Manual + Integration P1 iOS, Android, Web, Desktop Multiple residences and linked contractors Open residence contractor section Only related contractors shown Contractor with null residence Filtering done server-side Automate
84 CON-009 Contractors Share export Share contractor as .casera file Manual P1 Android Contractor exists Tap share contractor Share sheet opens with valid file payload Name containing '/' and long length Filename sanitization applied Manual
85 CON-010 Contractors Import .casera Import contractor from valid file Manual + Integration P0 Android Logged in, valid contractor file Open file/import confirm Contractor created and success dialog shown Unknown specialty names in file Specialties mapped by name to known IDs Automate partially
86 CON-011 Contractors Import invalid file Invalid extension/JSON/auth state handled safely Manual P0 Android Invalid file or logged out Attempt import Clear error shown; no partial creation Huge malformed JSON Import parser errors are surfaced Manual
87 NOTIF-001 Notifications Permission prompt Notification permission request outcomes handled Manual P0 iOS, Android Fresh install Respond Allow and Deny in separate runs App continues gracefully; state reflects permission User changes setting later Permission checked on foreground Manual
88 NOTIF-002 Notifications Device registration Register device token after login only Manual + Integration P0 iOS, Android Have APNs/FCM token Login with token available registerDevice called once and succeeds Token arrives before auth Auth gating prevents unauthenticated registration Automate
89 NOTIF-003 Notifications Token refresh New push token triggers backend re-registration Manual + Integration P1 iOS, Android Previously registered token Simulate token rotation Backend receives updated registration id No token change should skip call Last registered token cache used Automate
90 NOTIF-004 Notifications Foreground notification Foreground notifications display banner/sound and update read state Manual P1 iOS, Android Permission granted, send test push Receive push while app active Banner shown; notification handled Malformed payload missing type Foreground presentation explicitly enabled Manual
91 NOTIF-005 Notifications Notification tap navigation Tap task push opens app and routes to tasks context Manual + E2E P0 iOS, Android Task-linked push sent Tap push from background/terminated App opens on tasks flow for target task Task no longer exists Task id may be string or int Automate partially
92 NOTIF-006 Notifications Action buttons premium Premium users see and can execute task action buttons Manual + Integration P0 iOS, Android Premium subscription active Receive actionable task notification, tap action Action API executes and UI refreshes Action timeout/network loss Actions gated by premium/limitationsEnabled Manual
93 NOTIF-007 Notifications Action buttons free-tier gating Free users with limitations enabled are routed home/not allowed actions Manual P0 iOS, Android Free user limitationsEnabled=true Tap actionable notification No privileged task action executed Subscription cache stale nil Nil subscription defaults allow on iOS currently Manual
94 NOTIF-008 Notifications Preferences Load and update notification preference toggles Manual + Integration P1 iOS, Android, Web, Desktop Logged in Open notification preferences, toggle settings, save Preferences persist and affect server payloads Partial update failures Preferences API supports patch/update Automate
95 NOTIF-009 Notifications History/read state Notification history list and mark-read operations Manual + Integration P2 iOS, Android, Web, Desktop Notifications exist Open history, mark one and mark all Unread counts decrement correctly Race with incoming push Unread count endpoint consistent Automate
96 SUB-001 Subscription Status load Subscription status loads at app launch/foreground Manual + Integration P0 iOS, Android, Web, Desktop Logged in Launch then background/foreground app Status cache updates and UI gating accurate Backend temporarily unavailable Status refresh should be non-fatal Automate
97 SUB-002 Subscription Upgrade screen products Load purchasable plans and pricing Manual P0 iOS, Android Store config present Open upgrade screen Monthly/annual products displayed Store connectivity issues Product IDs configured as expected Manual + mocked automation
98 SUB-003 Subscription Purchase monthly Complete monthly purchase and backend verification Manual + Integration P0 iOS, Android Sandbox account, product available Buy monthly plan Entitlement granted, subscription status becomes pro Pending transactions Verification endpoint must return success Manual
99 SUB-004 Subscription Purchase annual Complete annual purchase and backend verification Manual + Integration P0 iOS, Android Sandbox account Buy annual plan Entitlement granted and reflected in app Upgrade/downgrade from existing plan Latest transaction determines tier Manual
100 SUB-005 Subscription Restore purchases Restore on clean install/device migration Manual + Integration P0 iOS, Android Existing prior subscription Tap restore Entitlements restored and backend synced No previous purchases Restore should not duplicate grants Manual
101 SUB-006 Subscription Purchase cancellation User-cancelled purchase does not show fatal error Manual P1 iOS, Android Open paywall Start then cancel purchase No entitlement changes; UX remains stable Repeated cancel attempts User cancel considered non-error Manual
102 SUB-007 Subscription Backend verification failure Store purchase succeeds but backend verify fails Manual P0 iOS, Android Force backend verify failure Complete purchase User sees recoverable state and can retry/restore Receipt parsing mismatch App should avoid false pro unlock Manual
103 SUB-008 Subscription Feature gating Pro-only features hidden/disabled for limited users Manual + E2E P0 iOS, Android, Web, Desktop Test free and pro accounts Traverse gated features (actions, limits, upgrades) Gating consistent across surfaces Cache stale after plan change Gating uses subscription status + limitationsEnabled Automate
104 WID-001 Widgets Small widget rendering Small widget shows counts and opens app Manual P1 Android Widget added, logged in Place small widget and tap Correct counts; tap opens app No data cached yet Widget reads from shared preferences state Manual
105 WID-002 Widgets Medium widget list Medium widget shows top tasks and overdue badge Manual P1 Android Tasks exist Place medium widget Task rows and overdue badge correct Malformed tasks_json JSON parse fallback to empty list Manual
106 WID-003 Widgets Large widget interactions Large widget actions execute for pro users Manual + Integration P0 Android Pro account, widget configured Tap row and action controls Opens task or executes action as expected Free user should not see/execute pro actions Widget passes task_id in intent Manual
107 WID-004 Widgets Widget refresh Widgets refresh after task state changes Manual P1 Android Widget present Complete/cancel task in app Widget counts/list update within expected interval Background restrictions Widget update manager triggers refresh Manual
108 SHR-001 Sharing/Import File association .casera files open app import flow Manual P1 Android Have .casera file Open file from files app/share sheet Import confirmation dialog shown Multiple apps can open same MIME Intent filter handles application/json with extension Manual
109 SHR-002 Sharing/Import Security Import rejects when unauthenticated Manual P0 Android Logged out, .casera file ready Attempt import Error shown, no data mutation Stale token in storage Auth check occurs before API call Manual
110 SHR-003 Sharing/Import Corrupt payload Corrupt .casera payload fails safely without crash Manual P0 Android Malformed JSON file Attempt import Graceful error dialog Very large payload Parser exceptions are caught Manual
111 DATA-001 Data layer Lookups init Seeded lookup data loads once and marks initialized Manual + Integration P0 iOS, Android, Web, Desktop Fresh login Observe first data bootstrap Lookups available for forms/templates Slow network during bootstrap initializeLookups has concurrency guard Automate
112 DATA-002 Data layer ETag refresh Lookup refresh uses ETag and handles 304 not modified Manual + Integration P1 iOS, Android, Web, Desktop Lookups already loaded + ETag Foreground app or force refresh No unnecessary data churn on 304 ETag lost between sessions ETag persisted in storage Automate
113 DATA-003 Data layer Legacy fallback If seeded-data endpoint fails, fallback static data path works Manual + Integration P1 iOS, Android, Web, Desktop Mock seeded endpoint failure Initialize lookups Core lookups still available Templates missing in fallback Fallback endpoint still reachable Automate
114 DATA-004 Data layer Cache timeout One-hour cache timeout triggers fresh fetch after expiry Manual + Integration P1 iOS, Android, Web, Desktop Cached data older/newer than timeout Request data with forceRefresh=false Valid cache reused; stale cache refetched Clock skew/device time changes Timeout constant is 3600000 ms Automate
115 DATA-005 Data layer Cache invalidation on logout Logout clears user data/cache/ETag but retains theme Manual + Integration P0 iOS, Android, Web, Desktop Logged in with populated data Logout then inspect next launch No user data remains; theme preference retained Persistence clear implementation drift Theme stored separately from persistenceManager.clear Automate
116 DATA-006 Data layer Disk persistence Current user and lookups reload correctly after app restart Manual + Integration P1 iOS, Android, Web, Desktop Logged in and data loaded Kill and relaunch app State restored without full refetch where valid Partial/corrupt persisted JSON Deserializer ignoreUnknownKeys is enabled Automate
117 DATA-007 Data layer Map/list consistency Lookup map IDs and list values remain consistent after updates Unit + Integration P2 iOS, Android, Web, Desktop Lookup update operation Compare list and map representations No missing or mismatched IDs Duplicate IDs from backend Maps are built via associateBy(id) Automate
118 OFF-001 Resilience Offline launch Offline launch with cached token/data behaves gracefully Manual P0 iOS, Android, Web, Desktop Previously logged in with cached data Launch with network off No crash; clear messaging; cached UI where possible Token validation cannot reach server Current behavior may clear session on fetch failure Manual
119 OFF-002 Resilience Offline action handling Create/update actions fail with retriable errors when offline Manual P0 iOS, Android, Web, Desktop Network disabled Attempt create/edit/delete flows Errors shown; no phantom local success Intermittent network flaps No offline queue currently assumed Manual
120 OFF-003 Resilience Retry behavior Retry from error dialogs succeeds without stale UI state Manual + E2E P1 iOS, Android, Web, Desktop Force transient API failure Tap retry then restore network Action succeeds and loading/error states reset Double-tap retry race ApiResult state machine handles Idle/Loading/Error Automate
121 OFF-004 Resilience Idempotency UX Double submit protection for create flows Manual + UI P1 iOS, Android, Web, Desktop Open any create form Rapid tap save Single record created Very slow API response Buttons disabled during loading Automate
122 SEC-001 Security Auth boundaries Protected endpoints reject without token and UI handles 401 Manual + Integration P0 iOS, Android, Web, Desktop No token Attempt protected operations Redirect/login prompt or clear error Token injected but expired APILayer checks token before API in many calls Automate
123 SEC-002 Security Session cleanup Sensitive data not accessible after logout and app restart Manual P0 iOS, Android, Web, Desktop Logged in then logout Force close and relaunch No protected screens/data accessible Widget still showing stale data Widget caches should be cleared on logout (iOS path) Manual
124 SEC-003 Security Import validation Imported files cannot execute code or break parser boundaries Manual P1 Android Craft malicious JSON payload Import payload App rejects safely, no crash Oversized strings, deep nesting Deserializer should throw and be caught Manual
125 SEC-004 Security PII exposure Logs and analytics avoid leaking sensitive credential values Manual + Code audit P1 iOS, Android, Web, Desktop Enable debug logging Run auth/payment flows No passwords/tokens in logs/events Third-party SDK auto-capture risk PostHog config reviewed Manual
126 PERF-001 Performance Cold start Startup time within target for logged-out and logged-in states Manual + Perf P1 iOS, Android Profile build with instrumentation Measure cold launch Meets agreed startup SLA Slow network path for verified user Auth check performs network call Automate perf
127 PERF-002 Performance Large data rendering Task/document/contractor lists remain responsive with large datasets Manual + Perf P1 iOS, Android, Web, Desktop Seed large dataset Scroll and interact lists No jank/crash; acceptable memory Thousands of items and images Virtualized list behavior depends on platform Manual + benchmarks
128 PERF-003 Performance Image handling Large image capture/upload/compression memory stability Manual + Perf P0 iOS, Android Use high-resolution photos Attach multiple images No OOM/crash; upload completes or fails gracefully Low-memory device ImageCompressor platform implementations are active Manual
129 PERF-004 Performance Background operations Foreground/resume refresh does not block UI thread Manual + Perf P2 iOS, Android App with valid session Background then foreground repeatedly UI remains interactive during refresh Concurrent refresh and navigation Lookups refresh runs async Manual
130 A11Y-001 Accessibility Basic semantics All primary controls have accessible labels/identifiers Manual P0 iOS, Android, Web, Desktop Screen reader on Traverse major flows Controls are announced clearly Custom components lacking labels Accessibility identifiers partly defined Manual + lint
131 A11Y-002 Accessibility Dynamic type Text scales correctly without clipping in key screens Manual P1 iOS, Android Large accessibility font settings Open forms/lists/dialogs Layout remains usable Long localized strings Design system supports flexible layout Manual
132 A11Y-003 Accessibility Keyboard navigation Tab/focus order valid on web/desktop forms Manual P1 Web, Desktop Hardware keyboard Navigate forms using keyboard only Logical focus traversal and visible focus states Modal dialogs focus trap Compose/web focus handling may differ Manual
133 A11Y-004 Accessibility Color contrast Theme variants meet minimum contrast requirements Manual + Tooling P1 iOS, Android, Web, Desktop Cycle themes Inspect text/icon contrast WCAG contrast thresholds met Error/success states on tinted backgrounds Multiple custom themes supported Manual + automated audit
134 I18N-001 Localization String coverage No missing keys/placeholders across supported locales Manual + Static check P1 iOS, Android, Web, Desktop Run app in each locale Traverse major screens No raw keys, no placeholder mismatches Pluralization and gender strings Locales include es/fr/de/it/ja/ko/nl/pt/zh etc. Automate (lint + screenshot)
135 I18N-002 Localization Layout expansion Long translations do not break onboarding/forms/buttons Manual P1 iOS, Android, Web, Desktop Switch to longest-string locale Review high-density screens No clipping/overlap RTL future locale support Current locales may be LTR only Manual
136 THEME-001 Theming Theme persistence Theme choice persists across app restarts Manual + Integration P1 iOS, Android, Web, Desktop Logged in or logged out Change theme then relaunch Selected theme reapplied Theme ID missing/corrupt in storage Theme stored separately from auth data Automate
137 THEME-002 Theming Theme switch live update Changing theme updates active screen without broken states Manual + UI P2 iOS, Android, Web, Desktop Open app on any tab Change theme in profile/settings Immediate UI recolor with legible components Transition while modal open Theme manager publishes updates Manual
138 NAV-001 Navigation Bottom tabs Residences/Tasks/Contractors/Documents tabs navigate and preserve expected state Manual + E2E UI P0 iOS, Android Logged in Switch tabs repeatedly Correct screens shown; no stuck navigation Push navigation then tab switch back Nested nav stacks differ per platform Automate
139 NAV-002 Navigation Back stack safety Back from details/forms returns to correct parent Manual + E2E UI P0 iOS, Android, Web, Desktop Navigate into detail/edit screens Use back gestures/buttons Parent state intact and refreshed as expected Direct deep-link entry without parent Saved-state refresh flags used in KMP nav Automate
140 NAV-003 Navigation Duplicate routes Avoid duplicate screen instances from repeated tap/navigation actions Manual P2 iOS, Android, Web, Desktop Rapidly tap nav actions Observe back stack and UI No duplicate stacking or loops Double tap race conditions NavHost popUpTo rules applied Manual
141 ANL-001 Analytics Auth events Login/register/logout/verify events fire once with correct properties Manual + Integration P2 iOS, Android Analytics enabled in test env Perform auth flows Expected events emitted once Retries causing duplicate events Event taxonomy defined in analytics layer Automate with mocked sink
142 ANL-002 Analytics Core feature events Residence/task/document/contractor create-edit-delete events tracked Manual + Integration P2 iOS, Android Analytics test workspace Perform CRUD actions Events mapped to correct feature Failed actions should not emit success PostHog wrappers used consistently Automate
143 ANL-003 Analytics Subscription events Upgrade prompt open, purchase, restore, verification outcomes tracked Manual + Integration P2 iOS, Android Store sandbox + analytics Run subscription flows Lifecycle events present and correctly attributed Purchase canceled path No sensitive receipt data in events Manual
144 QA-001 Cross-platform parity Feature parity Core flows behave equivalently between KMP UI and iOS native UI Manual regression P0 iOS, Android, Web, Desktop Same seeded account Run same scenarios on each platform Equivalent outcomes and data integrity Known UX differences documented iOS native app is source for iOS UX Manual
145 QA-002 Cross-platform parity API contract consistency All clients handle new/unknown JSON fields gracefully Integration P1 iOS, Android, Web, Desktop Backend adds extra fields Run major endpoints No crash; fields ignored where unknown Type changes breaking parsing Kotlin serializers set ignoreUnknownKeys Automate
146 QA-003 Release quality Smoke suite Minimal release gate across auth, residence, task, document, contractor, notification, subscription Manual + Automated P0 iOS, Android Release candidate build Run smoke checklist No blockers before release Environment instability Smoke should run against stable test backend Automate + manual signoff
147 QA-004 Release quality Data migration Upgrade app version preserves critical local state safely Manual P1 iOS, Android, Web, Desktop Install old build with data then upgrade Launch and use app No corruption; expected resets only Schema/key changes in persistence Persistence keys remain compatible Manual

View File

@@ -0,0 +1,147 @@
"Test_ID","Domain","Feature","Scenario","Test_Method","Priority","Platforms","Preconditions","Steps","Expected_Result","Edge_Cases","Assumptions","Automation_Recommendation"
"AUTH-001","Authentication","App start routing","First launch routes to onboarding when hasCompletedOnboarding=false","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Fresh install, no token","Launch app","Onboarding welcome is shown, not login/main tabs","Corrupted local onboarding flag","Onboarding state is persisted locally","Automate (UI smoke)"
"AUTH-002","Authentication","App start routing","Returning user with onboarding complete and no token routes to login","Manual + E2E UI","P0","iOS, Android, Web, Desktop","hasCompletedOnboarding=true, token missing","Launch app","Login screen shown","Stale cached user object present","Token is source of truth","Automate"
"AUTH-003","Authentication","App start routing","Authenticated + verified user routes to main tabs","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Valid token, verified user","Launch app","Main tab shell displayed","Cached token exists but API fails","Current-user fetch determines validity","Automate"
"AUTH-004","Authentication","App start routing","Authenticated but unverified user routes to verify email","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Valid token, verified=false","Launch app","Verify email screen shown","User gets verified between launches","Verification status fetched from backend","Automate"
"AUTH-005","Authentication","Token invalidation","Invalid token at startup clears session and returns to login","Manual + Integration","P0","iOS, Android, Web, Desktop","Expired/invalid token stored","Launch app","Data cleared and login shown","Backend 500 vs 401 behavior","401/failed current-user means logout","Automate"
"AUTH-006","Authentication","Login","Valid username/password login success","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Existing verified account","Submit login form","Token persisted, lookups initialized, main shown","Slow network during login","Login API returns token+user","Automate"
"AUTH-007","Authentication","Login","Invalid credentials shows actionable error","Manual + E2E UI","P0","iOS, Android, Web, Desktop","No session","Submit wrong password","Error shown, user remains on login","Rate-limit or lockout responses","Error parser maps backend errors","Automate"
"AUTH-008","Authentication","Login validation","Empty username/password blocked client-side","Manual + UI","P1","iOS, Android, Web, Desktop","No session","Tap login with empty fields","Validation errors shown, no API call","Whitespace-only input","Client validation active","Automate"
"AUTH-009","Authentication","Registration","Create account success then verify-email step","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Unique email/username","Submit valid registration","Session established and verify-email screen appears","Existing email conflict","Register API auto-authenticates","Automate"
"AUTH-010","Authentication","Registration validation","Invalid email/password formats rejected","Manual + UI","P1","iOS, Android, Web, Desktop","No session","Try invalid email, short password, weak password","User-friendly validation errors","Unicode emails, long usernames","Validation rules are enforced consistently","Automate"
"AUTH-011","Authentication","Email verification","Valid 6-digit code verifies account","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged-in unverified user","Enter 6-digit numeric code","Account marked verified and app routes forward","Code already used","Code must be exactly 6 digits","Automate"
"AUTH-012","Authentication","Email verification","Non-numeric/short/long code blocked","Manual + UI","P1","iOS, Android, Web, Desktop","On verify-email screen","Enter invalid codes","Verify action disabled or error shown","Pasted with spaces","Code input sanitizes to digits","Automate"
"AUTH-013","Authentication","Logout","Logout clears token, user data, lookups, and returns to login","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Tap logout","Login shown; protected API calls fail without token","Logout API fails network-side","Client clears state even if API call fails","Automate"
"AUTH-014","Authentication","Forgot password","Request reset by email success path","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Known account email","Submit forgot-password email","Success message and next step available","Unknown email behavior privacy-safe","Backend may still return generic success","Automate"
"AUTH-015","Authentication","Reset code verification","Verify reset code success path","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Reset email submitted","Enter correct code","Reset-token available for password reset","Expired code","Code verification endpoint returns token","Automate"
"AUTH-016","Authentication","Password reset","Reset password success with matching confirmation","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Valid reset token","Enter new password + confirm","Password changed; user can log in (or auto-login flow)","Token expires mid-flow","Reset endpoint ignores confirm field","Automate"
"AUTH-017","Authentication","Password reset","Mismatched password confirmation blocked","Manual + UI","P1","iOS, Android, Web, Desktop","Reset password screen","Enter mismatch","Inline error; no reset request","Trailing spaces","Client validates before submit","Automate"
"AUTH-018","Authentication","Deep link reset","Password-reset deep link opens flow with token prefilled","Manual + E2E UI","P0","iOS, Android","Installed app with deep-link support","Open reset deep link","Forgot/reset flow opens and token is consumed","Malformed token in URL","Deep link token can be cleared on back","Automate"
"AUTH-019","Authentication","SSO Apple","Apple Sign-In success creates or signs in account","Manual + Integration","P1","iOS","Apple-capable test device/simulator","Complete Apple sign-in","Session established; verification state handled","User hides email, first-login only email scope","Apple credential mapped to backend request","Automate partially (mock)"
"AUTH-020","Authentication","SSO Google","Google Sign-In success path","Manual + Integration","P1","Android, Web, KMP UI","Google sign-in configured","Complete Google sign-in","Session established with backend token","Revoked Google token","Backend validates ID token","Automate partially"
"ONB-001","Onboarding","Intent split","Start Fresh path goes through value props and name residence","Manual + E2E UI","P0","iOS, Android (KMP)","Fresh install","Choose Start Fresh and continue","Step order matches intended flow","Back navigation at each step","Flow differs by intent","Automate"
"ONB-002","Onboarding","Intent split","Join Existing path skips value/name steps and goes to account creation","Manual + E2E UI","P0","iOS, Android (KMP)","Fresh install","Choose Join Existing","Expected condensed step order","User switches intent mid-flow","Intent persisted during onboarding","Automate"
"ONB-003","Onboarding","Navigation","Back button transitions and step history correctness","Manual + UI","P1","iOS, Android (KMP)","In onboarding multi-step flow","Navigate forward then back","Returns to correct previous step","Back from verify-email triggers logout on iOS","Back behavior is product-defined","Automate"
"ONB-004","Onboarding","Skip behavior","Skippable screens skip to next valid state","Manual + UI","P1","iOS, Android (KMP)","On skippable step","Tap Skip","Progress advances without corrupting state","Skip on terminal upsell step completes onboarding","Skip availability is step-dependent","Automate"
"ONB-005","Onboarding","Residence bootstrap","Start Fresh creates residence automatically after verification","Manual + Integration","P0","iOS, Android (KMP)","Onboarding start-fresh with residence name","Verify email and continue","Residence created or graceful fallback if creation fails","Blank residence name bypasses creation","Creation failure should not hard-block onboarding","Automate"
"ONB-006","Onboarding","Join residence","Join-existing flow joins via share code","Manual + E2E UI","P0","iOS, Android (KMP)","Valid join code","Submit code in onboarding","User added to shared residence","Expired/invalid/reused code","Join code endpoint enforces ownership rules","Automate"
"ONB-007","Onboarding","First task","First-task onboarding step can create selected tasks","Manual + Integration","P1","iOS, Android (KMP)","On first-task step","Select templates and continue","Tasks created; flow proceeds","Partial task creation failures","At least one success considered success in KMP VM","Automate"
"ONB-008","Onboarding","Completion persistence","Completing onboarding persists flag and bypasses onboarding next launch","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Completed onboarding once","Restart app","Onboarding is skipped","App data clear resets flag","Onboarding flag stored locally","Automate"
"RES-001","Residences","List","Residences list loads with empty and non-empty states","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Open residences tab","Correct list/empty UI shown","Slow API and stale cache","List can come from cache or network","Automate"
"RES-002","Residences","Create","Create residence with required fields only","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Fill minimum fields and save","Residence appears in list/detail","Duplicate name allowed/not allowed behavior","Name required; other fields optional","Automate"
"RES-003","Residences","Create validation","Prevent submit when required name missing","Manual + UI","P1","iOS, Android, Web, Desktop","Open add residence form","Submit blank name","Validation error, no API call","Whitespace-only name","Required validation trims input","Automate"
"RES-004","Residences","Create optional fields","All optional numeric/text/address fields persist correctly","Manual + Integration","P1","iOS, Android, Web, Desktop","Open add residence form","Fill all fields and save","Values round-trip correctly in detail/edit","Decimals for bathrooms/lot size","Type conversion preserves precision","Automate"
"RES-005","Residences","Edit","Edit residence updates list and detail views","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Existing residence","Modify fields and save","Updated values shown immediately","Concurrent edit from another user","DataManager updates local caches","Automate"
"RES-006","Residences","Delete","Delete residence removes related task/document cached subsets","Manual + Integration","P0","iOS, Android, Web, Desktop","Residence with tasks/docs exists","Delete residence","Residence gone; related cached sections removed","Delete primary/only residence","Server cascade semantics documented","Automate"
"RES-007","Residences","Primary residence","Set/retain primary residence behavior","Manual","P2","iOS, Android, Web, Desktop","Multiple residences","Mark one as primary and reload","Only intended residence is primary","Two rapid primary updates","Backend enforces uniqueness","Automate partially"
"RES-008","Residences","Summary","Residence summary counts derive from kanban columns correctly","Manual + Integration","P1","iOS, Android, Web, Desktop","Residence with mixed task statuses","Open summary cards","Counts match task column truth","No tasks state","Summary can be client-computed","Automate"
"RES-009","Residences","Join by code","Join residence from manual share code entry","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Valid share code from another account","Enter code in join flow","Membership granted and residence appears","Code expired or already member","Join endpoint returns reasoned errors","Automate"
"RES-010","Residences","Generate share code","Generate/refresh residence share code","Manual + Integration","P1","iOS, Android, Web, Desktop","Owner access to residence","Generate code","New valid code returned/visible","Repeated generation invalidates old codes","Access limited by role","Automate"
"RES-011","Residences","Share package export","Create residence .casera package and open share sheet","Manual","P1","Android","Residence exists, logged in","Tap share residence","Share sheet opens with file attachment","Filename sanitization with special chars","Backend generates package with shareCode","Automate partially"
"RES-012","Residences","Share package import","Import .casera residence file joins residence","Manual + Integration","P0","Android","Valid .casera file received","Open file via app/import handler and confirm","Join succeeds and success dialog shown","Invalid JSON/wrong extension/no auth","Import requires auth and parse success","Automate partially"
"RES-013","Residences","Task report","Generate residence tasks report with/without email","Manual + Integration","P2","iOS, Android, Web, Desktop","Residence exists","Trigger generate report","Report creation success feedback","Invalid email format optional field","Backend handles async report generation","Automate"
"RES-014","Residences","Manage users view","Residence users list loads with owner/member roles","Manual + E2E UI","P1","iOS, Android (KMP)","Residence with multiple users","Open manage users","Accurate users and role indicators displayed","Owner missing from response","Role data trusted from API","Automate"
"RES-015","Residences","Remove user","Owner removes a member successfully","Manual + Integration","P0","iOS, Android (KMP)","Owner logged in, target member exists","Remove member","Member removed and state refreshes","Attempt remove self/owner","API enforces permission rules","Automate"
"TASK-001","Tasks","All tasks load","Kanban columns load for all residences","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in with at least one residence","Open tasks tab","Columns and counts render correctly","Zero tasks across all columns","Columns include overdue/in-progress/due-soon/upcoming/completed/cancelled","Automate"
"TASK-002","Tasks","Residence filtering","Tasks by residence uses filtered allTasks cache correctly","Manual + Integration","P1","iOS, Android, Web, Desktop","Multiple residences with tasks","Open residence detail tasks","Only selected residence tasks shown","Residence cache stale while global cache fresh","Client-side filtering path exists","Automate"
"TASK-003","Tasks","Create task","Create minimal valid task","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Residence exists, lookups loaded","Submit task with required fields","Task appears in expected column","Missing lookups due to failed seed load","Category/frequency/priority are required","Automate"
"TASK-004","Tasks","Create from template","Create task from template browser","Manual + E2E UI","P1","iOS, Android, Web, Desktop","Templates available","Open templates, select one, save","Task prefilled and created","Template with long description/tags","Template data from seeded lookups","Automate"
"TASK-005","Tasks","Template search","Search templates requires >=2 chars and limits results","Manual + Unit","P2","iOS, Android, Web, Desktop","Templates loaded","Search with 1 char then 2+ chars","1 char returns empty, 2+ filtered max 10","Case-insensitive tag match","Search is local in DataManager","Automate"
"TASK-006","Tasks","Edit task","Edit task fields and persist updates","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Existing task","Change title/category/frequency/priority/due/cost","Task updates and remains consistent in caches","Invalid cost string conversion","Edit route passes serialized fields","Automate"
"TASK-007","Tasks","Mark in progress","Transition task to in-progress column","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Existing non-in-progress task","Tap mark in progress","Task moves to in-progress column","Already in progress idempotency","UpdateTask uses kanbanColumn target","Automate"
"TASK-008","Tasks","Clear in progress","Clear in-progress state returns task to scheduled column","Manual + Integration","P1","iOS, Android, Web, Desktop","Task currently in progress","Clear in-progress","Task leaves in-progress with correct new column","Due date past while clearing","Backend decides target column","Automate"
"TASK-009","Tasks","Cancel task","Cancel action moves task to cancelled state","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Active task exists","Cancel task","Task appears in cancelled column/state","Cancel already-cancelled task","Endpoint idempotency defined","Automate"
"TASK-010","Tasks","Uncancel task","Restore cancelled task to active lifecycle","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Cancelled task exists","Uncancel task","Task restored to appropriate column","Uncancel archived task","State transitions validated by API","Automate"
"TASK-011","Tasks","Archive/unarchive","Archive hides task from active flow; unarchive restores","Manual + Integration","P1","iOS, Android, Web, Desktop","Task exists","Archive then unarchive","Visibility toggles correctly","Archived + cancelled combined states","Archive APIs available and cached updates propagate","Automate"
"TASK-012","Tasks","Delete semantics","Task removal updates all cached columns and summaries","Manual + Integration","P1","iOS, Android, Web, Desktop","Task exists in cached data","Delete or server-remove task then refresh","Task absent in all views and counts updated","Task present in multiple cached views","DataManager removeTask updates all maps","Automate"
"TASK-013","Tasks","Due date handling","Past/now/future due dates map to correct columns","Manual + Integration","P1","iOS, Android, Web, Desktop","Tasks with boundary due dates","Load tasks around timezone boundaries","Kanban placement matches backend logic","DST transitions","Backend provides canonical kanban_column","Automate"
"TASK-014","Tasks","Cost fields","Estimated cost accepts numeric and rejects invalid formats","Manual + UI","P2","iOS, Android, Web, Desktop","Task form open","Enter valid/invalid cost strings","Valid persisted; invalid blocked or sanitized","Locale decimal separators","Cost parsed to Double","Automate"
"TASK-015","Tasks","Task detail navigation","Push/deep-link task navigation opens tasks tab and relevant task context","Manual + E2E UI","P0","iOS, Android","App receives task navigation ID","Tap notification/open intent","Tasks tab selected and task reachable","Task deleted before open","Main shell handles navigate_to_task contract","Automate"
"TASK-016","Tasks","Bulk state refresh","After any task CRUD/action, summary cards refresh immediately","Manual + Integration","P1","iOS, Android, Web, Desktop","Dashboard visible with summaries","Perform task action","Summary counts update without hard reload","Rapid consecutive actions","Summary derived from cached kanban","Automate"
"TASK-017","Tasks","Concurrency","Two users edit same task; conflict resolution UX","Manual","P2","iOS, Android, Web, Desktop","Same task open on two accounts","Save conflicting edits","Consistent final state and clear error/last-write behavior","Out-of-order responses","Server conflict strategy documented","Manual"
"TCOMP-001","Task completion","Complete task basic","Complete task with notes/cost/rating","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Active task exists","Open complete flow and submit","Completion created and task column updates","Null rating vs default value","Completion endpoint accepts optional fields","Automate"
"TCOMP-002","Task completion","Complete with images","Attach one or multiple images during completion","Manual + Integration","P0","iOS, Android","Camera/gallery permission granted","Submit completion with images","Images uploaded and linked to completion","Large image compression/failure mid-upload","Image compression and multipart upload enabled","Automate partially"
"TCOMP-003","Task completion","Validation","Required completed-by field enforced (iOS form state)","Manual + UI","P1","iOS","Open complete task form","Submit blank completed-by","Validation error shown","Whitespace-only value","CompletedBy required by client form","Automate"
"TCOMP-004","Task completion","Completion history","History list loads for task and sorted correctly","Manual + Integration","P1","iOS, Android, Web, Desktop","Task with multiple completions","Open completion history","Entries ordered and accurate","Missing images in older completion records","History endpoint returns full list","Automate"
"DOC-001","Documents","List","Load all documents and residence-filtered documents","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in with docs data","Open documents tab and residence detail docs","Correct sets shown","Residence with zero docs","List supports optional residence filter","Automate"
"DOC-002","Documents","Create document","Create generic document with required fields","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Residence exists","Create document with title/type/residence","Document appears in lists","Missing residence selection on create","Create requires title/type/residence","Automate"
"DOC-003","Documents","Create warranty fields","Create warranty/appliance with provider/dates metadata","Manual + Integration","P1","iOS, Android, Web, Desktop","Document form open","Enter warranty-specific fields and save","Fields persist and render in detail","End date before start date","Date validation expectations defined","Automate"
"DOC-004","Documents","Edit document","Edit existing document including type/category/tags","Manual + E2E UI","P1","iOS, Android, Web, Desktop","Document exists","Modify and save","Detail/list reflect updates","Switching types with stale fields","Backend accepts partial update","Automate"
"DOC-005","Documents","Delete document","Delete removes from global and residence caches","Manual + Integration","P0","iOS, Android, Web, Desktop","Document exists in caches","Delete document","Document removed everywhere","Delete while detail screen open","DataManager removeDocument updates both caches","Automate"
"DOC-006","Documents","Upload image","Upload document image from camera/gallery","Manual + Integration","P0","iOS, Android","Permissions granted","Add image to document","Thumbnail and full image accessible","Upload timeout","Upload endpoint returns image metadata","Automate partially"
"DOC-007","Documents","Delete image","Delete specific document image updates detail immediately","Manual + Integration","P1","iOS, Android, Web, Desktop","Document with multiple images","Delete one image","Remaining images preserved","Deleting last image","Image delete endpoint idempotency","Automate"
"DOC-008","Documents","Download","Download/open document file via URL","Manual","P1","iOS, Android, Web, Desktop","Document has downloadable URL","Tap download/open","File retrieved and usable","Expired signed URL","Download API wraps binary result","Automate partially"
"DOC-009","Documents","Validation","Claim email optional but must be valid if provided","Manual + UI","P2","iOS","Document form open","Enter invalid claim email","Validation error shown","Internationalized domains","Email regex defines valid format","Automate"
"DOC-010","Documents","Media viewer","Image viewer navigation, zoom, swipe, close behavior","Manual","P2","iOS, Android","Document with multiple images","Open viewer and interact","No crashes; correct index and gestures","Very large images","Viewer supports list index initialization","Manual"
"CON-001","Contractors","List","Load contractors with empty and populated states","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Open contractors tab","List/empty state correct","Large list pagination if any","API supports optional filters","Automate"
"CON-002","Contractors","Create","Create contractor minimal required fields","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Create contractor with name","Contractor appears in list/detail","Special characters in names","Name is required","Automate"
"CON-003","Contractors","Create optional data","Persist optional company/contact/address/specialties","Manual + Integration","P1","iOS, Android, Web, Desktop","Contractor form open","Fill optional fields and save","All values persist accurately","Invalid website URL format","Optional fields may be null","Automate"
"CON-004","Contractors","Email validation","Optional email must be valid if supplied","Manual + UI","P1","iOS, Android, Web, Desktop","Contractor form open","Enter invalid email","Validation error blocks save","Uppercase email + spaces","Validation trims and regex-checks","Automate"
"CON-005","Contractors","Edit","Edit contractor and verify list/detail sync","Manual + E2E UI","P1","iOS, Android, Web, Desktop","Existing contractor","Update fields and save","Updated across views","Concurrent remote update","DataManager updateContractor handles summary mapping","Automate"
"CON-006","Contractors","Delete","Delete contractor removes from caches and residence associations","Manual + Integration","P0","iOS, Android, Web, Desktop","Existing contractor","Delete contractor","Removed from all views","Deleting favorite contractor","Association cleanup server-side","Automate"
"CON-007","Contractors","Favorite toggle","Toggle favorite updates UI and persistence","Manual + E2E UI","P1","iOS, Android, Web, Desktop","Existing contractor","Toggle favorite twice","State toggles correctly and persists refresh","Rapid repeated taps","Endpoint supports idempotent toggles","Automate"
"CON-008","Contractors","By residence filter","Load contractors scoped to residence","Manual + Integration","P1","iOS, Android, Web, Desktop","Multiple residences and linked contractors","Open residence contractor section","Only related contractors shown","Contractor with null residence","Filtering done server-side","Automate"
"CON-009","Contractors","Share export","Share contractor as .casera file","Manual","P1","Android","Contractor exists","Tap share contractor","Share sheet opens with valid file payload","Name containing '/' and long length","Filename sanitization applied","Manual"
"CON-010","Contractors","Import .casera","Import contractor from valid file","Manual + Integration","P0","Android","Logged in, valid contractor file","Open file/import confirm","Contractor created and success dialog shown","Unknown specialty names in file","Specialties mapped by name to known IDs","Automate partially"
"CON-011","Contractors","Import invalid file","Invalid extension/JSON/auth state handled safely","Manual","P0","Android","Invalid file or logged out","Attempt import","Clear error shown; no partial creation","Huge malformed JSON","Import parser errors are surfaced","Manual"
"NOTIF-001","Notifications","Permission prompt","Notification permission request outcomes handled","Manual","P0","iOS, Android","Fresh install","Respond Allow and Deny in separate runs","App continues gracefully; state reflects permission","User changes setting later","Permission checked on foreground","Manual"
"NOTIF-002","Notifications","Device registration","Register device token after login only","Manual + Integration","P0","iOS, Android","Have APNs/FCM token","Login with token available","registerDevice called once and succeeds","Token arrives before auth","Auth gating prevents unauthenticated registration","Automate"
"NOTIF-003","Notifications","Token refresh","New push token triggers backend re-registration","Manual + Integration","P1","iOS, Android","Previously registered token","Simulate token rotation","Backend receives updated registration id","No token change should skip call","Last registered token cache used","Automate"
"NOTIF-004","Notifications","Foreground notification","Foreground notifications display banner/sound and update read state","Manual","P1","iOS, Android","Permission granted, send test push","Receive push while app active","Banner shown; notification handled","Malformed payload missing type","Foreground presentation explicitly enabled","Manual"
"NOTIF-005","Notifications","Notification tap navigation","Tap task push opens app and routes to tasks context","Manual + E2E","P0","iOS, Android","Task-linked push sent","Tap push from background/terminated","App opens on tasks flow for target task","Task no longer exists","Task id may be string or int","Automate partially"
"NOTIF-006","Notifications","Action buttons premium","Premium users see and can execute task action buttons","Manual + Integration","P0","iOS, Android","Premium subscription active","Receive actionable task notification, tap action","Action API executes and UI refreshes","Action timeout/network loss","Actions gated by premium/limitationsEnabled","Manual"
"NOTIF-007","Notifications","Action buttons free-tier gating","Free users with limitations enabled are routed home/not allowed actions","Manual","P0","iOS, Android","Free user limitationsEnabled=true","Tap actionable notification","No privileged task action executed","Subscription cache stale nil","Nil subscription defaults allow on iOS currently","Manual"
"NOTIF-008","Notifications","Preferences","Load and update notification preference toggles","Manual + Integration","P1","iOS, Android, Web, Desktop","Logged in","Open notification preferences, toggle settings, save","Preferences persist and affect server payloads","Partial update failures","Preferences API supports patch/update","Automate"
"NOTIF-009","Notifications","History/read state","Notification history list and mark-read operations","Manual + Integration","P2","iOS, Android, Web, Desktop","Notifications exist","Open history, mark one and mark all","Unread counts decrement correctly","Race with incoming push","Unread count endpoint consistent","Automate"
"SUB-001","Subscription","Status load","Subscription status loads at app launch/foreground","Manual + Integration","P0","iOS, Android, Web, Desktop","Logged in","Launch then background/foreground app","Status cache updates and UI gating accurate","Backend temporarily unavailable","Status refresh should be non-fatal","Automate"
"SUB-002","Subscription","Upgrade screen products","Load purchasable plans and pricing","Manual","P0","iOS, Android","Store config present","Open upgrade screen","Monthly/annual products displayed","Store connectivity issues","Product IDs configured as expected","Manual + mocked automation"
"SUB-003","Subscription","Purchase monthly","Complete monthly purchase and backend verification","Manual + Integration","P0","iOS, Android","Sandbox account, product available","Buy monthly plan","Entitlement granted, subscription status becomes pro","Pending transactions","Verification endpoint must return success","Manual"
"SUB-004","Subscription","Purchase annual","Complete annual purchase and backend verification","Manual + Integration","P0","iOS, Android","Sandbox account","Buy annual plan","Entitlement granted and reflected in app","Upgrade/downgrade from existing plan","Latest transaction determines tier","Manual"
"SUB-005","Subscription","Restore purchases","Restore on clean install/device migration","Manual + Integration","P0","iOS, Android","Existing prior subscription","Tap restore","Entitlements restored and backend synced","No previous purchases","Restore should not duplicate grants","Manual"
"SUB-006","Subscription","Purchase cancellation","User-cancelled purchase does not show fatal error","Manual","P1","iOS, Android","Open paywall","Start then cancel purchase","No entitlement changes; UX remains stable","Repeated cancel attempts","User cancel considered non-error","Manual"
"SUB-007","Subscription","Backend verification failure","Store purchase succeeds but backend verify fails","Manual","P0","iOS, Android","Force backend verify failure","Complete purchase","User sees recoverable state and can retry/restore","Receipt parsing mismatch","App should avoid false pro unlock","Manual"
"SUB-008","Subscription","Feature gating","Pro-only features hidden/disabled for limited users","Manual + E2E","P0","iOS, Android, Web, Desktop","Test free and pro accounts","Traverse gated features (actions, limits, upgrades)","Gating consistent across surfaces","Cache stale after plan change","Gating uses subscription status + limitationsEnabled","Automate"
"WID-001","Widgets","Small widget rendering","Small widget shows counts and opens app","Manual","P1","Android","Widget added, logged in","Place small widget and tap","Correct counts; tap opens app","No data cached yet","Widget reads from shared preferences state","Manual"
"WID-002","Widgets","Medium widget list","Medium widget shows top tasks and overdue badge","Manual","P1","Android","Tasks exist","Place medium widget","Task rows and overdue badge correct","Malformed tasks_json","JSON parse fallback to empty list","Manual"
"WID-003","Widgets","Large widget interactions","Large widget actions execute for pro users","Manual + Integration","P0","Android","Pro account, widget configured","Tap row and action controls","Opens task or executes action as expected","Free user should not see/execute pro actions","Widget passes task_id in intent","Manual"
"WID-004","Widgets","Widget refresh","Widgets refresh after task state changes","Manual","P1","Android","Widget present","Complete/cancel task in app","Widget counts/list update within expected interval","Background restrictions","Widget update manager triggers refresh","Manual"
"SHR-001","Sharing/Import","File association",".casera files open app import flow","Manual","P1","Android","Have .casera file","Open file from files app/share sheet","Import confirmation dialog shown","Multiple apps can open same MIME","Intent filter handles application/json with extension","Manual"
"SHR-002","Sharing/Import","Security","Import rejects when unauthenticated","Manual","P0","Android","Logged out, .casera file ready","Attempt import","Error shown, no data mutation","Stale token in storage","Auth check occurs before API call","Manual"
"SHR-003","Sharing/Import","Corrupt payload","Corrupt .casera payload fails safely without crash","Manual","P0","Android","Malformed JSON file","Attempt import","Graceful error dialog","Very large payload","Parser exceptions are caught","Manual"
"DATA-001","Data layer","Lookups init","Seeded lookup data loads once and marks initialized","Manual + Integration","P0","iOS, Android, Web, Desktop","Fresh login","Observe first data bootstrap","Lookups available for forms/templates","Slow network during bootstrap","initializeLookups has concurrency guard","Automate"
"DATA-002","Data layer","ETag refresh","Lookup refresh uses ETag and handles 304 not modified","Manual + Integration","P1","iOS, Android, Web, Desktop","Lookups already loaded + ETag","Foreground app or force refresh","No unnecessary data churn on 304","ETag lost between sessions","ETag persisted in storage","Automate"
"DATA-003","Data layer","Legacy fallback","If seeded-data endpoint fails, fallback static data path works","Manual + Integration","P1","iOS, Android, Web, Desktop","Mock seeded endpoint failure","Initialize lookups","Core lookups still available","Templates missing in fallback","Fallback endpoint still reachable","Automate"
"DATA-004","Data layer","Cache timeout","One-hour cache timeout triggers fresh fetch after expiry","Manual + Integration","P1","iOS, Android, Web, Desktop","Cached data older/newer than timeout","Request data with forceRefresh=false","Valid cache reused; stale cache refetched","Clock skew/device time changes","Timeout constant is 3600000 ms","Automate"
"DATA-005","Data layer","Cache invalidation on logout","Logout clears user data/cache/ETag but retains theme","Manual + Integration","P0","iOS, Android, Web, Desktop","Logged in with populated data","Logout then inspect next launch","No user data remains; theme preference retained","Persistence clear implementation drift","Theme stored separately from persistenceManager.clear","Automate"
"DATA-006","Data layer","Disk persistence","Current user and lookups reload correctly after app restart","Manual + Integration","P1","iOS, Android, Web, Desktop","Logged in and data loaded","Kill and relaunch app","State restored without full refetch where valid","Partial/corrupt persisted JSON","Deserializer ignoreUnknownKeys is enabled","Automate"
"DATA-007","Data layer","Map/list consistency","Lookup map IDs and list values remain consistent after updates","Unit + Integration","P2","iOS, Android, Web, Desktop","Lookup update operation","Compare list and map representations","No missing or mismatched IDs","Duplicate IDs from backend","Maps are built via associateBy(id)","Automate"
"OFF-001","Resilience","Offline launch","Offline launch with cached token/data behaves gracefully","Manual","P0","iOS, Android, Web, Desktop","Previously logged in with cached data","Launch with network off","No crash; clear messaging; cached UI where possible","Token validation cannot reach server","Current behavior may clear session on fetch failure","Manual"
"OFF-002","Resilience","Offline action handling","Create/update actions fail with retriable errors when offline","Manual","P0","iOS, Android, Web, Desktop","Network disabled","Attempt create/edit/delete flows","Errors shown; no phantom local success","Intermittent network flaps","No offline queue currently assumed","Manual"
"OFF-003","Resilience","Retry behavior","Retry from error dialogs succeeds without stale UI state","Manual + E2E","P1","iOS, Android, Web, Desktop","Force transient API failure","Tap retry then restore network","Action succeeds and loading/error states reset","Double-tap retry race","ApiResult state machine handles Idle/Loading/Error","Automate"
"OFF-004","Resilience","Idempotency UX","Double submit protection for create flows","Manual + UI","P1","iOS, Android, Web, Desktop","Open any create form","Rapid tap save","Single record created","Very slow API response","Buttons disabled during loading","Automate"
"SEC-001","Security","Auth boundaries","Protected endpoints reject without token and UI handles 401","Manual + Integration","P0","iOS, Android, Web, Desktop","No token","Attempt protected operations","Redirect/login prompt or clear error","Token injected but expired","APILayer checks token before API in many calls","Automate"
"SEC-002","Security","Session cleanup","Sensitive data not accessible after logout and app restart","Manual","P0","iOS, Android, Web, Desktop","Logged in then logout","Force close and relaunch","No protected screens/data accessible","Widget still showing stale data","Widget caches should be cleared on logout (iOS path)","Manual"
"SEC-003","Security","Import validation","Imported files cannot execute code or break parser boundaries","Manual","P1","Android","Craft malicious JSON payload","Import payload","App rejects safely, no crash","Oversized strings, deep nesting","Deserializer should throw and be caught","Manual"
"SEC-004","Security","PII exposure","Logs and analytics avoid leaking sensitive credential values","Manual + Code audit","P1","iOS, Android, Web, Desktop","Enable debug logging","Run auth/payment flows","No passwords/tokens in logs/events","Third-party SDK auto-capture risk","PostHog config reviewed","Manual"
"PERF-001","Performance","Cold start","Startup time within target for logged-out and logged-in states","Manual + Perf","P1","iOS, Android","Profile build with instrumentation","Measure cold launch","Meets agreed startup SLA","Slow network path for verified user","Auth check performs network call","Automate perf"
"PERF-002","Performance","Large data rendering","Task/document/contractor lists remain responsive with large datasets","Manual + Perf","P1","iOS, Android, Web, Desktop","Seed large dataset","Scroll and interact lists","No jank/crash; acceptable memory","Thousands of items and images","Virtualized list behavior depends on platform","Manual + benchmarks"
"PERF-003","Performance","Image handling","Large image capture/upload/compression memory stability","Manual + Perf","P0","iOS, Android","Use high-resolution photos","Attach multiple images","No OOM/crash; upload completes or fails gracefully","Low-memory device","ImageCompressor platform implementations are active","Manual"
"PERF-004","Performance","Background operations","Foreground/resume refresh does not block UI thread","Manual + Perf","P2","iOS, Android","App with valid session","Background then foreground repeatedly","UI remains interactive during refresh","Concurrent refresh and navigation","Lookups refresh runs async","Manual"
"A11Y-001","Accessibility","Basic semantics","All primary controls have accessible labels/identifiers","Manual","P0","iOS, Android, Web, Desktop","Screen reader on","Traverse major flows","Controls are announced clearly","Custom components lacking labels","Accessibility identifiers partly defined","Manual + lint"
"A11Y-002","Accessibility","Dynamic type","Text scales correctly without clipping in key screens","Manual","P1","iOS, Android","Large accessibility font settings","Open forms/lists/dialogs","Layout remains usable","Long localized strings","Design system supports flexible layout","Manual"
"A11Y-003","Accessibility","Keyboard navigation","Tab/focus order valid on web/desktop forms","Manual","P1","Web, Desktop","Hardware keyboard","Navigate forms using keyboard only","Logical focus traversal and visible focus states","Modal dialogs focus trap","Compose/web focus handling may differ","Manual"
"A11Y-004","Accessibility","Color contrast","Theme variants meet minimum contrast requirements","Manual + Tooling","P1","iOS, Android, Web, Desktop","Cycle themes","Inspect text/icon contrast","WCAG contrast thresholds met","Error/success states on tinted backgrounds","Multiple custom themes supported","Manual + automated audit"
"I18N-001","Localization","String coverage","No missing keys/placeholders across supported locales","Manual + Static check","P1","iOS, Android, Web, Desktop","Run app in each locale","Traverse major screens","No raw keys, no placeholder mismatches","Pluralization and gender strings","Locales include es/fr/de/it/ja/ko/nl/pt/zh etc.","Automate (lint + screenshot)"
"I18N-002","Localization","Layout expansion","Long translations do not break onboarding/forms/buttons","Manual","P1","iOS, Android, Web, Desktop","Switch to longest-string locale","Review high-density screens","No clipping/overlap","RTL future locale support","Current locales may be LTR only","Manual"
"THEME-001","Theming","Theme persistence","Theme choice persists across app restarts","Manual + Integration","P1","iOS, Android, Web, Desktop","Logged in or logged out","Change theme then relaunch","Selected theme reapplied","Theme ID missing/corrupt in storage","Theme stored separately from auth data","Automate"
"THEME-002","Theming","Theme switch live update","Changing theme updates active screen without broken states","Manual + UI","P2","iOS, Android, Web, Desktop","Open app on any tab","Change theme in profile/settings","Immediate UI recolor with legible components","Transition while modal open","Theme manager publishes updates","Manual"
"NAV-001","Navigation","Bottom tabs","Residences/Tasks/Contractors/Documents tabs navigate and preserve expected state","Manual + E2E UI","P0","iOS, Android","Logged in","Switch tabs repeatedly","Correct screens shown; no stuck navigation","Push navigation then tab switch back","Nested nav stacks differ per platform","Automate"
"NAV-002","Navigation","Back stack safety","Back from details/forms returns to correct parent","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Navigate into detail/edit screens","Use back gestures/buttons","Parent state intact and refreshed as expected","Direct deep-link entry without parent","Saved-state refresh flags used in KMP nav","Automate"
"NAV-003","Navigation","Duplicate routes","Avoid duplicate screen instances from repeated tap/navigation actions","Manual","P2","iOS, Android, Web, Desktop","Rapidly tap nav actions","Observe back stack and UI","No duplicate stacking or loops","Double tap race conditions","NavHost popUpTo rules applied","Manual"
"ANL-001","Analytics","Auth events","Login/register/logout/verify events fire once with correct properties","Manual + Integration","P2","iOS, Android","Analytics enabled in test env","Perform auth flows","Expected events emitted once","Retries causing duplicate events","Event taxonomy defined in analytics layer","Automate with mocked sink"
"ANL-002","Analytics","Core feature events","Residence/task/document/contractor create-edit-delete events tracked","Manual + Integration","P2","iOS, Android","Analytics test workspace","Perform CRUD actions","Events mapped to correct feature","Failed actions should not emit success","PostHog wrappers used consistently","Automate"
"ANL-003","Analytics","Subscription events","Upgrade prompt open, purchase, restore, verification outcomes tracked","Manual + Integration","P2","iOS, Android","Store sandbox + analytics","Run subscription flows","Lifecycle events present and correctly attributed","Purchase canceled path","No sensitive receipt data in events","Manual"
"QA-001","Cross-platform parity","Feature parity","Core flows behave equivalently between KMP UI and iOS native UI","Manual regression","P0","iOS, Android, Web, Desktop","Same seeded account","Run same scenarios on each platform","Equivalent outcomes and data integrity","Known UX differences documented","iOS native app is source for iOS UX","Manual"
"QA-002","Cross-platform parity","API contract consistency","All clients handle new/unknown JSON fields gracefully","Integration","P1","iOS, Android, Web, Desktop","Backend adds extra fields","Run major endpoints","No crash; fields ignored where unknown","Type changes breaking parsing","Kotlin serializers set ignoreUnknownKeys","Automate"
"QA-003","Release quality","Smoke suite","Minimal release gate across auth, residence, task, document, contractor, notification, subscription","Manual + Automated","P0","iOS, Android","Release candidate build","Run smoke checklist","No blockers before release","Environment instability","Smoke should run against stable test backend","Automate + manual signoff"
"QA-004","Release quality","Data migration","Upgrade app version preserves critical local state safely","Manual","P1","iOS, Android, Web, Desktop","Install old build with data then upgrade","Launch and use app","No corruption; expected resets only","Schema/key changes in persistence","Persistence keys remain compatible","Manual"
1 Test_ID Domain Feature Scenario Test_Method Priority Platforms Preconditions Steps Expected_Result Edge_Cases Assumptions Automation_Recommendation
2 AUTH-001 Authentication App start routing First launch routes to onboarding when hasCompletedOnboarding=false Manual + E2E UI P0 iOS, Android, Web, Desktop Fresh install, no token Launch app Onboarding welcome is shown, not login/main tabs Corrupted local onboarding flag Onboarding state is persisted locally Automate (UI smoke)
3 AUTH-002 Authentication App start routing Returning user with onboarding complete and no token routes to login Manual + E2E UI P0 iOS, Android, Web, Desktop hasCompletedOnboarding=true, token missing Launch app Login screen shown Stale cached user object present Token is source of truth Automate
4 AUTH-003 Authentication App start routing Authenticated + verified user routes to main tabs Manual + E2E UI P0 iOS, Android, Web, Desktop Valid token, verified user Launch app Main tab shell displayed Cached token exists but API fails Current-user fetch determines validity Automate
5 AUTH-004 Authentication App start routing Authenticated but unverified user routes to verify email Manual + E2E UI P0 iOS, Android, Web, Desktop Valid token, verified=false Launch app Verify email screen shown User gets verified between launches Verification status fetched from backend Automate
6 AUTH-005 Authentication Token invalidation Invalid token at startup clears session and returns to login Manual + Integration P0 iOS, Android, Web, Desktop Expired/invalid token stored Launch app Data cleared and login shown Backend 500 vs 401 behavior 401/failed current-user means logout Automate
7 AUTH-006 Authentication Login Valid username/password login success Manual + E2E UI P0 iOS, Android, Web, Desktop Existing verified account Submit login form Token persisted, lookups initialized, main shown Slow network during login Login API returns token+user Automate
8 AUTH-007 Authentication Login Invalid credentials shows actionable error Manual + E2E UI P0 iOS, Android, Web, Desktop No session Submit wrong password Error shown, user remains on login Rate-limit or lockout responses Error parser maps backend errors Automate
9 AUTH-008 Authentication Login validation Empty username/password blocked client-side Manual + UI P1 iOS, Android, Web, Desktop No session Tap login with empty fields Validation errors shown, no API call Whitespace-only input Client validation active Automate
10 AUTH-009 Authentication Registration Create account success then verify-email step Manual + E2E UI P0 iOS, Android, Web, Desktop Unique email/username Submit valid registration Session established and verify-email screen appears Existing email conflict Register API auto-authenticates Automate
11 AUTH-010 Authentication Registration validation Invalid email/password formats rejected Manual + UI P1 iOS, Android, Web, Desktop No session Try invalid email, short password, weak password User-friendly validation errors Unicode emails, long usernames Validation rules are enforced consistently Automate
12 AUTH-011 Authentication Email verification Valid 6-digit code verifies account Manual + E2E UI P0 iOS, Android, Web, Desktop Logged-in unverified user Enter 6-digit numeric code Account marked verified and app routes forward Code already used Code must be exactly 6 digits Automate
13 AUTH-012 Authentication Email verification Non-numeric/short/long code blocked Manual + UI P1 iOS, Android, Web, Desktop On verify-email screen Enter invalid codes Verify action disabled or error shown Pasted with spaces Code input sanitizes to digits Automate
14 AUTH-013 Authentication Logout Logout clears token, user data, lookups, and returns to login Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Tap logout Login shown; protected API calls fail without token Logout API fails network-side Client clears state even if API call fails Automate
15 AUTH-014 Authentication Forgot password Request reset by email success path Manual + E2E UI P0 iOS, Android, Web, Desktop Known account email Submit forgot-password email Success message and next step available Unknown email behavior privacy-safe Backend may still return generic success Automate
16 AUTH-015 Authentication Reset code verification Verify reset code success path Manual + E2E UI P0 iOS, Android, Web, Desktop Reset email submitted Enter correct code Reset-token available for password reset Expired code Code verification endpoint returns token Automate
17 AUTH-016 Authentication Password reset Reset password success with matching confirmation Manual + E2E UI P0 iOS, Android, Web, Desktop Valid reset token Enter new password + confirm Password changed; user can log in (or auto-login flow) Token expires mid-flow Reset endpoint ignores confirm field Automate
18 AUTH-017 Authentication Password reset Mismatched password confirmation blocked Manual + UI P1 iOS, Android, Web, Desktop Reset password screen Enter mismatch Inline error; no reset request Trailing spaces Client validates before submit Automate
19 AUTH-018 Authentication Deep link reset Password-reset deep link opens flow with token prefilled Manual + E2E UI P0 iOS, Android Installed app with deep-link support Open reset deep link Forgot/reset flow opens and token is consumed Malformed token in URL Deep link token can be cleared on back Automate
20 AUTH-019 Authentication SSO Apple Apple Sign-In success creates or signs in account Manual + Integration P1 iOS Apple-capable test device/simulator Complete Apple sign-in Session established; verification state handled User hides email, first-login only email scope Apple credential mapped to backend request Automate partially (mock)
21 AUTH-020 Authentication SSO Google Google Sign-In success path Manual + Integration P1 Android, Web, KMP UI Google sign-in configured Complete Google sign-in Session established with backend token Revoked Google token Backend validates ID token Automate partially
22 ONB-001 Onboarding Intent split Start Fresh path goes through value props and name residence Manual + E2E UI P0 iOS, Android (KMP) Fresh install Choose Start Fresh and continue Step order matches intended flow Back navigation at each step Flow differs by intent Automate
23 ONB-002 Onboarding Intent split Join Existing path skips value/name steps and goes to account creation Manual + E2E UI P0 iOS, Android (KMP) Fresh install Choose Join Existing Expected condensed step order User switches intent mid-flow Intent persisted during onboarding Automate
24 ONB-003 Onboarding Navigation Back button transitions and step history correctness Manual + UI P1 iOS, Android (KMP) In onboarding multi-step flow Navigate forward then back Returns to correct previous step Back from verify-email triggers logout on iOS Back behavior is product-defined Automate
25 ONB-004 Onboarding Skip behavior Skippable screens skip to next valid state Manual + UI P1 iOS, Android (KMP) On skippable step Tap Skip Progress advances without corrupting state Skip on terminal upsell step completes onboarding Skip availability is step-dependent Automate
26 ONB-005 Onboarding Residence bootstrap Start Fresh creates residence automatically after verification Manual + Integration P0 iOS, Android (KMP) Onboarding start-fresh with residence name Verify email and continue Residence created or graceful fallback if creation fails Blank residence name bypasses creation Creation failure should not hard-block onboarding Automate
27 ONB-006 Onboarding Join residence Join-existing flow joins via share code Manual + E2E UI P0 iOS, Android (KMP) Valid join code Submit code in onboarding User added to shared residence Expired/invalid/reused code Join code endpoint enforces ownership rules Automate
28 ONB-007 Onboarding First task First-task onboarding step can create selected tasks Manual + Integration P1 iOS, Android (KMP) On first-task step Select templates and continue Tasks created; flow proceeds Partial task creation failures At least one success considered success in KMP VM Automate
29 ONB-008 Onboarding Completion persistence Completing onboarding persists flag and bypasses onboarding next launch Manual + E2E UI P0 iOS, Android, Web, Desktop Completed onboarding once Restart app Onboarding is skipped App data clear resets flag Onboarding flag stored locally Automate
30 RES-001 Residences List Residences list loads with empty and non-empty states Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Open residences tab Correct list/empty UI shown Slow API and stale cache List can come from cache or network Automate
31 RES-002 Residences Create Create residence with required fields only Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Fill minimum fields and save Residence appears in list/detail Duplicate name allowed/not allowed behavior Name required; other fields optional Automate
32 RES-003 Residences Create validation Prevent submit when required name missing Manual + UI P1 iOS, Android, Web, Desktop Open add residence form Submit blank name Validation error, no API call Whitespace-only name Required validation trims input Automate
33 RES-004 Residences Create optional fields All optional numeric/text/address fields persist correctly Manual + Integration P1 iOS, Android, Web, Desktop Open add residence form Fill all fields and save Values round-trip correctly in detail/edit Decimals for bathrooms/lot size Type conversion preserves precision Automate
34 RES-005 Residences Edit Edit residence updates list and detail views Manual + E2E UI P0 iOS, Android, Web, Desktop Existing residence Modify fields and save Updated values shown immediately Concurrent edit from another user DataManager updates local caches Automate
35 RES-006 Residences Delete Delete residence removes related task/document cached subsets Manual + Integration P0 iOS, Android, Web, Desktop Residence with tasks/docs exists Delete residence Residence gone; related cached sections removed Delete primary/only residence Server cascade semantics documented Automate
36 RES-007 Residences Primary residence Set/retain primary residence behavior Manual P2 iOS, Android, Web, Desktop Multiple residences Mark one as primary and reload Only intended residence is primary Two rapid primary updates Backend enforces uniqueness Automate partially
37 RES-008 Residences Summary Residence summary counts derive from kanban columns correctly Manual + Integration P1 iOS, Android, Web, Desktop Residence with mixed task statuses Open summary cards Counts match task column truth No tasks state Summary can be client-computed Automate
38 RES-009 Residences Join by code Join residence from manual share code entry Manual + E2E UI P0 iOS, Android, Web, Desktop Valid share code from another account Enter code in join flow Membership granted and residence appears Code expired or already member Join endpoint returns reasoned errors Automate
39 RES-010 Residences Generate share code Generate/refresh residence share code Manual + Integration P1 iOS, Android, Web, Desktop Owner access to residence Generate code New valid code returned/visible Repeated generation invalidates old codes Access limited by role Automate
40 RES-011 Residences Share package export Create residence .casera package and open share sheet Manual P1 Android Residence exists, logged in Tap share residence Share sheet opens with file attachment Filename sanitization with special chars Backend generates package with shareCode Automate partially
41 RES-012 Residences Share package import Import .casera residence file joins residence Manual + Integration P0 Android Valid .casera file received Open file via app/import handler and confirm Join succeeds and success dialog shown Invalid JSON/wrong extension/no auth Import requires auth and parse success Automate partially
42 RES-013 Residences Task report Generate residence tasks report with/without email Manual + Integration P2 iOS, Android, Web, Desktop Residence exists Trigger generate report Report creation success feedback Invalid email format optional field Backend handles async report generation Automate
43 RES-014 Residences Manage users view Residence users list loads with owner/member roles Manual + E2E UI P1 iOS, Android (KMP) Residence with multiple users Open manage users Accurate users and role indicators displayed Owner missing from response Role data trusted from API Automate
44 RES-015 Residences Remove user Owner removes a member successfully Manual + Integration P0 iOS, Android (KMP) Owner logged in, target member exists Remove member Member removed and state refreshes Attempt remove self/owner API enforces permission rules Automate
45 TASK-001 Tasks All tasks load Kanban columns load for all residences Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in with at least one residence Open tasks tab Columns and counts render correctly Zero tasks across all columns Columns include overdue/in-progress/due-soon/upcoming/completed/cancelled Automate
46 TASK-002 Tasks Residence filtering Tasks by residence uses filtered allTasks cache correctly Manual + Integration P1 iOS, Android, Web, Desktop Multiple residences with tasks Open residence detail tasks Only selected residence tasks shown Residence cache stale while global cache fresh Client-side filtering path exists Automate
47 TASK-003 Tasks Create task Create minimal valid task Manual + E2E UI P0 iOS, Android, Web, Desktop Residence exists, lookups loaded Submit task with required fields Task appears in expected column Missing lookups due to failed seed load Category/frequency/priority are required Automate
48 TASK-004 Tasks Create from template Create task from template browser Manual + E2E UI P1 iOS, Android, Web, Desktop Templates available Open templates, select one, save Task prefilled and created Template with long description/tags Template data from seeded lookups Automate
49 TASK-005 Tasks Template search Search templates requires >=2 chars and limits results Manual + Unit P2 iOS, Android, Web, Desktop Templates loaded Search with 1 char then 2+ chars 1 char returns empty, 2+ filtered max 10 Case-insensitive tag match Search is local in DataManager Automate
50 TASK-006 Tasks Edit task Edit task fields and persist updates Manual + E2E UI P0 iOS, Android, Web, Desktop Existing task Change title/category/frequency/priority/due/cost Task updates and remains consistent in caches Invalid cost string conversion Edit route passes serialized fields Automate
51 TASK-007 Tasks Mark in progress Transition task to in-progress column Manual + E2E UI P0 iOS, Android, Web, Desktop Existing non-in-progress task Tap mark in progress Task moves to in-progress column Already in progress idempotency UpdateTask uses kanbanColumn target Automate
52 TASK-008 Tasks Clear in progress Clear in-progress state returns task to scheduled column Manual + Integration P1 iOS, Android, Web, Desktop Task currently in progress Clear in-progress Task leaves in-progress with correct new column Due date past while clearing Backend decides target column Automate
53 TASK-009 Tasks Cancel task Cancel action moves task to cancelled state Manual + E2E UI P0 iOS, Android, Web, Desktop Active task exists Cancel task Task appears in cancelled column/state Cancel already-cancelled task Endpoint idempotency defined Automate
54 TASK-010 Tasks Uncancel task Restore cancelled task to active lifecycle Manual + E2E UI P0 iOS, Android, Web, Desktop Cancelled task exists Uncancel task Task restored to appropriate column Uncancel archived task State transitions validated by API Automate
55 TASK-011 Tasks Archive/unarchive Archive hides task from active flow; unarchive restores Manual + Integration P1 iOS, Android, Web, Desktop Task exists Archive then unarchive Visibility toggles correctly Archived + cancelled combined states Archive APIs available and cached updates propagate Automate
56 TASK-012 Tasks Delete semantics Task removal updates all cached columns and summaries Manual + Integration P1 iOS, Android, Web, Desktop Task exists in cached data Delete or server-remove task then refresh Task absent in all views and counts updated Task present in multiple cached views DataManager removeTask updates all maps Automate
57 TASK-013 Tasks Due date handling Past/now/future due dates map to correct columns Manual + Integration P1 iOS, Android, Web, Desktop Tasks with boundary due dates Load tasks around timezone boundaries Kanban placement matches backend logic DST transitions Backend provides canonical kanban_column Automate
58 TASK-014 Tasks Cost fields Estimated cost accepts numeric and rejects invalid formats Manual + UI P2 iOS, Android, Web, Desktop Task form open Enter valid/invalid cost strings Valid persisted; invalid blocked or sanitized Locale decimal separators Cost parsed to Double Automate
59 TASK-015 Tasks Task detail navigation Push/deep-link task navigation opens tasks tab and relevant task context Manual + E2E UI P0 iOS, Android App receives task navigation ID Tap notification/open intent Tasks tab selected and task reachable Task deleted before open Main shell handles navigate_to_task contract Automate
60 TASK-016 Tasks Bulk state refresh After any task CRUD/action, summary cards refresh immediately Manual + Integration P1 iOS, Android, Web, Desktop Dashboard visible with summaries Perform task action Summary counts update without hard reload Rapid consecutive actions Summary derived from cached kanban Automate
61 TASK-017 Tasks Concurrency Two users edit same task; conflict resolution UX Manual P2 iOS, Android, Web, Desktop Same task open on two accounts Save conflicting edits Consistent final state and clear error/last-write behavior Out-of-order responses Server conflict strategy documented Manual
62 TCOMP-001 Task completion Complete task basic Complete task with notes/cost/rating Manual + E2E UI P0 iOS, Android, Web, Desktop Active task exists Open complete flow and submit Completion created and task column updates Null rating vs default value Completion endpoint accepts optional fields Automate
63 TCOMP-002 Task completion Complete with images Attach one or multiple images during completion Manual + Integration P0 iOS, Android Camera/gallery permission granted Submit completion with images Images uploaded and linked to completion Large image compression/failure mid-upload Image compression and multipart upload enabled Automate partially
64 TCOMP-003 Task completion Validation Required completed-by field enforced (iOS form state) Manual + UI P1 iOS Open complete task form Submit blank completed-by Validation error shown Whitespace-only value CompletedBy required by client form Automate
65 TCOMP-004 Task completion Completion history History list loads for task and sorted correctly Manual + Integration P1 iOS, Android, Web, Desktop Task with multiple completions Open completion history Entries ordered and accurate Missing images in older completion records History endpoint returns full list Automate
66 DOC-001 Documents List Load all documents and residence-filtered documents Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in with docs data Open documents tab and residence detail docs Correct sets shown Residence with zero docs List supports optional residence filter Automate
67 DOC-002 Documents Create document Create generic document with required fields Manual + E2E UI P0 iOS, Android, Web, Desktop Residence exists Create document with title/type/residence Document appears in lists Missing residence selection on create Create requires title/type/residence Automate
68 DOC-003 Documents Create warranty fields Create warranty/appliance with provider/dates metadata Manual + Integration P1 iOS, Android, Web, Desktop Document form open Enter warranty-specific fields and save Fields persist and render in detail End date before start date Date validation expectations defined Automate
69 DOC-004 Documents Edit document Edit existing document including type/category/tags Manual + E2E UI P1 iOS, Android, Web, Desktop Document exists Modify and save Detail/list reflect updates Switching types with stale fields Backend accepts partial update Automate
70 DOC-005 Documents Delete document Delete removes from global and residence caches Manual + Integration P0 iOS, Android, Web, Desktop Document exists in caches Delete document Document removed everywhere Delete while detail screen open DataManager removeDocument updates both caches Automate
71 DOC-006 Documents Upload image Upload document image from camera/gallery Manual + Integration P0 iOS, Android Permissions granted Add image to document Thumbnail and full image accessible Upload timeout Upload endpoint returns image metadata Automate partially
72 DOC-007 Documents Delete image Delete specific document image updates detail immediately Manual + Integration P1 iOS, Android, Web, Desktop Document with multiple images Delete one image Remaining images preserved Deleting last image Image delete endpoint idempotency Automate
73 DOC-008 Documents Download Download/open document file via URL Manual P1 iOS, Android, Web, Desktop Document has downloadable URL Tap download/open File retrieved and usable Expired signed URL Download API wraps binary result Automate partially
74 DOC-009 Documents Validation Claim email optional but must be valid if provided Manual + UI P2 iOS Document form open Enter invalid claim email Validation error shown Internationalized domains Email regex defines valid format Automate
75 DOC-010 Documents Media viewer Image viewer navigation, zoom, swipe, close behavior Manual P2 iOS, Android Document with multiple images Open viewer and interact No crashes; correct index and gestures Very large images Viewer supports list index initialization Manual
76 CON-001 Contractors List Load contractors with empty and populated states Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Open contractors tab List/empty state correct Large list pagination if any API supports optional filters Automate
77 CON-002 Contractors Create Create contractor minimal required fields Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Create contractor with name Contractor appears in list/detail Special characters in names Name is required Automate
78 CON-003 Contractors Create optional data Persist optional company/contact/address/specialties Manual + Integration P1 iOS, Android, Web, Desktop Contractor form open Fill optional fields and save All values persist accurately Invalid website URL format Optional fields may be null Automate
79 CON-004 Contractors Email validation Optional email must be valid if supplied Manual + UI P1 iOS, Android, Web, Desktop Contractor form open Enter invalid email Validation error blocks save Uppercase email + spaces Validation trims and regex-checks Automate
80 CON-005 Contractors Edit Edit contractor and verify list/detail sync Manual + E2E UI P1 iOS, Android, Web, Desktop Existing contractor Update fields and save Updated across views Concurrent remote update DataManager updateContractor handles summary mapping Automate
81 CON-006 Contractors Delete Delete contractor removes from caches and residence associations Manual + Integration P0 iOS, Android, Web, Desktop Existing contractor Delete contractor Removed from all views Deleting favorite contractor Association cleanup server-side Automate
82 CON-007 Contractors Favorite toggle Toggle favorite updates UI and persistence Manual + E2E UI P1 iOS, Android, Web, Desktop Existing contractor Toggle favorite twice State toggles correctly and persists refresh Rapid repeated taps Endpoint supports idempotent toggles Automate
83 CON-008 Contractors By residence filter Load contractors scoped to residence Manual + Integration P1 iOS, Android, Web, Desktop Multiple residences and linked contractors Open residence contractor section Only related contractors shown Contractor with null residence Filtering done server-side Automate
84 CON-009 Contractors Share export Share contractor as .casera file Manual P1 Android Contractor exists Tap share contractor Share sheet opens with valid file payload Name containing '/' and long length Filename sanitization applied Manual
85 CON-010 Contractors Import .casera Import contractor from valid file Manual + Integration P0 Android Logged in, valid contractor file Open file/import confirm Contractor created and success dialog shown Unknown specialty names in file Specialties mapped by name to known IDs Automate partially
86 CON-011 Contractors Import invalid file Invalid extension/JSON/auth state handled safely Manual P0 Android Invalid file or logged out Attempt import Clear error shown; no partial creation Huge malformed JSON Import parser errors are surfaced Manual
87 NOTIF-001 Notifications Permission prompt Notification permission request outcomes handled Manual P0 iOS, Android Fresh install Respond Allow and Deny in separate runs App continues gracefully; state reflects permission User changes setting later Permission checked on foreground Manual
88 NOTIF-002 Notifications Device registration Register device token after login only Manual + Integration P0 iOS, Android Have APNs/FCM token Login with token available registerDevice called once and succeeds Token arrives before auth Auth gating prevents unauthenticated registration Automate
89 NOTIF-003 Notifications Token refresh New push token triggers backend re-registration Manual + Integration P1 iOS, Android Previously registered token Simulate token rotation Backend receives updated registration id No token change should skip call Last registered token cache used Automate
90 NOTIF-004 Notifications Foreground notification Foreground notifications display banner/sound and update read state Manual P1 iOS, Android Permission granted, send test push Receive push while app active Banner shown; notification handled Malformed payload missing type Foreground presentation explicitly enabled Manual
91 NOTIF-005 Notifications Notification tap navigation Tap task push opens app and routes to tasks context Manual + E2E P0 iOS, Android Task-linked push sent Tap push from background/terminated App opens on tasks flow for target task Task no longer exists Task id may be string or int Automate partially
92 NOTIF-006 Notifications Action buttons premium Premium users see and can execute task action buttons Manual + Integration P0 iOS, Android Premium subscription active Receive actionable task notification, tap action Action API executes and UI refreshes Action timeout/network loss Actions gated by premium/limitationsEnabled Manual
93 NOTIF-007 Notifications Action buttons free-tier gating Free users with limitations enabled are routed home/not allowed actions Manual P0 iOS, Android Free user limitationsEnabled=true Tap actionable notification No privileged task action executed Subscription cache stale nil Nil subscription defaults allow on iOS currently Manual
94 NOTIF-008 Notifications Preferences Load and update notification preference toggles Manual + Integration P1 iOS, Android, Web, Desktop Logged in Open notification preferences, toggle settings, save Preferences persist and affect server payloads Partial update failures Preferences API supports patch/update Automate
95 NOTIF-009 Notifications History/read state Notification history list and mark-read operations Manual + Integration P2 iOS, Android, Web, Desktop Notifications exist Open history, mark one and mark all Unread counts decrement correctly Race with incoming push Unread count endpoint consistent Automate
96 SUB-001 Subscription Status load Subscription status loads at app launch/foreground Manual + Integration P0 iOS, Android, Web, Desktop Logged in Launch then background/foreground app Status cache updates and UI gating accurate Backend temporarily unavailable Status refresh should be non-fatal Automate
97 SUB-002 Subscription Upgrade screen products Load purchasable plans and pricing Manual P0 iOS, Android Store config present Open upgrade screen Monthly/annual products displayed Store connectivity issues Product IDs configured as expected Manual + mocked automation
98 SUB-003 Subscription Purchase monthly Complete monthly purchase and backend verification Manual + Integration P0 iOS, Android Sandbox account, product available Buy monthly plan Entitlement granted, subscription status becomes pro Pending transactions Verification endpoint must return success Manual
99 SUB-004 Subscription Purchase annual Complete annual purchase and backend verification Manual + Integration P0 iOS, Android Sandbox account Buy annual plan Entitlement granted and reflected in app Upgrade/downgrade from existing plan Latest transaction determines tier Manual
100 SUB-005 Subscription Restore purchases Restore on clean install/device migration Manual + Integration P0 iOS, Android Existing prior subscription Tap restore Entitlements restored and backend synced No previous purchases Restore should not duplicate grants Manual
101 SUB-006 Subscription Purchase cancellation User-cancelled purchase does not show fatal error Manual P1 iOS, Android Open paywall Start then cancel purchase No entitlement changes; UX remains stable Repeated cancel attempts User cancel considered non-error Manual
102 SUB-007 Subscription Backend verification failure Store purchase succeeds but backend verify fails Manual P0 iOS, Android Force backend verify failure Complete purchase User sees recoverable state and can retry/restore Receipt parsing mismatch App should avoid false pro unlock Manual
103 SUB-008 Subscription Feature gating Pro-only features hidden/disabled for limited users Manual + E2E P0 iOS, Android, Web, Desktop Test free and pro accounts Traverse gated features (actions, limits, upgrades) Gating consistent across surfaces Cache stale after plan change Gating uses subscription status + limitationsEnabled Automate
104 WID-001 Widgets Small widget rendering Small widget shows counts and opens app Manual P1 Android Widget added, logged in Place small widget and tap Correct counts; tap opens app No data cached yet Widget reads from shared preferences state Manual
105 WID-002 Widgets Medium widget list Medium widget shows top tasks and overdue badge Manual P1 Android Tasks exist Place medium widget Task rows and overdue badge correct Malformed tasks_json JSON parse fallback to empty list Manual
106 WID-003 Widgets Large widget interactions Large widget actions execute for pro users Manual + Integration P0 Android Pro account, widget configured Tap row and action controls Opens task or executes action as expected Free user should not see/execute pro actions Widget passes task_id in intent Manual
107 WID-004 Widgets Widget refresh Widgets refresh after task state changes Manual P1 Android Widget present Complete/cancel task in app Widget counts/list update within expected interval Background restrictions Widget update manager triggers refresh Manual
108 SHR-001 Sharing/Import File association .casera files open app import flow Manual P1 Android Have .casera file Open file from files app/share sheet Import confirmation dialog shown Multiple apps can open same MIME Intent filter handles application/json with extension Manual
109 SHR-002 Sharing/Import Security Import rejects when unauthenticated Manual P0 Android Logged out, .casera file ready Attempt import Error shown, no data mutation Stale token in storage Auth check occurs before API call Manual
110 SHR-003 Sharing/Import Corrupt payload Corrupt .casera payload fails safely without crash Manual P0 Android Malformed JSON file Attempt import Graceful error dialog Very large payload Parser exceptions are caught Manual
111 DATA-001 Data layer Lookups init Seeded lookup data loads once and marks initialized Manual + Integration P0 iOS, Android, Web, Desktop Fresh login Observe first data bootstrap Lookups available for forms/templates Slow network during bootstrap initializeLookups has concurrency guard Automate
112 DATA-002 Data layer ETag refresh Lookup refresh uses ETag and handles 304 not modified Manual + Integration P1 iOS, Android, Web, Desktop Lookups already loaded + ETag Foreground app or force refresh No unnecessary data churn on 304 ETag lost between sessions ETag persisted in storage Automate
113 DATA-003 Data layer Legacy fallback If seeded-data endpoint fails, fallback static data path works Manual + Integration P1 iOS, Android, Web, Desktop Mock seeded endpoint failure Initialize lookups Core lookups still available Templates missing in fallback Fallback endpoint still reachable Automate
114 DATA-004 Data layer Cache timeout One-hour cache timeout triggers fresh fetch after expiry Manual + Integration P1 iOS, Android, Web, Desktop Cached data older/newer than timeout Request data with forceRefresh=false Valid cache reused; stale cache refetched Clock skew/device time changes Timeout constant is 3600000 ms Automate
115 DATA-005 Data layer Cache invalidation on logout Logout clears user data/cache/ETag but retains theme Manual + Integration P0 iOS, Android, Web, Desktop Logged in with populated data Logout then inspect next launch No user data remains; theme preference retained Persistence clear implementation drift Theme stored separately from persistenceManager.clear Automate
116 DATA-006 Data layer Disk persistence Current user and lookups reload correctly after app restart Manual + Integration P1 iOS, Android, Web, Desktop Logged in and data loaded Kill and relaunch app State restored without full refetch where valid Partial/corrupt persisted JSON Deserializer ignoreUnknownKeys is enabled Automate
117 DATA-007 Data layer Map/list consistency Lookup map IDs and list values remain consistent after updates Unit + Integration P2 iOS, Android, Web, Desktop Lookup update operation Compare list and map representations No missing or mismatched IDs Duplicate IDs from backend Maps are built via associateBy(id) Automate
118 OFF-001 Resilience Offline launch Offline launch with cached token/data behaves gracefully Manual P0 iOS, Android, Web, Desktop Previously logged in with cached data Launch with network off No crash; clear messaging; cached UI where possible Token validation cannot reach server Current behavior may clear session on fetch failure Manual
119 OFF-002 Resilience Offline action handling Create/update actions fail with retriable errors when offline Manual P0 iOS, Android, Web, Desktop Network disabled Attempt create/edit/delete flows Errors shown; no phantom local success Intermittent network flaps No offline queue currently assumed Manual
120 OFF-003 Resilience Retry behavior Retry from error dialogs succeeds without stale UI state Manual + E2E P1 iOS, Android, Web, Desktop Force transient API failure Tap retry then restore network Action succeeds and loading/error states reset Double-tap retry race ApiResult state machine handles Idle/Loading/Error Automate
121 OFF-004 Resilience Idempotency UX Double submit protection for create flows Manual + UI P1 iOS, Android, Web, Desktop Open any create form Rapid tap save Single record created Very slow API response Buttons disabled during loading Automate
122 SEC-001 Security Auth boundaries Protected endpoints reject without token and UI handles 401 Manual + Integration P0 iOS, Android, Web, Desktop No token Attempt protected operations Redirect/login prompt or clear error Token injected but expired APILayer checks token before API in many calls Automate
123 SEC-002 Security Session cleanup Sensitive data not accessible after logout and app restart Manual P0 iOS, Android, Web, Desktop Logged in then logout Force close and relaunch No protected screens/data accessible Widget still showing stale data Widget caches should be cleared on logout (iOS path) Manual
124 SEC-003 Security Import validation Imported files cannot execute code or break parser boundaries Manual P1 Android Craft malicious JSON payload Import payload App rejects safely, no crash Oversized strings, deep nesting Deserializer should throw and be caught Manual
125 SEC-004 Security PII exposure Logs and analytics avoid leaking sensitive credential values Manual + Code audit P1 iOS, Android, Web, Desktop Enable debug logging Run auth/payment flows No passwords/tokens in logs/events Third-party SDK auto-capture risk PostHog config reviewed Manual
126 PERF-001 Performance Cold start Startup time within target for logged-out and logged-in states Manual + Perf P1 iOS, Android Profile build with instrumentation Measure cold launch Meets agreed startup SLA Slow network path for verified user Auth check performs network call Automate perf
127 PERF-002 Performance Large data rendering Task/document/contractor lists remain responsive with large datasets Manual + Perf P1 iOS, Android, Web, Desktop Seed large dataset Scroll and interact lists No jank/crash; acceptable memory Thousands of items and images Virtualized list behavior depends on platform Manual + benchmarks
128 PERF-003 Performance Image handling Large image capture/upload/compression memory stability Manual + Perf P0 iOS, Android Use high-resolution photos Attach multiple images No OOM/crash; upload completes or fails gracefully Low-memory device ImageCompressor platform implementations are active Manual
129 PERF-004 Performance Background operations Foreground/resume refresh does not block UI thread Manual + Perf P2 iOS, Android App with valid session Background then foreground repeatedly UI remains interactive during refresh Concurrent refresh and navigation Lookups refresh runs async Manual
130 A11Y-001 Accessibility Basic semantics All primary controls have accessible labels/identifiers Manual P0 iOS, Android, Web, Desktop Screen reader on Traverse major flows Controls are announced clearly Custom components lacking labels Accessibility identifiers partly defined Manual + lint
131 A11Y-002 Accessibility Dynamic type Text scales correctly without clipping in key screens Manual P1 iOS, Android Large accessibility font settings Open forms/lists/dialogs Layout remains usable Long localized strings Design system supports flexible layout Manual
132 A11Y-003 Accessibility Keyboard navigation Tab/focus order valid on web/desktop forms Manual P1 Web, Desktop Hardware keyboard Navigate forms using keyboard only Logical focus traversal and visible focus states Modal dialogs focus trap Compose/web focus handling may differ Manual
133 A11Y-004 Accessibility Color contrast Theme variants meet minimum contrast requirements Manual + Tooling P1 iOS, Android, Web, Desktop Cycle themes Inspect text/icon contrast WCAG contrast thresholds met Error/success states on tinted backgrounds Multiple custom themes supported Manual + automated audit
134 I18N-001 Localization String coverage No missing keys/placeholders across supported locales Manual + Static check P1 iOS, Android, Web, Desktop Run app in each locale Traverse major screens No raw keys, no placeholder mismatches Pluralization and gender strings Locales include es/fr/de/it/ja/ko/nl/pt/zh etc. Automate (lint + screenshot)
135 I18N-002 Localization Layout expansion Long translations do not break onboarding/forms/buttons Manual P1 iOS, Android, Web, Desktop Switch to longest-string locale Review high-density screens No clipping/overlap RTL future locale support Current locales may be LTR only Manual
136 THEME-001 Theming Theme persistence Theme choice persists across app restarts Manual + Integration P1 iOS, Android, Web, Desktop Logged in or logged out Change theme then relaunch Selected theme reapplied Theme ID missing/corrupt in storage Theme stored separately from auth data Automate
137 THEME-002 Theming Theme switch live update Changing theme updates active screen without broken states Manual + UI P2 iOS, Android, Web, Desktop Open app on any tab Change theme in profile/settings Immediate UI recolor with legible components Transition while modal open Theme manager publishes updates Manual
138 NAV-001 Navigation Bottom tabs Residences/Tasks/Contractors/Documents tabs navigate and preserve expected state Manual + E2E UI P0 iOS, Android Logged in Switch tabs repeatedly Correct screens shown; no stuck navigation Push navigation then tab switch back Nested nav stacks differ per platform Automate
139 NAV-002 Navigation Back stack safety Back from details/forms returns to correct parent Manual + E2E UI P0 iOS, Android, Web, Desktop Navigate into detail/edit screens Use back gestures/buttons Parent state intact and refreshed as expected Direct deep-link entry without parent Saved-state refresh flags used in KMP nav Automate
140 NAV-003 Navigation Duplicate routes Avoid duplicate screen instances from repeated tap/navigation actions Manual P2 iOS, Android, Web, Desktop Rapidly tap nav actions Observe back stack and UI No duplicate stacking or loops Double tap race conditions NavHost popUpTo rules applied Manual
141 ANL-001 Analytics Auth events Login/register/logout/verify events fire once with correct properties Manual + Integration P2 iOS, Android Analytics enabled in test env Perform auth flows Expected events emitted once Retries causing duplicate events Event taxonomy defined in analytics layer Automate with mocked sink
142 ANL-002 Analytics Core feature events Residence/task/document/contractor create-edit-delete events tracked Manual + Integration P2 iOS, Android Analytics test workspace Perform CRUD actions Events mapped to correct feature Failed actions should not emit success PostHog wrappers used consistently Automate
143 ANL-003 Analytics Subscription events Upgrade prompt open, purchase, restore, verification outcomes tracked Manual + Integration P2 iOS, Android Store sandbox + analytics Run subscription flows Lifecycle events present and correctly attributed Purchase canceled path No sensitive receipt data in events Manual
144 QA-001 Cross-platform parity Feature parity Core flows behave equivalently between KMP UI and iOS native UI Manual regression P0 iOS, Android, Web, Desktop Same seeded account Run same scenarios on each platform Equivalent outcomes and data integrity Known UX differences documented iOS native app is source for iOS UX Manual
145 QA-002 Cross-platform parity API contract consistency All clients handle new/unknown JSON fields gracefully Integration P1 iOS, Android, Web, Desktop Backend adds extra fields Run major endpoints No crash; fields ignored where unknown Type changes breaking parsing Kotlin serializers set ignoreUnknownKeys Automate
146 QA-003 Release quality Smoke suite Minimal release gate across auth, residence, task, document, contractor, notification, subscription Manual + Automated P0 iOS, Android Release candidate build Run smoke checklist No blockers before release Environment instability Smoke should run against stable test backend Automate + manual signoff
147 QA-004 Release quality Data migration Upgrade app version preserves critical local state safely Manual P1 iOS, Android, Web, Desktop Install old build with data then upgrade Launch and use app No corruption; expected resets only Schema/key changes in persistence Persistence keys remain compatible Manual

View File

@@ -0,0 +1,147 @@
"Test_ID","Domain","Feature","Scenario","Test_Method","Priority","Platforms","Preconditions","Steps","Expected_Result","Edge_Cases","Assumptions","Automation_Recommendation","automated"
"AUTH-001","Authentication","App start routing","First launch routes to onboarding when hasCompletedOnboarding=false","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Fresh install, no token","Launch app","Onboarding welcome is shown, not login/main tabs","Corrupted local onboarding flag","Onboarding state is persisted locally","Automate (UI smoke)","🟢 testF001_ColdLaunchShowsOnboardingWelcome"
"AUTH-002","Authentication","App start routing","Returning user with onboarding complete and no token routes to login","Manual + E2E UI","P0","iOS, Android, Web, Desktop","hasCompletedOnboarding=true, token missing","Launch app","Login screen shown","Stale cached user object present","Token is source of truth","Automate","🟢 testAppLaunchesAndShowsLoginScreen"
"AUTH-003","Authentication","App start routing","Authenticated + verified user routes to main tabs","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Valid token, verified user","Launch app","Main tab shell displayed","Cached token exists but API fails","Current-user fetch determines validity","Automate","🟢 testR203_validLoginTransitionsToMainAppRoot"
"AUTH-004","Authentication","App start routing","Authenticated but unverified user routes to verify email","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Valid token, verified=false","Launch app","Verify email screen shown","User gets verified between launches","Verification status fetched from backend","Automate","🟢 testR104_verificationGateBlocksMainAppBeforeCodeEntry | testR110_relaunchUnverifiedUserNeverLandsInMainApp"
"AUTH-005","Authentication","Token invalidation","Invalid token at startup clears session and returns to login","Manual + Integration","P0","iOS, Android, Web, Desktop","Expired/invalid token stored","Launch app","Data cleared and login shown","Backend 500 vs 401 behavior","401/failed current-user means logout","Automate","🟢 test08_invalidatedTokenRedirectsToLogin"
"AUTH-006","Authentication","Login","Valid username/password login success","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Existing verified account","Submit login form","Token persisted, lookups initialized, main shown","Slow network during login","Login API returns token+user","Automate","🟢 test02_loginWithValidCredentials | testR202_validCredentialsSubmitFromLogin"
"AUTH-007","Authentication","Login","Invalid credentials shows actionable error","Manual + E2E UI","P0","iOS, Android, Web, Desktop","No session","Submit wrong password","Error shown, user remains on login","Rate-limit or lockout responses","Error parser maps backend errors","Automate","🟢 test01_loginWithInvalidCredentials"
"AUTH-008","Authentication","Login validation","Empty username/password blocked client-side","Manual + UI","P1","iOS, Android, Web, Desktop","No session","Tap login with empty fields","Validation errors shown, no API call","Whitespace-only input","Client validation active","Automate","🟢 testF205_LoginButtonDisabledWhenCredentialsAreEmpty | testF207_LoginScreenShowsAllExpectedElements | testF208_RegisterFormShowsAllRequiredFields"
"AUTH-009","Authentication","Registration","Create account success then verify-email step","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Unique email/username","Submit valid registration","Session established and verify-email screen appears","Existing email conflict","Register API auto-authenticates","Automate","🟢 testR103_successfulRegistrationTransitionsToVerificationGate"
"AUTH-010","Authentication","Registration validation","Invalid email/password formats rejected","Manual + UI","P1","iOS, Android, Web, Desktop","No session","Try invalid email, short password, weak password","User-friendly validation errors","Unicode emails, long usernames","Validation rules are enforced consistently","Automate","🟢 test03_registrationWithEmptyFields | test04_registrationWithInvalidEmail | test06_registrationWithWeakPassword"
"AUTH-011","Authentication","Email verification","Valid 6-digit code verifies account","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged-in unverified user","Enter 6-digit numeric code","Account marked verified and app routes forward","Code already used","Code must be exactly 6 digits","Automate","🟢 testR105_validVerificationCodeTransitionsToMainApp | test07_successfulRegistrationAndVerification"
"AUTH-012","Authentication","Email verification","Non-numeric/short/long code blocked","Manual + UI","P1","iOS, Android, Web, Desktop","On verify-email screen","Enter invalid codes","Verify action disabled or error shown","Pasted with spaces","Code input sanitizes to digits","Automate","🟢 testR107_invalidVerificationCodeShowsErrorAndStaysBlocked | testR109_verifyButtonDisabledForIncompleteCode | test10_verificationCodeFieldValidation"
"AUTH-013","Authentication","Logout","Logout clears token, user data, lookups, and returns to login","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Tap logout","Login shown; protected API calls fail without token","Logout API fails network-side","Client clears state even if API call fails","Automate","🟢 test06_logout | testR205_logoutFromMainAppReturnsToLoginRoot"
"AUTH-014","Authentication","Forgot password","Request reset by email success path","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Known account email","Submit forgot-password email","Success message and next step available","Unknown email behavior privacy-safe","Backend may still return generic success","Automate","🟢 test05_forgotPasswordNavigation | testF206_ForgotPasswordButtonIsAccessible | testF209_ForgotPasswordNavigatesToResetFlow"
"AUTH-015","Authentication","Reset code verification","Verify reset code success path","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Reset email submitted","Enter correct code","Reset-token available for password reset","Expired code","Code verification endpoint returns token","Automate","🟢 test03_verifyResetCodeSuccess"
"AUTH-016","Authentication","Password reset","Reset password success with matching confirmation","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Valid reset token","Enter new password + confirm","Password changed; user can log in (or auto-login flow)","Token expires mid-flow","Reset endpoint ignores confirm field","Automate","🟢 test04_resetPasswordSuccessAndLogin"
"AUTH-017","Authentication","Password reset","Mismatched password confirmation blocked","Manual + UI","P1","iOS, Android, Web, Desktop","Reset password screen","Enter mismatch","Inline error; no reset request","Trailing spaces","Client validates before submit","Automate","🟢 mismatchedPasswordsFails | caseSensitiveMismatchFails (ValidationHelpersTests)"
"AUTH-018","Authentication","Deep link reset","Password-reset deep link opens flow with token prefilled","Manual + E2E UI","P0","iOS, Android","Installed app with deep-link support","Open reset deep link","Forgot/reset flow opens and token is consumed","Malformed token in URL","Deep link token can be cleared on back","Automate",""
"AUTH-019","Authentication","SSO Apple","Apple Sign-In success creates or signs in account","Manual + Integration","P1","iOS","Apple-capable test device/simulator","Complete Apple sign-in","Session established; verification state handled","User hides email, first-login only email scope","Apple credential mapped to backend request","Automate partially (mock)",""
"AUTH-020","Authentication","SSO Google","Google Sign-In success path","Manual + Integration","P1","Android, Web, KMP UI","Google sign-in configured","Complete Google sign-in","Session established with backend token","Revoked Google token","Backend validates ID token","Automate partially",""
"ONB-001","Onboarding","Intent split","Start Fresh path goes through value props and name residence","Manual + E2E UI","P0","iOS, Android (KMP)","Fresh install","Choose Start Fresh and continue","Step order matches intended flow","Back navigation at each step","Flow differs by intent","Automate","🟢 testF101_StartFreshFlowReachesCreateAccount | testR002_startFreshFlowReachesCreateAccount"
"ONB-002","Onboarding","Intent split","Join Existing path skips value/name steps and goes to account creation","Manual + E2E UI","P0","iOS, Android (KMP)","Fresh install","Choose Join Existing","Expected condensed step order","User switches intent mid-flow","Intent persisted during onboarding","Automate","🟢 testF102_JoinExistingFlowGoesToCreateAccount | testF105_JoinExistingFlowSkipsValuePropsAndNameResidence"
"ONB-003","Onboarding","Navigation","Back button transitions and step history correctness","Manual + UI","P1","iOS, Android (KMP)","In onboarding multi-step flow","Navigate forward then back","Returns to correct previous step","Back from verify-email triggers logout on iOS","Back behavior is product-defined","Automate","🟢 testF103_BackNavigationFromNameResidenceReturnsToValueProps | testF108_BackFromCreateAccountNavigatesToPreviousStep"
"ONB-004","Onboarding","Skip behavior","Skippable screens skip to next valid state","Manual + UI","P1","iOS, Android (KMP)","On skippable step","Tap Skip","Progress advances without corrupting state","Skip on terminal upsell step completes onboarding","Skip availability is step-dependent","Automate","🟢 testF104_SkipOnValuePropsMovesToNameResidence"
"ONB-005","Onboarding","Residence bootstrap","Start Fresh creates residence automatically after verification","Manual + Integration","P0","iOS, Android (KMP)","Onboarding start-fresh with residence name","Verify email and continue","Residence created or graceful fallback if creation fails","Blank residence name bypasses creation","Creation failure should not hard-block onboarding","Automate","🟢 testF110_startFreshCreatesResidenceAfterVerification"
"ONB-006","Onboarding","Join residence","Join-existing flow joins via share code","Manual + E2E UI","P0","iOS, Android (KMP)","Valid join code","Submit code in onboarding","User added to shared residence","Expired/invalid/reused code","Join code endpoint enforces ownership rules","Automate",""
"ONB-007","Onboarding","First task","First-task onboarding step can create selected tasks","Manual + Integration","P1","iOS, Android (KMP)","On first-task step","Select templates and continue","Tasks created; flow proceeds","Partial task creation failures","At least one success considered success in KMP VM","Automate",""
"ONB-008","Onboarding","Completion persistence","Completing onboarding persists flag and bypasses onboarding next launch","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Completed onboarding once","Restart app","Onboarding is skipped","App data clear resets flag","Onboarding flag stored locally","Automate","🟢 testF111_completedOnboardingBypassedOnRelaunch"
"RES-001","Residences","List","Residences list loads with empty and non-empty states","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Open residences tab","Correct list/empty UI shown","Slow API and stale cache","List can come from cache or network","Automate","🟢 test01_viewResidencesList | testR303_residencesListLoadsAfterTabSelection"
"RES-002","Residences","Create","Create residence with required fields only","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Fill minimum fields and save","Residence appears in list/detail","Duplicate name allowed/not allowed behavior","Name required; other fields optional","Automate","🟢 test05_createResidenceWithMinimalData | testR306_createResidenceMinimalDataSubmitsSuccessfully"
"RES-003","Residences","Create validation","Prevent submit when required name missing","Manual + UI","P1","iOS, Android, Web, Desktop","Open add residence form","Submit blank name","Validation error, no API call","Whitespace-only name","Required validation trims input","Automate","🟢 test01_cannotCreateResidenceWithEmptyName"
"RES-004","Residences","Create optional fields","All optional numeric/text/address fields persist correctly","Manual + Integration","P1","iOS, Android, Web, Desktop","Open add residence form","Fill all fields and save","Values round-trip correctly in detail/edit","Decimals for bathrooms/lot size","Type conversion preserves precision","Automate","🟢 test12_updateAllResidenceFields"
"RES-005","Residences","Edit","Edit residence updates list and detail views","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Existing residence","Modify fields and save","Updated values shown immediately","Concurrent edit from another user","DataManager updates local caches","Automate","🟢 test11_editResidenceName | test12_updateAllResidenceFields"
"RES-006","Residences","Delete","Delete residence removes related task/document cached subsets","Manual + Integration","P0","iOS, Android, Web, Desktop","Residence with tasks/docs exists","Delete residence","Residence gone; related cached sections removed","Delete primary/only residence","Server cascade semantics documented","Automate","🟢 test02_residenceCRUDFlow"
"RES-007","Residences","Primary residence","Set/retain primary residence behavior","Manual","P2","iOS, Android, Web, Desktop","Multiple residences","Mark one as primary and reload","Only intended residence is primary","Two rapid primary updates","Backend enforces uniqueness","Automate partially","🟢 test18_setPrimaryResidence"
"RES-008","Residences","Summary","Residence summary counts derive from kanban columns correctly","Manual + Integration","P1","iOS, Android, Web, Desktop","Residence with mixed task statuses","Open summary cards","Counts match task column truth","No tasks state","Summary can be client-computed","Automate","🟢 test09_fullFlowSummary | test06_verifyKanbanStructure"
"RES-009","Residences","Join by code","Join residence from manual share code entry","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Valid share code from another account","Enter code in join flow","Membership granted and residence appears","Code expired or already member","Join endpoint returns reasoned errors","Automate",""
"RES-010","Residences","Generate share code","Generate/refresh residence share code","Manual + Integration","P1","iOS, Android, Web, Desktop","Owner access to residence","Generate code","New valid code returned/visible","Repeated generation invalidates old codes","Access limited by role","Automate","🟢 test07_residenceSharingUIElements"
"RES-011","Residences","Share package export","Create residence .casera package and open share sheet","Manual","P1","Android","Residence exists, logged in","Tap share residence","Share sheet opens with file attachment","Filename sanitization with special chars","Backend generates package with shareCode","Automate partially",""
"RES-012","Residences","Share package import","Import .casera residence file joins residence","Manual + Integration","P0","Android","Valid .casera file received","Open file via app/import handler and confirm","Join succeeds and success dialog shown","Invalid JSON/wrong extension/no auth","Import requires auth and parse success","Automate partially",""
"RES-013","Residences","Task report","Generate residence tasks report with/without email","Manual + Integration","P2","iOS, Android, Web, Desktop","Residence exists","Trigger generate report","Report creation success feedback","Invalid email format optional field","Backend handles async report generation","Automate",""
"RES-014","Residences","Manage users view","Residence users list loads with owner/member roles","Manual + E2E UI","P1","iOS, Android (KMP)","Residence with multiple users","Open manage users","Accurate users and role indicators displayed","Owner missing from response","Role data trusted from API","Automate",""
"RES-015","Residences","Remove user","Owner removes a member successfully","Manual + Integration","P0","iOS, Android (KMP)","Owner logged in, target member exists","Remove member","Member removed and state refreshes","Attempt remove self/owner","API enforces permission rules","Automate",""
"TASK-001","Tasks","All tasks load","Kanban columns load for all residences","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in with at least one residence","Open tasks tab","Columns and counts render correctly","Zero tasks across all columns","Columns include overdue/in-progress/due-soon/upcoming/completed/cancelled","Automate","🟢 test03_viewTasksList"
"TASK-002","Tasks","Residence filtering","Tasks by residence uses filtered allTasks cache correctly","Manual + Integration","P1","iOS, Android, Web, Desktop","Multiple residences with tasks","Open residence detail tasks","Only selected residence tasks shown","Residence cache stale while global cache fresh","Client-side filtering path exists","Automate","🟢 test07_residenceDetailsShowTasks"
"TASK-003","Tasks","Create task","Create minimal valid task","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Residence exists, lookups loaded","Submit task with required fields","Task appears in expected column","Missing lookups due to failed seed load","Category/frequency/priority are required","Automate","🟢 test03_createTaskWithMinimalData | test06_createBasicTask"
"TASK-004","Tasks","Create from template","Create task from template browser","Manual + E2E UI","P1","iOS, Android, Web, Desktop","Templates available","Open templates, select one, save","Task prefilled and created","Template with long description/tags","Template data from seeded lookups","Automate","🟢 test16_createTaskFromTemplate"
"TASK-005","Tasks","Template search","Search templates requires >=2 chars and limits results","Manual + Unit","P2","iOS, Android, Web, Desktop","Templates loaded","Search with 1 char then 2+ chars","1 char returns empty, 2+ filtered max 10","Case-insensitive tag match","Search is local in DataManager","Automate","🟢 searchWithSingleCharReturnsEmpty | searchWithTwoCharsMatchesTitles | searchIsCaseInsensitive | searchMatchesDescription | searchMatchesTags | searchReturnsMaxTenResults | emptyQueryReturnsEmpty (TemplateSearchTests)"
"TASK-006","Tasks","Edit task","Edit task fields and persist updates","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Existing task","Change title/category/frequency/priority/due/cost","Task updates and remains consistent in caches","Invalid cost string conversion","Edit route passes serialized fields","Automate","🟢 test09_editTaskTitle | test10_updateAllTaskFields"
"TASK-007","Tasks","Mark in progress","Transition task to in-progress column","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Existing non-in-progress task","Tap mark in progress","Task moves to in-progress column","Already in progress idempotency","UpdateTask uses kanbanColumn target","Automate","🟢 test03_taskStateTransitions"
"TASK-008","Tasks","Clear in progress","Clear in-progress state returns task to scheduled column","Manual + Integration","P1","iOS, Android, Web, Desktop","Task currently in progress","Clear in-progress","Task leaves in-progress with correct new column","Due date past while clearing","Backend decides target column","Automate","🟢 test03_taskStateTransitions"
"TASK-009","Tasks","Cancel task","Cancel action moves task to cancelled state","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Active task exists","Cancel task","Task appears in cancelled column/state","Cancel already-cancelled task","Endpoint idempotency defined","Automate","🟢 test04_taskCancelOperation"
"TASK-010","Tasks","Uncancel task","Restore cancelled task to active lifecycle","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Cancelled task exists","Uncancel task","Task restored to appropriate column","Uncancel archived task","State transitions validated by API","Automate","🟢 test15_uncancelRestorescancelledTask"
"TASK-011","Tasks","Archive/unarchive","Archive hides task from active flow; unarchive restores","Manual + Integration","P1","iOS, Android, Web, Desktop","Task exists","Archive then unarchive","Visibility toggles correctly","Archived + cancelled combined states","Archive APIs available and cached updates propagate","Automate","🟢 test05_taskArchiveOperation"
"TASK-012","Tasks","Delete semantics","Task removal updates all cached columns and summaries","Manual + Integration","P1","iOS, Android, Web, Desktop","Task exists in cached data","Delete or server-remove task then refresh","Task absent in all views and counts updated","Task present in multiple cached views","DataManager removeTask updates all maps","Automate","🟢 allTasksIsNilAfterClear | removeTaskOnNilAllTasksIsNoOp | tasksByResidenceIsEmptyAfterClear (RemoveTaskTests)"
"TASK-013","Tasks","Due date handling","Past/now/future due dates map to correct columns","Manual + Integration","P1","iOS, Android, Web, Desktop","Tasks with boundary due dates","Load tasks around timezone boundaries","Kanban placement matches backend logic","DST transitions","Backend provides canonical kanban_column","Automate","🟢 test04_kanbanColumnDistribution | mixedTaskCategories (TaskMetricsTests)"
"TASK-014","Tasks","Cost fields","Estimated cost accepts numeric and rejects invalid formats","Manual + UI","P2","iOS, Android, Web, Desktop","Task form open","Enter valid/invalid cost strings","Valid persisted; invalid blocked or sanitized","Locale decimal separators","Cost parsed to Double","Automate","🟢 test04_createTaskWithAllFields"
"TASK-015","Tasks","Task detail navigation","Push/deep-link task navigation opens tasks tab and relevant task context","Manual + E2E UI","P0","iOS, Android","App receives task navigation ID","Tap notification/open intent","Tasks tab selected and task reachable","Task deleted before open","Main shell handles navigate_to_task contract","Automate",""
"TASK-016","Tasks","Bulk state refresh","After any task CRUD/action, summary cards refresh immediately","Manual + Integration","P1","iOS, Android, Web, Desktop","Dashboard visible with summaries","Perform task action","Summary counts update without hard reload","Rapid consecutive actions","Summary derived from cached kanban","Automate","🟢 test09_fullFlowSummary"
"TASK-017","Tasks","Concurrency","Two users edit same task; conflict resolution UX","Manual","P2","iOS, Android, Web, Desktop","Same task open on two accounts","Save conflicting edits","Consistent final state and clear error/last-write behavior","Out-of-order responses","Server conflict strategy documented","Manual",""
"TCOMP-001","Task completion","Complete task basic","Complete task with notes/cost/rating","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Active task exists","Open complete flow and submit","Completion created and task column updates","Null rating vs default value","Completion endpoint accepts optional fields","Automate","🟢 test03_taskLifecycleFlow"
"TCOMP-002","Task completion","Complete with images","Attach one or multiple images during completion","Manual + Integration","P0","iOS, Android","Camera/gallery permission granted","Submit completion with images","Images uploaded and linked to completion","Large image compression/failure mid-upload","Image compression and multipart upload enabled","Automate partially",""
"TCOMP-003","Task completion","Validation","Required completed-by field enforced (iOS form state)","Manual + UI","P1","iOS","Open complete task form","Submit blank completed-by","Validation error shown","Whitespace-only value","CompletedBy required by client form","Automate","🟢 completedByFieldRequired | completedByFieldWithValuePasses | completedByFieldWhitespaceOnlyFails (TaskCompletionValidationTests)"
"TCOMP-004","Task completion","Completion history","History list loads for task and sorted correctly","Manual + Integration","P1","iOS, Android, Web, Desktop","Task with multiple completions","Open completion history","Entries ordered and accurate","Missing images in older completion records","History endpoint returns full list","Automate","🟢 test10_completionHistoryLoadsAndIsSorted"
"DOC-001","Documents","List","Load all documents and residence-filtered documents","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in with docs data","Open documents tab and residence detail docs","Correct sets shown","Residence with zero docs","List supports optional residence filter","Automate","🟢 test01_NavigateToDocumentsScreen | test20_HandleEmptyDocumentsList | test21_HandleEmptyWarrantiesList"
"DOC-002","Documents","Create document","Create generic document with required fields","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Residence exists","Create document with title/type/residence","Document appears in lists","Missing residence selection on create","Create requires title/type/residence","Automate","🟢 test04_CreateDocumentWithMinimalFields"
"DOC-003","Documents","Create warranty fields","Create warranty/appliance with provider/dates metadata","Manual + Integration","P1","iOS, Android, Web, Desktop","Document form open","Enter warranty-specific fields and save","Fields persist and render in detail","End date before start date","Date validation expectations defined","Automate","🟢 test06_CreateWarrantyWithAllFields | test07_CreateWarrantyWithFutureDates | test08_CreateExpiredWarranty"
"DOC-004","Documents","Edit document","Edit existing document including type/category/tags","Manual + E2E UI","P1","iOS, Android, Web, Desktop","Document exists","Modify and save","Detail/list reflect updates","Switching types with stale fields","Backend accepts partial update","Automate","🟢 test15_EditDocumentTitle | test16_EditWarrantyDates"
"DOC-005","Documents","Delete document","Delete removes from global and residence caches","Manual + Integration","P0","iOS, Android, Web, Desktop","Document exists in caches","Delete document","Document removed everywhere","Delete while detail screen open","DataManager removeDocument updates both caches","Automate","🟢 test17_DeleteDocument | test18_DeleteWarranty"
"DOC-006","Documents","Upload image","Upload document image from camera/gallery","Manual + Integration","P0","iOS, Android","Permissions granted","Add image to document","Thumbnail and full image accessible","Upload timeout","Upload endpoint returns image metadata","Automate partially",""
"DOC-007","Documents","Delete image","Delete specific document image updates detail immediately","Manual + Integration","P1","iOS, Android, Web, Desktop","Document with multiple images","Delete one image","Remaining images preserved","Deleting last image","Image delete endpoint idempotency","Automate","🟢 test22_documentImageSectionExists"
"DOC-008","Documents","Download","Download/open document file via URL","Manual","P1","iOS, Android, Web, Desktop","Document has downloadable URL","Tap download/open","File retrieved and usable","Expired signed URL","Download API wraps binary result","Automate partially",""
"DOC-009","Documents","Validation","Claim email optional but must be valid if provided","Manual + UI","P2","iOS","Document form open","Enter invalid claim email","Validation error shown","Internationalized domains","Email regex defines valid format","Automate","🟢 validEmailPasses | invalidEmailMissingAtFails (ValidationHelpersTests + StringExtensionsTests)"
"DOC-010","Documents","Media viewer","Image viewer navigation, zoom, swipe, close behavior","Manual","P2","iOS, Android","Document with multiple images","Open viewer and interact","No crashes; correct index and gestures","Very large images","Viewer supports list index initialization","Manual",""
"CON-001","Contractors","List","Load contractors with empty and populated states","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Open contractors tab","List/empty state correct","Large list pagination if any","API supports optional filters","Automate","🟢 test16_refreshContractorsList"
"CON-002","Contractors","Create","Create contractor minimal required fields","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Logged in","Create contractor with name","Contractor appears in list/detail","Special characters in names","Name is required","Automate","🟢 test03_createContractorWithMinimalData"
"CON-003","Contractors","Create optional data","Persist optional company/contact/address/specialties","Manual + Integration","P1","iOS, Android, Web, Desktop","Contractor form open","Fill optional fields and save","All values persist accurately","Invalid website URL format","Optional fields may be null","Automate","🟢 test04_createContractorWithAllFields | test14_updateAllContractorFields"
"CON-004","Contractors","Email validation","Optional email must be valid if supplied","Manual + UI","P1","iOS, Android, Web, Desktop","Contractor form open","Enter invalid email","Validation error blocks save","Uppercase email + spaces","Validation trims and regex-checks","Automate","🟢 validEmailPasses | invalidEmailMissingAtFails | invalidEmailMissingDomainFails (ValidationHelpersTests + StringExtensionsTests)"
"CON-005","Contractors","Edit","Edit contractor and verify list/detail sync","Manual + E2E UI","P1","iOS, Android, Web, Desktop","Existing contractor","Update fields and save","Updated across views","Concurrent remote update","DataManager updateContractor handles summary mapping","Automate","🟢 test13_editContractorName | test14_updateAllContractorFields"
"CON-006","Contractors","Delete","Delete contractor removes from caches and residence associations","Manual + Integration","P0","iOS, Android, Web, Desktop","Existing contractor","Delete contractor","Removed from all views","Deleting favorite contractor","Association cleanup server-side","Automate","🟢 test08_contractorCRUD"
"CON-007","Contractors","Favorite toggle","Toggle favorite updates UI and persistence","Manual + E2E UI","P1","iOS, Android, Web, Desktop","Existing contractor","Toggle favorite twice","State toggles correctly and persists refresh","Rapid repeated taps","Endpoint supports idempotent toggles","Automate","🟢 test20_toggleContractorFavorite"
"CON-008","Contractors","By residence filter","Load contractors scoped to residence","Manual + Integration","P1","iOS, Android, Web, Desktop","Multiple residences and linked contractors","Open residence contractor section","Only related contractors shown","Contractor with null residence","Filtering done server-side","Automate","🟢 test21_contractorByResidenceFilter"
"CON-009","Contractors","Share export","Share contractor as .casera file","Manual","P1","Android","Contractor exists","Tap share contractor","Share sheet opens with valid file payload","Name containing '/' and long length","Filename sanitization applied","Manual",""
"CON-010","Contractors","Import .casera","Import contractor from valid file","Manual + Integration","P0","Android","Logged in, valid contractor file","Open file/import confirm","Contractor created and success dialog shown","Unknown specialty names in file","Specialties mapped by name to known IDs","Automate partially",""
"CON-011","Contractors","Import invalid file","Invalid extension/JSON/auth state handled safely","Manual","P0","Android","Invalid file or logged out","Attempt import","Clear error shown; no partial creation","Huge malformed JSON","Import parser errors are surfaced","Manual",""
"NOTIF-001","Notifications","Permission prompt","Notification permission request outcomes handled","Manual","P0","iOS, Android","Fresh install","Respond Allow and Deny in separate runs","App continues gracefully; state reflects permission","User changes setting later","Permission checked on foreground","Manual",""
"NOTIF-002","Notifications","Device registration","Register device token after login only","Manual + Integration","P0","iOS, Android","Have APNs/FCM token","Login with token available","registerDevice called once and succeeds","Token arrives before auth","Auth gating prevents unauthenticated registration","Automate",""
"NOTIF-003","Notifications","Token refresh","New push token triggers backend re-registration","Manual + Integration","P1","iOS, Android","Previously registered token","Simulate token rotation","Backend receives updated registration id","No token change should skip call","Last registered token cache used","Automate",""
"NOTIF-004","Notifications","Foreground notification","Foreground notifications display banner/sound and update read state","Manual","P1","iOS, Android","Permission granted, send test push","Receive push while app active","Banner shown; notification handled","Malformed payload missing type","Foreground presentation explicitly enabled","Manual",""
"NOTIF-005","Notifications","Notification tap navigation","Tap task push opens app and routes to tasks context","Manual + E2E","P0","iOS, Android","Task-linked push sent","Tap push from background/terminated","App opens on tasks flow for target task","Task no longer exists","Task id may be string or int","Automate partially",""
"NOTIF-006","Notifications","Action buttons premium","Premium users see and can execute task action buttons","Manual + Integration","P0","iOS, Android","Premium subscription active","Receive actionable task notification, tap action","Action API executes and UI refreshes","Action timeout/network loss","Actions gated by premium/limitationsEnabled","Manual",""
"NOTIF-007","Notifications","Action buttons free-tier gating","Free users with limitations enabled are routed home/not allowed actions","Manual","P0","iOS, Android","Free user limitationsEnabled=true","Tap actionable notification","No privileged task action executed","Subscription cache stale nil","Nil subscription defaults allow on iOS currently","Manual",""
"NOTIF-008","Notifications","Preferences","Load and update notification preference toggles","Manual + Integration","P1","iOS, Android, Web, Desktop","Logged in","Open notification preferences, toggle settings, save","Preferences persist and affect server payloads","Partial update failures","Preferences API supports patch/update","Automate",""
"NOTIF-009","Notifications","History/read state","Notification history list and mark-read operations","Manual + Integration","P2","iOS, Android, Web, Desktop","Notifications exist","Open history, mark one and mark all","Unread counts decrement correctly","Race with incoming push","Unread count endpoint consistent","Automate",""
"SUB-001","Subscription","Status load","Subscription status loads at app launch/foreground","Manual + Integration","P0","iOS, Android, Web, Desktop","Logged in","Launch then background/foreground app","Status cache updates and UI gating accurate","Backend temporarily unavailable","Status refresh should be non-fatal","Automate",""
"SUB-002","Subscription","Upgrade screen products","Load purchasable plans and pricing","Manual","P0","iOS, Android","Store config present","Open upgrade screen","Monthly/annual products displayed","Store connectivity issues","Product IDs configured as expected","Manual + mocked automation",""
"SUB-003","Subscription","Purchase monthly","Complete monthly purchase and backend verification","Manual + Integration","P0","iOS, Android","Sandbox account, product available","Buy monthly plan","Entitlement granted, subscription status becomes pro","Pending transactions","Verification endpoint must return success","Manual",""
"SUB-004","Subscription","Purchase annual","Complete annual purchase and backend verification","Manual + Integration","P0","iOS, Android","Sandbox account","Buy annual plan","Entitlement granted and reflected in app","Upgrade/downgrade from existing plan","Latest transaction determines tier","Manual",""
"SUB-005","Subscription","Restore purchases","Restore on clean install/device migration","Manual + Integration","P0","iOS, Android","Existing prior subscription","Tap restore","Entitlements restored and backend synced","No previous purchases","Restore should not duplicate grants","Manual",""
"SUB-006","Subscription","Purchase cancellation","User-cancelled purchase does not show fatal error","Manual","P1","iOS, Android","Open paywall","Start then cancel purchase","No entitlement changes; UX remains stable","Repeated cancel attempts","User cancel considered non-error","Manual",""
"SUB-007","Subscription","Backend verification failure","Store purchase succeeds but backend verify fails","Manual","P0","iOS, Android","Force backend verify failure","Complete purchase","User sees recoverable state and can retry/restore","Receipt parsing mismatch","App should avoid false pro unlock","Manual",""
"SUB-008","Subscription","Feature gating","Pro-only features hidden/disabled for limited users","Manual + E2E","P0","iOS, Android, Web, Desktop","Test free and pro accounts","Traverse gated features (actions, limits, upgrades)","Gating consistent across surfaces","Cache stale after plan change","Gating uses subscription status + limitationsEnabled","Automate",""
"WID-001","Widgets","Small widget rendering","Small widget shows counts and opens app","Manual","P1","Android","Widget added, logged in","Place small widget and tap","Correct counts; tap opens app","No data cached yet","Widget reads from shared preferences state","Manual",""
"WID-002","Widgets","Medium widget list","Medium widget shows top tasks and overdue badge","Manual","P1","Android","Tasks exist","Place medium widget","Task rows and overdue badge correct","Malformed tasks_json","JSON parse fallback to empty list","Manual",""
"WID-003","Widgets","Large widget interactions","Large widget actions execute for pro users","Manual + Integration","P0","Android","Pro account, widget configured","Tap row and action controls","Opens task or executes action as expected","Free user should not see/execute pro actions","Widget passes task_id in intent","Manual",""
"WID-004","Widgets","Widget refresh","Widgets refresh after task state changes","Manual","P1","Android","Widget present","Complete/cancel task in app","Widget counts/list update within expected interval","Background restrictions","Widget update manager triggers refresh","Manual",""
"SHR-001","Sharing/Import","File association",".casera files open app import flow","Manual","P1","Android","Have .casera file","Open file from files app/share sheet","Import confirmation dialog shown","Multiple apps can open same MIME","Intent filter handles application/json with extension","Manual",""
"SHR-002","Sharing/Import","Security","Import rejects when unauthenticated","Manual","P0","Android","Logged out, .casera file ready","Attempt import","Error shown, no data mutation","Stale token in storage","Auth check occurs before API call","Manual",""
"SHR-003","Sharing/Import","Corrupt payload","Corrupt .casera payload fails safely without crash","Manual","P0","Android","Malformed JSON file","Attempt import","Graceful error dialog","Very large payload","Parser exceptions are caught","Manual",""
"DATA-001","Data layer","Lookups init","Seeded lookup data loads once and marks initialized","Manual + Integration","P0","iOS, Android, Web, Desktop","Fresh login","Observe first data bootstrap","Lookups available for forms/templates","Slow network during bootstrap","initializeLookups has concurrency guard","Automate","🟢 test06_lookupDataAvailable | setTaskCategoriesPopulatesList | setTaskCategoriesBuildsMappedLookup | setTaskPrioritiesPopulatesListAndMap | setTaskFrequenciesPopulatesListAndMap | setResidenceTypesPopulatesListAndMap | setContractorSpecialtiesPopulatesListAndMap | markLookupsInitializedSetsFlag (DataLayerTests)"
"DATA-002","Data layer","ETag refresh","Lookup refresh uses ETag and handles 304 not modified","Manual + Integration","P1","iOS, Android, Web, Desktop","Lookups already loaded + ETag","Foreground app or force refresh","No unnecessary data churn on 304","ETag lost between sessions","ETag persisted in storage","Automate","🟢 staticDataEndpointReturnsETag | conditionalRequestReturns304WhenDataUnchanged | staleETagReturns200 (DataLayerETagTests)"
"DATA-003","Data layer","Legacy fallback","If seeded-data endpoint fails, fallback static data path works","Manual + Integration","P1","iOS, Android, Web, Desktop","Mock seeded endpoint failure","Initialize lookups","Core lookups still available","Templates missing in fallback","Fallback endpoint still reachable","Automate","🟢 staticDataContainsAllRequiredLookupTypes | allLookupItemsHaveIdAndName | taskCategoriesHaveColorAndIcon | taskPrioritiesHaveLevelAndColor (DataLayerAPISchemaTests)"
"DATA-004","Data layer","Cache timeout","One-hour cache timeout triggers fresh fetch after expiry","Manual + Integration","P1","iOS, Android, Web, Desktop","Cached data older/newer than timeout","Request data with forceRefresh=false","Valid cache reused; stale cache refetched","Clock skew/device time changes","Timeout constant is 3600000 ms","Automate","🟢 cacheTimeZeroIsInvalid | recentCacheTimeIsValid | expiredCacheTimeIsInvalid | cacheTimeoutConstantIsOneHour | allCacheTimestampsStartAtZeroAfterClear (DataLayerTests.CacheValidationTests)"
"DATA-005","Data layer","Cache invalidation on logout","Logout clears user data/cache/ETag but retains theme","Manual + Integration","P0","iOS, Android, Web, Desktop","Logged in with populated data","Logout then inspect next launch","No user data remains; theme preference retained","Persistence clear implementation drift","Theme stored separately from persistenceManager.clear","Automate","🟢 testR206_postLogoutMainAppIsNoLongerAccessible | clearResetsAllCacheTimestamps | clearEmptiesLookupLists | clearResetsLookupsInitializedFlag | clearUserDataKeepsLookups | clearUserDataResetsCacheTimestamps (DataLayerTests.ClearTests)"
"DATA-006","Data layer","Disk persistence","Current user and lookups reload correctly after app restart","Manual + Integration","P1","iOS, Android, Web, Desktop","Logged in and data loaded","Kill and relaunch app","State restored without full refetch where valid","Partial/corrupt persisted JSON","Deserializer ignoreUnknownKeys is enabled","Automate","🟢 test08_diskPersistencePreservesLookupsAfterRestart"
"DATA-007","Data layer","Map/list consistency","Lookup map IDs and list values remain consistent after updates","Unit + Integration","P2","iOS, Android, Web, Desktop","Lookup update operation","Compare list and map representations","No missing or mismatched IDs","Duplicate IDs from backend","Maps are built via associateBy(id)","Automate","🟢 setTaskCategoriesBuildsMappedLookup | getterReturnsNilForMissingId | getterReturnsNilForNilId | allIdsAreUniquePerLookupType (DataLayerTests.LookupSetterTests + DataLayerAPISchemaTests)"
"OFF-001","Resilience","Offline launch","Offline launch with cached token/data behaves gracefully","Manual","P0","iOS, Android, Web, Desktop","Previously logged in with cached data","Launch with network off","No crash; clear messaging; cached UI where possible","Token validation cannot reach server","Current behavior may clear session on fetch failure","Manual",""
"OFF-002","Resilience","Offline action handling","Create/update actions fail with retriable errors when offline","Manual","P0","iOS, Android, Web, Desktop","Network disabled","Attempt create/edit/delete flows","Errors shown; no phantom local success","Intermittent network flaps","No offline queue currently assumed","Manual",""
"OFF-003","Resilience","Retry behavior","Retry from error dialogs succeeds without stale UI state","Manual + E2E","P1","iOS, Android, Web, Desktop","Force transient API failure","Tap retry then restore network","Action succeeds and loading/error states reset","Double-tap retry race","ApiResult state machine handles Idle/Loading/Error","Automate","🟢 testP010_retryButtonExistsOnErrorState"
"OFF-004","Resilience","Idempotency UX","Double submit protection for create flows","Manual + UI","P1","iOS, Android, Web, Desktop","Open any create form","Rapid tap save","Single record created","Very slow API response","Buttons disabled during loading","Automate","🟢 test19_doubleSubmitProtection"
"SEC-001","Security","Auth boundaries","Protected endpoints reject without token and UI handles 401","Manual + Integration","P0","iOS, Android, Web, Desktop","No token","Attempt protected operations","Redirect/login prompt or clear error","Token injected but expired","APILayer checks token before API in many calls","Automate","🟢 test05_crossUserAccessControl"
"SEC-002","Security","Session cleanup","Sensitive data not accessible after logout and app restart","Manual","P0","iOS, Android, Web, Desktop","Logged in then logout","Force close and relaunch","No protected screens/data accessible","Widget still showing stale data","Widget caches should be cleared on logout (iOS path)","Manual","🟢 testR206_postLogoutMainAppIsNoLongerAccessible"
"SEC-003","Security","Import validation","Imported files cannot execute code or break parser boundaries","Manual","P1","Android","Craft malicious JSON payload","Import payload","App rejects safely, no crash","Oversized strings, deep nesting","Deserializer should throw and be caught","Manual",""
"SEC-004","Security","PII exposure","Logs and analytics avoid leaking sensitive credential values","Manual + Code audit","P1","iOS, Android, Web, Desktop","Enable debug logging","Run auth/payment flows","No passwords/tokens in logs/events","Third-party SDK auto-capture risk","PostHog config reviewed","Manual",""
"PERF-001","Performance","Cold start","Startup time within target for logged-out and logged-in states","Manual + Perf","P1","iOS, Android","Profile build with instrumentation","Measure cold launch","Meets agreed startup SLA","Slow network path for verified user","Auth check performs network call","Automate perf",""
"PERF-002","Performance","Large data rendering","Task/document/contractor lists remain responsive with large datasets","Manual + Perf","P1","iOS, Android, Web, Desktop","Seed large dataset","Scroll and interact lists","No jank/crash; acceptable memory","Thousands of items and images","Virtualized list behavior depends on platform","Manual + benchmarks","🟢 test17_residenceListPerformance | test14_taskListPerformance | test19_contractorListPerformance"
"PERF-003","Performance","Image handling","Large image capture/upload/compression memory stability","Manual + Perf","P0","iOS, Android","Use high-resolution photos","Attach multiple images","No OOM/crash; upload completes or fails gracefully","Low-memory device","ImageCompressor platform implementations are active","Manual",""
"PERF-004","Performance","Background operations","Foreground/resume refresh does not block UI thread","Manual + Perf","P2","iOS, Android","App with valid session","Background then foreground repeatedly","UI remains interactive during refresh","Concurrent refresh and navigation","Lookups refresh runs async","Manual","🟢 test16_residencePersistsAfterBackgroundingApp | test13_taskPersistsAfterBackgroundingApp | test18_contractorPersistsAfterBackgroundingApp"
"A11Y-001","Accessibility","Basic semantics","All primary controls have accessible labels/identifiers","Manual","P0","iOS, Android, Web, Desktop","Screen reader on","Traverse major flows","Controls are announced clearly","Custom components lacking labels","Accessibility identifiers partly defined","Manual + lint","🟢 testA001_OnboardingPrimaryControlsAreReachable | testA003_CoreControlsExposeIdentifiers | testA004_ValuePropsScreenControlsAreReachable | testA005_NameResidenceScreenControlsAreReachable | testA006_CreateAccountScreenControlsAreReachable"
"A11Y-002","Accessibility","Dynamic type","Text scales correctly without clipping in key screens","Manual","P1","iOS, Android","Large accessibility font settings","Open forms/lists/dialogs","Layout remains usable","Long localized strings","Design system supports flexible layout","Manual",""
"A11Y-003","Accessibility","Keyboard navigation","Tab/focus order valid on web/desktop forms","Manual","P1","Web, Desktop","Hardware keyboard","Navigate forms using keyboard only","Logical focus traversal and visible focus states","Modal dialogs focus trap","Compose/web focus handling may differ","Manual",""
"A11Y-004","Accessibility","Color contrast","Theme variants meet minimum contrast requirements","Manual + Tooling","P1","iOS, Android, Web, Desktop","Cycle themes","Inspect text/icon contrast","WCAG contrast thresholds met","Error/success states on tinted backgrounds","Multiple custom themes supported","Manual + automated audit",""
"I18N-001","Localization","String coverage","No missing keys/placeholders across supported locales","Manual + Static check","P1","iOS, Android, Web, Desktop","Run app in each locale","Traverse major screens","No raw keys, no placeholder mismatches","Pluralization and gender strings","Locales include es/fr/de/it/ja/ko/nl/pt/zh etc.","Automate (lint + screenshot)",""
"I18N-002","Localization","Layout expansion","Long translations do not break onboarding/forms/buttons","Manual","P1","iOS, Android, Web, Desktop","Switch to longest-string locale","Review high-density screens","No clipping/overlap","RTL future locale support","Current locales may be LTR only","Manual",""
"THEME-001","Theming","Theme persistence","Theme choice persists across app restarts","Manual + Integration","P1","iOS, Android, Web, Desktop","Logged in or logged out","Change theme then relaunch","Selected theme reapplied","Theme ID missing/corrupt in storage","Theme stored separately from auth data","Automate","🟢 defaultThemeIdIsDefault | setThemeIdUpdatesValue | clearDoesNotResetTheme | themeIdIsPreservedAsOceanAfterClear (ThemePersistenceTests) | test09_themePersistsAcrossRestart"
"THEME-002","Theming","Theme switch live update","Changing theme updates active screen without broken states","Manual + UI","P2","iOS, Android, Web, Desktop","Open app on any tab","Change theme in profile/settings","Immediate UI recolor with legible components","Transition while modal open","Theme manager publishes updates","Manual",""
"NAV-001","Navigation","Bottom tabs","Residences/Tasks/Contractors/Documents tabs navigate and preserve expected state","Manual + E2E UI","P0","iOS, Android","Logged in","Switch tabs repeatedly","Correct screens shown; no stuck navigation","Push navigation then tab switch back","Nested nav stacks differ per platform","Automate","🟢 test03_navigationBetweenTabs | test10_navigateBetweenTabs | testR309_navigationAcrossPrimaryTabsAndBackToResidences"
"NAV-002","Navigation","Back stack safety","Back from details/forms returns to correct parent","Manual + E2E UI","P0","iOS, Android, Web, Desktop","Navigate into detail/edit screens","Use back gestures/buttons","Parent state intact and refreshed as expected","Direct deep-link entry without parent","Saved-state refresh flags used in KMP nav","Automate","🟢 test02_cancelRegistration | test04_cancelResidenceCreation | test02_cancelTaskCreation | test19_CancelDocumentCreation"
"NAV-003","Navigation","Duplicate routes","Avoid duplicate screen instances from repeated tap/navigation actions","Manual","P2","iOS, Android, Web, Desktop","Rapidly tap nav actions","Observe back stack and UI","No duplicate stacking or loops","Double tap race conditions","NavHost popUpTo rules applied","Manual","🟢 testP003_RapidDoubleTapOnValuePropsContinueLandsOnNameResidence | testP004_StartFreshThenBackToWelcomeThenJoinExistingDoesNotCorruptState | testP005_RepeatedLoginNavigationRemainsStable"
"ANL-001","Analytics","Auth events","Login/register/logout/verify events fire once with correct properties","Manual + Integration","P2","iOS, Android","Analytics enabled in test env","Perform auth flows","Expected events emitted once","Retries causing duplicate events","Event taxonomy defined in analytics layer","Automate with mocked sink",""
"ANL-002","Analytics","Core feature events","Residence/task/document/contractor create-edit-delete events tracked","Manual + Integration","P2","iOS, Android","Analytics test workspace","Perform CRUD actions","Events mapped to correct feature","Failed actions should not emit success","PostHog wrappers used consistently","Automate",""
"ANL-003","Analytics","Subscription events","Upgrade prompt open, purchase, restore, verification outcomes tracked","Manual + Integration","P2","iOS, Android","Store sandbox + analytics","Run subscription flows","Lifecycle events present and correctly attributed","Purchase canceled path","No sensitive receipt data in events","Manual",""
"QA-001","Cross-platform parity","Feature parity","Core flows behave equivalently between KMP UI and iOS native UI","Manual regression","P0","iOS, Android, Web, Desktop","Same seeded account","Run same scenarios on each platform","Equivalent outcomes and data integrity","Known UX differences documented","iOS native app is source for iOS UX","Manual",""
"QA-002","Cross-platform parity","API contract consistency","All clients handle new/unknown JSON fields gracefully","Integration","P1","iOS, Android, Web, Desktop","Backend adds extra fields","Run major endpoints","No crash; fields ignored where unknown","Type changes breaking parsing","Kotlin serializers set ignoreUnknownKeys","Automate","🟢 widgetTaskDecodesWithExtraFields | widgetTaskIgnoresUnknownNestedObjects (JSONUnknownFieldsResilienceTests)"
"QA-003","Release quality","Smoke suite","Minimal release gate across auth, residence, task, document, contractor, notification, subscription","Manual + Automated","P0","iOS, Android","Release candidate build","Run smoke checklist","No blockers before release","Environment instability","Smoke should run against stable test backend","Automate + manual signoff","🟢 test01_authenticationFlow | test02_residenceCRUDFlow | test03_taskLifecycleFlow | test08_contractorCRUD | test01_NavigateToDocumentsScreen"
"QA-004","Release quality","Data migration","Upgrade app version preserves critical local state safely","Manual","P1","iOS, Android, Web, Desktop","Install old build with data then upgrade","Launch and use app","No corruption; expected resets only","Schema/key changes in persistence","Persistence keys remain compatible","Manual",""
1 Test_ID Domain Feature Scenario Test_Method Priority Platforms Preconditions Steps Expected_Result Edge_Cases Assumptions Automation_Recommendation automated
2 AUTH-001 Authentication App start routing First launch routes to onboarding when hasCompletedOnboarding=false Manual + E2E UI P0 iOS, Android, Web, Desktop Fresh install, no token Launch app Onboarding welcome is shown, not login/main tabs Corrupted local onboarding flag Onboarding state is persisted locally Automate (UI smoke) 🟢 testF001_ColdLaunchShowsOnboardingWelcome
3 AUTH-002 Authentication App start routing Returning user with onboarding complete and no token routes to login Manual + E2E UI P0 iOS, Android, Web, Desktop hasCompletedOnboarding=true, token missing Launch app Login screen shown Stale cached user object present Token is source of truth Automate 🟢 testAppLaunchesAndShowsLoginScreen
4 AUTH-003 Authentication App start routing Authenticated + verified user routes to main tabs Manual + E2E UI P0 iOS, Android, Web, Desktop Valid token, verified user Launch app Main tab shell displayed Cached token exists but API fails Current-user fetch determines validity Automate 🟢 testR203_validLoginTransitionsToMainAppRoot
5 AUTH-004 Authentication App start routing Authenticated but unverified user routes to verify email Manual + E2E UI P0 iOS, Android, Web, Desktop Valid token, verified=false Launch app Verify email screen shown User gets verified between launches Verification status fetched from backend Automate 🟢 testR104_verificationGateBlocksMainAppBeforeCodeEntry | testR110_relaunchUnverifiedUserNeverLandsInMainApp
6 AUTH-005 Authentication Token invalidation Invalid token at startup clears session and returns to login Manual + Integration P0 iOS, Android, Web, Desktop Expired/invalid token stored Launch app Data cleared and login shown Backend 500 vs 401 behavior 401/failed current-user means logout Automate 🟢 test08_invalidatedTokenRedirectsToLogin
7 AUTH-006 Authentication Login Valid username/password login success Manual + E2E UI P0 iOS, Android, Web, Desktop Existing verified account Submit login form Token persisted, lookups initialized, main shown Slow network during login Login API returns token+user Automate 🟢 test02_loginWithValidCredentials | testR202_validCredentialsSubmitFromLogin
8 AUTH-007 Authentication Login Invalid credentials shows actionable error Manual + E2E UI P0 iOS, Android, Web, Desktop No session Submit wrong password Error shown, user remains on login Rate-limit or lockout responses Error parser maps backend errors Automate 🟢 test01_loginWithInvalidCredentials
9 AUTH-008 Authentication Login validation Empty username/password blocked client-side Manual + UI P1 iOS, Android, Web, Desktop No session Tap login with empty fields Validation errors shown, no API call Whitespace-only input Client validation active Automate 🟢 testF205_LoginButtonDisabledWhenCredentialsAreEmpty | testF207_LoginScreenShowsAllExpectedElements | testF208_RegisterFormShowsAllRequiredFields
10 AUTH-009 Authentication Registration Create account success then verify-email step Manual + E2E UI P0 iOS, Android, Web, Desktop Unique email/username Submit valid registration Session established and verify-email screen appears Existing email conflict Register API auto-authenticates Automate 🟢 testR103_successfulRegistrationTransitionsToVerificationGate
11 AUTH-010 Authentication Registration validation Invalid email/password formats rejected Manual + UI P1 iOS, Android, Web, Desktop No session Try invalid email, short password, weak password User-friendly validation errors Unicode emails, long usernames Validation rules are enforced consistently Automate 🟢 test03_registrationWithEmptyFields | test04_registrationWithInvalidEmail | test06_registrationWithWeakPassword
12 AUTH-011 Authentication Email verification Valid 6-digit code verifies account Manual + E2E UI P0 iOS, Android, Web, Desktop Logged-in unverified user Enter 6-digit numeric code Account marked verified and app routes forward Code already used Code must be exactly 6 digits Automate 🟢 testR105_validVerificationCodeTransitionsToMainApp | test07_successfulRegistrationAndVerification
13 AUTH-012 Authentication Email verification Non-numeric/short/long code blocked Manual + UI P1 iOS, Android, Web, Desktop On verify-email screen Enter invalid codes Verify action disabled or error shown Pasted with spaces Code input sanitizes to digits Automate 🟢 testR107_invalidVerificationCodeShowsErrorAndStaysBlocked | testR109_verifyButtonDisabledForIncompleteCode | test10_verificationCodeFieldValidation
14 AUTH-013 Authentication Logout Logout clears token, user data, lookups, and returns to login Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Tap logout Login shown; protected API calls fail without token Logout API fails network-side Client clears state even if API call fails Automate 🟢 test06_logout | testR205_logoutFromMainAppReturnsToLoginRoot
15 AUTH-014 Authentication Forgot password Request reset by email success path Manual + E2E UI P0 iOS, Android, Web, Desktop Known account email Submit forgot-password email Success message and next step available Unknown email behavior privacy-safe Backend may still return generic success Automate 🟢 test05_forgotPasswordNavigation | testF206_ForgotPasswordButtonIsAccessible | testF209_ForgotPasswordNavigatesToResetFlow
16 AUTH-015 Authentication Reset code verification Verify reset code success path Manual + E2E UI P0 iOS, Android, Web, Desktop Reset email submitted Enter correct code Reset-token available for password reset Expired code Code verification endpoint returns token Automate 🟢 test03_verifyResetCodeSuccess
17 AUTH-016 Authentication Password reset Reset password success with matching confirmation Manual + E2E UI P0 iOS, Android, Web, Desktop Valid reset token Enter new password + confirm Password changed; user can log in (or auto-login flow) Token expires mid-flow Reset endpoint ignores confirm field Automate 🟢 test04_resetPasswordSuccessAndLogin
18 AUTH-017 Authentication Password reset Mismatched password confirmation blocked Manual + UI P1 iOS, Android, Web, Desktop Reset password screen Enter mismatch Inline error; no reset request Trailing spaces Client validates before submit Automate 🟢 mismatchedPasswordsFails | caseSensitiveMismatchFails (ValidationHelpersTests)
19 AUTH-018 Authentication Deep link reset Password-reset deep link opens flow with token prefilled Manual + E2E UI P0 iOS, Android Installed app with deep-link support Open reset deep link Forgot/reset flow opens and token is consumed Malformed token in URL Deep link token can be cleared on back Automate
20 AUTH-019 Authentication SSO Apple Apple Sign-In success creates or signs in account Manual + Integration P1 iOS Apple-capable test device/simulator Complete Apple sign-in Session established; verification state handled User hides email, first-login only email scope Apple credential mapped to backend request Automate partially (mock)
21 AUTH-020 Authentication SSO Google Google Sign-In success path Manual + Integration P1 Android, Web, KMP UI Google sign-in configured Complete Google sign-in Session established with backend token Revoked Google token Backend validates ID token Automate partially
22 ONB-001 Onboarding Intent split Start Fresh path goes through value props and name residence Manual + E2E UI P0 iOS, Android (KMP) Fresh install Choose Start Fresh and continue Step order matches intended flow Back navigation at each step Flow differs by intent Automate 🟢 testF101_StartFreshFlowReachesCreateAccount | testR002_startFreshFlowReachesCreateAccount
23 ONB-002 Onboarding Intent split Join Existing path skips value/name steps and goes to account creation Manual + E2E UI P0 iOS, Android (KMP) Fresh install Choose Join Existing Expected condensed step order User switches intent mid-flow Intent persisted during onboarding Automate 🟢 testF102_JoinExistingFlowGoesToCreateAccount | testF105_JoinExistingFlowSkipsValuePropsAndNameResidence
24 ONB-003 Onboarding Navigation Back button transitions and step history correctness Manual + UI P1 iOS, Android (KMP) In onboarding multi-step flow Navigate forward then back Returns to correct previous step Back from verify-email triggers logout on iOS Back behavior is product-defined Automate 🟢 testF103_BackNavigationFromNameResidenceReturnsToValueProps | testF108_BackFromCreateAccountNavigatesToPreviousStep
25 ONB-004 Onboarding Skip behavior Skippable screens skip to next valid state Manual + UI P1 iOS, Android (KMP) On skippable step Tap Skip Progress advances without corrupting state Skip on terminal upsell step completes onboarding Skip availability is step-dependent Automate 🟢 testF104_SkipOnValuePropsMovesToNameResidence
26 ONB-005 Onboarding Residence bootstrap Start Fresh creates residence automatically after verification Manual + Integration P0 iOS, Android (KMP) Onboarding start-fresh with residence name Verify email and continue Residence created or graceful fallback if creation fails Blank residence name bypasses creation Creation failure should not hard-block onboarding Automate 🟢 testF110_startFreshCreatesResidenceAfterVerification
27 ONB-006 Onboarding Join residence Join-existing flow joins via share code Manual + E2E UI P0 iOS, Android (KMP) Valid join code Submit code in onboarding User added to shared residence Expired/invalid/reused code Join code endpoint enforces ownership rules Automate
28 ONB-007 Onboarding First task First-task onboarding step can create selected tasks Manual + Integration P1 iOS, Android (KMP) On first-task step Select templates and continue Tasks created; flow proceeds Partial task creation failures At least one success considered success in KMP VM Automate
29 ONB-008 Onboarding Completion persistence Completing onboarding persists flag and bypasses onboarding next launch Manual + E2E UI P0 iOS, Android, Web, Desktop Completed onboarding once Restart app Onboarding is skipped App data clear resets flag Onboarding flag stored locally Automate 🟢 testF111_completedOnboardingBypassedOnRelaunch
30 RES-001 Residences List Residences list loads with empty and non-empty states Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Open residences tab Correct list/empty UI shown Slow API and stale cache List can come from cache or network Automate 🟢 test01_viewResidencesList | testR303_residencesListLoadsAfterTabSelection
31 RES-002 Residences Create Create residence with required fields only Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Fill minimum fields and save Residence appears in list/detail Duplicate name allowed/not allowed behavior Name required; other fields optional Automate 🟢 test05_createResidenceWithMinimalData | testR306_createResidenceMinimalDataSubmitsSuccessfully
32 RES-003 Residences Create validation Prevent submit when required name missing Manual + UI P1 iOS, Android, Web, Desktop Open add residence form Submit blank name Validation error, no API call Whitespace-only name Required validation trims input Automate 🟢 test01_cannotCreateResidenceWithEmptyName
33 RES-004 Residences Create optional fields All optional numeric/text/address fields persist correctly Manual + Integration P1 iOS, Android, Web, Desktop Open add residence form Fill all fields and save Values round-trip correctly in detail/edit Decimals for bathrooms/lot size Type conversion preserves precision Automate 🟢 test12_updateAllResidenceFields
34 RES-005 Residences Edit Edit residence updates list and detail views Manual + E2E UI P0 iOS, Android, Web, Desktop Existing residence Modify fields and save Updated values shown immediately Concurrent edit from another user DataManager updates local caches Automate 🟢 test11_editResidenceName | test12_updateAllResidenceFields
35 RES-006 Residences Delete Delete residence removes related task/document cached subsets Manual + Integration P0 iOS, Android, Web, Desktop Residence with tasks/docs exists Delete residence Residence gone; related cached sections removed Delete primary/only residence Server cascade semantics documented Automate 🟢 test02_residenceCRUDFlow
36 RES-007 Residences Primary residence Set/retain primary residence behavior Manual P2 iOS, Android, Web, Desktop Multiple residences Mark one as primary and reload Only intended residence is primary Two rapid primary updates Backend enforces uniqueness Automate partially 🟢 test18_setPrimaryResidence
37 RES-008 Residences Summary Residence summary counts derive from kanban columns correctly Manual + Integration P1 iOS, Android, Web, Desktop Residence with mixed task statuses Open summary cards Counts match task column truth No tasks state Summary can be client-computed Automate 🟢 test09_fullFlowSummary | test06_verifyKanbanStructure
38 RES-009 Residences Join by code Join residence from manual share code entry Manual + E2E UI P0 iOS, Android, Web, Desktop Valid share code from another account Enter code in join flow Membership granted and residence appears Code expired or already member Join endpoint returns reasoned errors Automate
39 RES-010 Residences Generate share code Generate/refresh residence share code Manual + Integration P1 iOS, Android, Web, Desktop Owner access to residence Generate code New valid code returned/visible Repeated generation invalidates old codes Access limited by role Automate 🟢 test07_residenceSharingUIElements
40 RES-011 Residences Share package export Create residence .casera package and open share sheet Manual P1 Android Residence exists, logged in Tap share residence Share sheet opens with file attachment Filename sanitization with special chars Backend generates package with shareCode Automate partially
41 RES-012 Residences Share package import Import .casera residence file joins residence Manual + Integration P0 Android Valid .casera file received Open file via app/import handler and confirm Join succeeds and success dialog shown Invalid JSON/wrong extension/no auth Import requires auth and parse success Automate partially
42 RES-013 Residences Task report Generate residence tasks report with/without email Manual + Integration P2 iOS, Android, Web, Desktop Residence exists Trigger generate report Report creation success feedback Invalid email format optional field Backend handles async report generation Automate
43 RES-014 Residences Manage users view Residence users list loads with owner/member roles Manual + E2E UI P1 iOS, Android (KMP) Residence with multiple users Open manage users Accurate users and role indicators displayed Owner missing from response Role data trusted from API Automate
44 RES-015 Residences Remove user Owner removes a member successfully Manual + Integration P0 iOS, Android (KMP) Owner logged in, target member exists Remove member Member removed and state refreshes Attempt remove self/owner API enforces permission rules Automate
45 TASK-001 Tasks All tasks load Kanban columns load for all residences Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in with at least one residence Open tasks tab Columns and counts render correctly Zero tasks across all columns Columns include overdue/in-progress/due-soon/upcoming/completed/cancelled Automate 🟢 test03_viewTasksList
46 TASK-002 Tasks Residence filtering Tasks by residence uses filtered allTasks cache correctly Manual + Integration P1 iOS, Android, Web, Desktop Multiple residences with tasks Open residence detail tasks Only selected residence tasks shown Residence cache stale while global cache fresh Client-side filtering path exists Automate 🟢 test07_residenceDetailsShowTasks
47 TASK-003 Tasks Create task Create minimal valid task Manual + E2E UI P0 iOS, Android, Web, Desktop Residence exists, lookups loaded Submit task with required fields Task appears in expected column Missing lookups due to failed seed load Category/frequency/priority are required Automate 🟢 test03_createTaskWithMinimalData | test06_createBasicTask
48 TASK-004 Tasks Create from template Create task from template browser Manual + E2E UI P1 iOS, Android, Web, Desktop Templates available Open templates, select one, save Task prefilled and created Template with long description/tags Template data from seeded lookups Automate 🟢 test16_createTaskFromTemplate
49 TASK-005 Tasks Template search Search templates requires >=2 chars and limits results Manual + Unit P2 iOS, Android, Web, Desktop Templates loaded Search with 1 char then 2+ chars 1 char returns empty, 2+ filtered max 10 Case-insensitive tag match Search is local in DataManager Automate 🟢 searchWithSingleCharReturnsEmpty | searchWithTwoCharsMatchesTitles | searchIsCaseInsensitive | searchMatchesDescription | searchMatchesTags | searchReturnsMaxTenResults | emptyQueryReturnsEmpty (TemplateSearchTests)
50 TASK-006 Tasks Edit task Edit task fields and persist updates Manual + E2E UI P0 iOS, Android, Web, Desktop Existing task Change title/category/frequency/priority/due/cost Task updates and remains consistent in caches Invalid cost string conversion Edit route passes serialized fields Automate 🟢 test09_editTaskTitle | test10_updateAllTaskFields
51 TASK-007 Tasks Mark in progress Transition task to in-progress column Manual + E2E UI P0 iOS, Android, Web, Desktop Existing non-in-progress task Tap mark in progress Task moves to in-progress column Already in progress idempotency UpdateTask uses kanbanColumn target Automate 🟢 test03_taskStateTransitions
52 TASK-008 Tasks Clear in progress Clear in-progress state returns task to scheduled column Manual + Integration P1 iOS, Android, Web, Desktop Task currently in progress Clear in-progress Task leaves in-progress with correct new column Due date past while clearing Backend decides target column Automate 🟢 test03_taskStateTransitions
53 TASK-009 Tasks Cancel task Cancel action moves task to cancelled state Manual + E2E UI P0 iOS, Android, Web, Desktop Active task exists Cancel task Task appears in cancelled column/state Cancel already-cancelled task Endpoint idempotency defined Automate 🟢 test04_taskCancelOperation
54 TASK-010 Tasks Uncancel task Restore cancelled task to active lifecycle Manual + E2E UI P0 iOS, Android, Web, Desktop Cancelled task exists Uncancel task Task restored to appropriate column Uncancel archived task State transitions validated by API Automate 🟢 test15_uncancelRestorescancelledTask
55 TASK-011 Tasks Archive/unarchive Archive hides task from active flow; unarchive restores Manual + Integration P1 iOS, Android, Web, Desktop Task exists Archive then unarchive Visibility toggles correctly Archived + cancelled combined states Archive APIs available and cached updates propagate Automate 🟢 test05_taskArchiveOperation
56 TASK-012 Tasks Delete semantics Task removal updates all cached columns and summaries Manual + Integration P1 iOS, Android, Web, Desktop Task exists in cached data Delete or server-remove task then refresh Task absent in all views and counts updated Task present in multiple cached views DataManager removeTask updates all maps Automate 🟢 allTasksIsNilAfterClear | removeTaskOnNilAllTasksIsNoOp | tasksByResidenceIsEmptyAfterClear (RemoveTaskTests)
57 TASK-013 Tasks Due date handling Past/now/future due dates map to correct columns Manual + Integration P1 iOS, Android, Web, Desktop Tasks with boundary due dates Load tasks around timezone boundaries Kanban placement matches backend logic DST transitions Backend provides canonical kanban_column Automate 🟢 test04_kanbanColumnDistribution | mixedTaskCategories (TaskMetricsTests)
58 TASK-014 Tasks Cost fields Estimated cost accepts numeric and rejects invalid formats Manual + UI P2 iOS, Android, Web, Desktop Task form open Enter valid/invalid cost strings Valid persisted; invalid blocked or sanitized Locale decimal separators Cost parsed to Double Automate 🟢 test04_createTaskWithAllFields
59 TASK-015 Tasks Task detail navigation Push/deep-link task navigation opens tasks tab and relevant task context Manual + E2E UI P0 iOS, Android App receives task navigation ID Tap notification/open intent Tasks tab selected and task reachable Task deleted before open Main shell handles navigate_to_task contract Automate
60 TASK-016 Tasks Bulk state refresh After any task CRUD/action, summary cards refresh immediately Manual + Integration P1 iOS, Android, Web, Desktop Dashboard visible with summaries Perform task action Summary counts update without hard reload Rapid consecutive actions Summary derived from cached kanban Automate 🟢 test09_fullFlowSummary
61 TASK-017 Tasks Concurrency Two users edit same task; conflict resolution UX Manual P2 iOS, Android, Web, Desktop Same task open on two accounts Save conflicting edits Consistent final state and clear error/last-write behavior Out-of-order responses Server conflict strategy documented Manual
62 TCOMP-001 Task completion Complete task basic Complete task with notes/cost/rating Manual + E2E UI P0 iOS, Android, Web, Desktop Active task exists Open complete flow and submit Completion created and task column updates Null rating vs default value Completion endpoint accepts optional fields Automate 🟢 test03_taskLifecycleFlow
63 TCOMP-002 Task completion Complete with images Attach one or multiple images during completion Manual + Integration P0 iOS, Android Camera/gallery permission granted Submit completion with images Images uploaded and linked to completion Large image compression/failure mid-upload Image compression and multipart upload enabled Automate partially
64 TCOMP-003 Task completion Validation Required completed-by field enforced (iOS form state) Manual + UI P1 iOS Open complete task form Submit blank completed-by Validation error shown Whitespace-only value CompletedBy required by client form Automate 🟢 completedByFieldRequired | completedByFieldWithValuePasses | completedByFieldWhitespaceOnlyFails (TaskCompletionValidationTests)
65 TCOMP-004 Task completion Completion history History list loads for task and sorted correctly Manual + Integration P1 iOS, Android, Web, Desktop Task with multiple completions Open completion history Entries ordered and accurate Missing images in older completion records History endpoint returns full list Automate 🟢 test10_completionHistoryLoadsAndIsSorted
66 DOC-001 Documents List Load all documents and residence-filtered documents Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in with docs data Open documents tab and residence detail docs Correct sets shown Residence with zero docs List supports optional residence filter Automate 🟢 test01_NavigateToDocumentsScreen | test20_HandleEmptyDocumentsList | test21_HandleEmptyWarrantiesList
67 DOC-002 Documents Create document Create generic document with required fields Manual + E2E UI P0 iOS, Android, Web, Desktop Residence exists Create document with title/type/residence Document appears in lists Missing residence selection on create Create requires title/type/residence Automate 🟢 test04_CreateDocumentWithMinimalFields
68 DOC-003 Documents Create warranty fields Create warranty/appliance with provider/dates metadata Manual + Integration P1 iOS, Android, Web, Desktop Document form open Enter warranty-specific fields and save Fields persist and render in detail End date before start date Date validation expectations defined Automate 🟢 test06_CreateWarrantyWithAllFields | test07_CreateWarrantyWithFutureDates | test08_CreateExpiredWarranty
69 DOC-004 Documents Edit document Edit existing document including type/category/tags Manual + E2E UI P1 iOS, Android, Web, Desktop Document exists Modify and save Detail/list reflect updates Switching types with stale fields Backend accepts partial update Automate 🟢 test15_EditDocumentTitle | test16_EditWarrantyDates
70 DOC-005 Documents Delete document Delete removes from global and residence caches Manual + Integration P0 iOS, Android, Web, Desktop Document exists in caches Delete document Document removed everywhere Delete while detail screen open DataManager removeDocument updates both caches Automate 🟢 test17_DeleteDocument | test18_DeleteWarranty
71 DOC-006 Documents Upload image Upload document image from camera/gallery Manual + Integration P0 iOS, Android Permissions granted Add image to document Thumbnail and full image accessible Upload timeout Upload endpoint returns image metadata Automate partially
72 DOC-007 Documents Delete image Delete specific document image updates detail immediately Manual + Integration P1 iOS, Android, Web, Desktop Document with multiple images Delete one image Remaining images preserved Deleting last image Image delete endpoint idempotency Automate 🟢 test22_documentImageSectionExists
73 DOC-008 Documents Download Download/open document file via URL Manual P1 iOS, Android, Web, Desktop Document has downloadable URL Tap download/open File retrieved and usable Expired signed URL Download API wraps binary result Automate partially
74 DOC-009 Documents Validation Claim email optional but must be valid if provided Manual + UI P2 iOS Document form open Enter invalid claim email Validation error shown Internationalized domains Email regex defines valid format Automate 🟢 validEmailPasses | invalidEmailMissingAtFails (ValidationHelpersTests + StringExtensionsTests)
75 DOC-010 Documents Media viewer Image viewer navigation, zoom, swipe, close behavior Manual P2 iOS, Android Document with multiple images Open viewer and interact No crashes; correct index and gestures Very large images Viewer supports list index initialization Manual
76 CON-001 Contractors List Load contractors with empty and populated states Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Open contractors tab List/empty state correct Large list pagination if any API supports optional filters Automate 🟢 test16_refreshContractorsList
77 CON-002 Contractors Create Create contractor minimal required fields Manual + E2E UI P0 iOS, Android, Web, Desktop Logged in Create contractor with name Contractor appears in list/detail Special characters in names Name is required Automate 🟢 test03_createContractorWithMinimalData
78 CON-003 Contractors Create optional data Persist optional company/contact/address/specialties Manual + Integration P1 iOS, Android, Web, Desktop Contractor form open Fill optional fields and save All values persist accurately Invalid website URL format Optional fields may be null Automate 🟢 test04_createContractorWithAllFields | test14_updateAllContractorFields
79 CON-004 Contractors Email validation Optional email must be valid if supplied Manual + UI P1 iOS, Android, Web, Desktop Contractor form open Enter invalid email Validation error blocks save Uppercase email + spaces Validation trims and regex-checks Automate 🟢 validEmailPasses | invalidEmailMissingAtFails | invalidEmailMissingDomainFails (ValidationHelpersTests + StringExtensionsTests)
80 CON-005 Contractors Edit Edit contractor and verify list/detail sync Manual + E2E UI P1 iOS, Android, Web, Desktop Existing contractor Update fields and save Updated across views Concurrent remote update DataManager updateContractor handles summary mapping Automate 🟢 test13_editContractorName | test14_updateAllContractorFields
81 CON-006 Contractors Delete Delete contractor removes from caches and residence associations Manual + Integration P0 iOS, Android, Web, Desktop Existing contractor Delete contractor Removed from all views Deleting favorite contractor Association cleanup server-side Automate 🟢 test08_contractorCRUD
82 CON-007 Contractors Favorite toggle Toggle favorite updates UI and persistence Manual + E2E UI P1 iOS, Android, Web, Desktop Existing contractor Toggle favorite twice State toggles correctly and persists refresh Rapid repeated taps Endpoint supports idempotent toggles Automate 🟢 test20_toggleContractorFavorite
83 CON-008 Contractors By residence filter Load contractors scoped to residence Manual + Integration P1 iOS, Android, Web, Desktop Multiple residences and linked contractors Open residence contractor section Only related contractors shown Contractor with null residence Filtering done server-side Automate 🟢 test21_contractorByResidenceFilter
84 CON-009 Contractors Share export Share contractor as .casera file Manual P1 Android Contractor exists Tap share contractor Share sheet opens with valid file payload Name containing '/' and long length Filename sanitization applied Manual
85 CON-010 Contractors Import .casera Import contractor from valid file Manual + Integration P0 Android Logged in, valid contractor file Open file/import confirm Contractor created and success dialog shown Unknown specialty names in file Specialties mapped by name to known IDs Automate partially
86 CON-011 Contractors Import invalid file Invalid extension/JSON/auth state handled safely Manual P0 Android Invalid file or logged out Attempt import Clear error shown; no partial creation Huge malformed JSON Import parser errors are surfaced Manual
87 NOTIF-001 Notifications Permission prompt Notification permission request outcomes handled Manual P0 iOS, Android Fresh install Respond Allow and Deny in separate runs App continues gracefully; state reflects permission User changes setting later Permission checked on foreground Manual
88 NOTIF-002 Notifications Device registration Register device token after login only Manual + Integration P0 iOS, Android Have APNs/FCM token Login with token available registerDevice called once and succeeds Token arrives before auth Auth gating prevents unauthenticated registration Automate
89 NOTIF-003 Notifications Token refresh New push token triggers backend re-registration Manual + Integration P1 iOS, Android Previously registered token Simulate token rotation Backend receives updated registration id No token change should skip call Last registered token cache used Automate
90 NOTIF-004 Notifications Foreground notification Foreground notifications display banner/sound and update read state Manual P1 iOS, Android Permission granted, send test push Receive push while app active Banner shown; notification handled Malformed payload missing type Foreground presentation explicitly enabled Manual
91 NOTIF-005 Notifications Notification tap navigation Tap task push opens app and routes to tasks context Manual + E2E P0 iOS, Android Task-linked push sent Tap push from background/terminated App opens on tasks flow for target task Task no longer exists Task id may be string or int Automate partially
92 NOTIF-006 Notifications Action buttons premium Premium users see and can execute task action buttons Manual + Integration P0 iOS, Android Premium subscription active Receive actionable task notification, tap action Action API executes and UI refreshes Action timeout/network loss Actions gated by premium/limitationsEnabled Manual
93 NOTIF-007 Notifications Action buttons free-tier gating Free users with limitations enabled are routed home/not allowed actions Manual P0 iOS, Android Free user limitationsEnabled=true Tap actionable notification No privileged task action executed Subscription cache stale nil Nil subscription defaults allow on iOS currently Manual
94 NOTIF-008 Notifications Preferences Load and update notification preference toggles Manual + Integration P1 iOS, Android, Web, Desktop Logged in Open notification preferences, toggle settings, save Preferences persist and affect server payloads Partial update failures Preferences API supports patch/update Automate
95 NOTIF-009 Notifications History/read state Notification history list and mark-read operations Manual + Integration P2 iOS, Android, Web, Desktop Notifications exist Open history, mark one and mark all Unread counts decrement correctly Race with incoming push Unread count endpoint consistent Automate
96 SUB-001 Subscription Status load Subscription status loads at app launch/foreground Manual + Integration P0 iOS, Android, Web, Desktop Logged in Launch then background/foreground app Status cache updates and UI gating accurate Backend temporarily unavailable Status refresh should be non-fatal Automate
97 SUB-002 Subscription Upgrade screen products Load purchasable plans and pricing Manual P0 iOS, Android Store config present Open upgrade screen Monthly/annual products displayed Store connectivity issues Product IDs configured as expected Manual + mocked automation
98 SUB-003 Subscription Purchase monthly Complete monthly purchase and backend verification Manual + Integration P0 iOS, Android Sandbox account, product available Buy monthly plan Entitlement granted, subscription status becomes pro Pending transactions Verification endpoint must return success Manual
99 SUB-004 Subscription Purchase annual Complete annual purchase and backend verification Manual + Integration P0 iOS, Android Sandbox account Buy annual plan Entitlement granted and reflected in app Upgrade/downgrade from existing plan Latest transaction determines tier Manual
100 SUB-005 Subscription Restore purchases Restore on clean install/device migration Manual + Integration P0 iOS, Android Existing prior subscription Tap restore Entitlements restored and backend synced No previous purchases Restore should not duplicate grants Manual
101 SUB-006 Subscription Purchase cancellation User-cancelled purchase does not show fatal error Manual P1 iOS, Android Open paywall Start then cancel purchase No entitlement changes; UX remains stable Repeated cancel attempts User cancel considered non-error Manual
102 SUB-007 Subscription Backend verification failure Store purchase succeeds but backend verify fails Manual P0 iOS, Android Force backend verify failure Complete purchase User sees recoverable state and can retry/restore Receipt parsing mismatch App should avoid false pro unlock Manual
103 SUB-008 Subscription Feature gating Pro-only features hidden/disabled for limited users Manual + E2E P0 iOS, Android, Web, Desktop Test free and pro accounts Traverse gated features (actions, limits, upgrades) Gating consistent across surfaces Cache stale after plan change Gating uses subscription status + limitationsEnabled Automate
104 WID-001 Widgets Small widget rendering Small widget shows counts and opens app Manual P1 Android Widget added, logged in Place small widget and tap Correct counts; tap opens app No data cached yet Widget reads from shared preferences state Manual
105 WID-002 Widgets Medium widget list Medium widget shows top tasks and overdue badge Manual P1 Android Tasks exist Place medium widget Task rows and overdue badge correct Malformed tasks_json JSON parse fallback to empty list Manual
106 WID-003 Widgets Large widget interactions Large widget actions execute for pro users Manual + Integration P0 Android Pro account, widget configured Tap row and action controls Opens task or executes action as expected Free user should not see/execute pro actions Widget passes task_id in intent Manual
107 WID-004 Widgets Widget refresh Widgets refresh after task state changes Manual P1 Android Widget present Complete/cancel task in app Widget counts/list update within expected interval Background restrictions Widget update manager triggers refresh Manual
108 SHR-001 Sharing/Import File association .casera files open app import flow Manual P1 Android Have .casera file Open file from files app/share sheet Import confirmation dialog shown Multiple apps can open same MIME Intent filter handles application/json with extension Manual
109 SHR-002 Sharing/Import Security Import rejects when unauthenticated Manual P0 Android Logged out, .casera file ready Attempt import Error shown, no data mutation Stale token in storage Auth check occurs before API call Manual
110 SHR-003 Sharing/Import Corrupt payload Corrupt .casera payload fails safely without crash Manual P0 Android Malformed JSON file Attempt import Graceful error dialog Very large payload Parser exceptions are caught Manual
111 DATA-001 Data layer Lookups init Seeded lookup data loads once and marks initialized Manual + Integration P0 iOS, Android, Web, Desktop Fresh login Observe first data bootstrap Lookups available for forms/templates Slow network during bootstrap initializeLookups has concurrency guard Automate 🟢 test06_lookupDataAvailable | setTaskCategoriesPopulatesList | setTaskCategoriesBuildsMappedLookup | setTaskPrioritiesPopulatesListAndMap | setTaskFrequenciesPopulatesListAndMap | setResidenceTypesPopulatesListAndMap | setContractorSpecialtiesPopulatesListAndMap | markLookupsInitializedSetsFlag (DataLayerTests)
112 DATA-002 Data layer ETag refresh Lookup refresh uses ETag and handles 304 not modified Manual + Integration P1 iOS, Android, Web, Desktop Lookups already loaded + ETag Foreground app or force refresh No unnecessary data churn on 304 ETag lost between sessions ETag persisted in storage Automate 🟢 staticDataEndpointReturnsETag | conditionalRequestReturns304WhenDataUnchanged | staleETagReturns200 (DataLayerETagTests)
113 DATA-003 Data layer Legacy fallback If seeded-data endpoint fails, fallback static data path works Manual + Integration P1 iOS, Android, Web, Desktop Mock seeded endpoint failure Initialize lookups Core lookups still available Templates missing in fallback Fallback endpoint still reachable Automate 🟢 staticDataContainsAllRequiredLookupTypes | allLookupItemsHaveIdAndName | taskCategoriesHaveColorAndIcon | taskPrioritiesHaveLevelAndColor (DataLayerAPISchemaTests)
114 DATA-004 Data layer Cache timeout One-hour cache timeout triggers fresh fetch after expiry Manual + Integration P1 iOS, Android, Web, Desktop Cached data older/newer than timeout Request data with forceRefresh=false Valid cache reused; stale cache refetched Clock skew/device time changes Timeout constant is 3600000 ms Automate 🟢 cacheTimeZeroIsInvalid | recentCacheTimeIsValid | expiredCacheTimeIsInvalid | cacheTimeoutConstantIsOneHour | allCacheTimestampsStartAtZeroAfterClear (DataLayerTests.CacheValidationTests)
115 DATA-005 Data layer Cache invalidation on logout Logout clears user data/cache/ETag but retains theme Manual + Integration P0 iOS, Android, Web, Desktop Logged in with populated data Logout then inspect next launch No user data remains; theme preference retained Persistence clear implementation drift Theme stored separately from persistenceManager.clear Automate 🟢 testR206_postLogoutMainAppIsNoLongerAccessible | clearResetsAllCacheTimestamps | clearEmptiesLookupLists | clearResetsLookupsInitializedFlag | clearUserDataKeepsLookups | clearUserDataResetsCacheTimestamps (DataLayerTests.ClearTests)
116 DATA-006 Data layer Disk persistence Current user and lookups reload correctly after app restart Manual + Integration P1 iOS, Android, Web, Desktop Logged in and data loaded Kill and relaunch app State restored without full refetch where valid Partial/corrupt persisted JSON Deserializer ignoreUnknownKeys is enabled Automate 🟢 test08_diskPersistencePreservesLookupsAfterRestart
117 DATA-007 Data layer Map/list consistency Lookup map IDs and list values remain consistent after updates Unit + Integration P2 iOS, Android, Web, Desktop Lookup update operation Compare list and map representations No missing or mismatched IDs Duplicate IDs from backend Maps are built via associateBy(id) Automate 🟢 setTaskCategoriesBuildsMappedLookup | getterReturnsNilForMissingId | getterReturnsNilForNilId | allIdsAreUniquePerLookupType (DataLayerTests.LookupSetterTests + DataLayerAPISchemaTests)
118 OFF-001 Resilience Offline launch Offline launch with cached token/data behaves gracefully Manual P0 iOS, Android, Web, Desktop Previously logged in with cached data Launch with network off No crash; clear messaging; cached UI where possible Token validation cannot reach server Current behavior may clear session on fetch failure Manual
119 OFF-002 Resilience Offline action handling Create/update actions fail with retriable errors when offline Manual P0 iOS, Android, Web, Desktop Network disabled Attempt create/edit/delete flows Errors shown; no phantom local success Intermittent network flaps No offline queue currently assumed Manual
120 OFF-003 Resilience Retry behavior Retry from error dialogs succeeds without stale UI state Manual + E2E P1 iOS, Android, Web, Desktop Force transient API failure Tap retry then restore network Action succeeds and loading/error states reset Double-tap retry race ApiResult state machine handles Idle/Loading/Error Automate 🟢 testP010_retryButtonExistsOnErrorState
121 OFF-004 Resilience Idempotency UX Double submit protection for create flows Manual + UI P1 iOS, Android, Web, Desktop Open any create form Rapid tap save Single record created Very slow API response Buttons disabled during loading Automate 🟢 test19_doubleSubmitProtection
122 SEC-001 Security Auth boundaries Protected endpoints reject without token and UI handles 401 Manual + Integration P0 iOS, Android, Web, Desktop No token Attempt protected operations Redirect/login prompt or clear error Token injected but expired APILayer checks token before API in many calls Automate 🟢 test05_crossUserAccessControl
123 SEC-002 Security Session cleanup Sensitive data not accessible after logout and app restart Manual P0 iOS, Android, Web, Desktop Logged in then logout Force close and relaunch No protected screens/data accessible Widget still showing stale data Widget caches should be cleared on logout (iOS path) Manual 🟢 testR206_postLogoutMainAppIsNoLongerAccessible
124 SEC-003 Security Import validation Imported files cannot execute code or break parser boundaries Manual P1 Android Craft malicious JSON payload Import payload App rejects safely, no crash Oversized strings, deep nesting Deserializer should throw and be caught Manual
125 SEC-004 Security PII exposure Logs and analytics avoid leaking sensitive credential values Manual + Code audit P1 iOS, Android, Web, Desktop Enable debug logging Run auth/payment flows No passwords/tokens in logs/events Third-party SDK auto-capture risk PostHog config reviewed Manual
126 PERF-001 Performance Cold start Startup time within target for logged-out and logged-in states Manual + Perf P1 iOS, Android Profile build with instrumentation Measure cold launch Meets agreed startup SLA Slow network path for verified user Auth check performs network call Automate perf
127 PERF-002 Performance Large data rendering Task/document/contractor lists remain responsive with large datasets Manual + Perf P1 iOS, Android, Web, Desktop Seed large dataset Scroll and interact lists No jank/crash; acceptable memory Thousands of items and images Virtualized list behavior depends on platform Manual + benchmarks 🟢 test17_residenceListPerformance | test14_taskListPerformance | test19_contractorListPerformance
128 PERF-003 Performance Image handling Large image capture/upload/compression memory stability Manual + Perf P0 iOS, Android Use high-resolution photos Attach multiple images No OOM/crash; upload completes or fails gracefully Low-memory device ImageCompressor platform implementations are active Manual
129 PERF-004 Performance Background operations Foreground/resume refresh does not block UI thread Manual + Perf P2 iOS, Android App with valid session Background then foreground repeatedly UI remains interactive during refresh Concurrent refresh and navigation Lookups refresh runs async Manual 🟢 test16_residencePersistsAfterBackgroundingApp | test13_taskPersistsAfterBackgroundingApp | test18_contractorPersistsAfterBackgroundingApp
130 A11Y-001 Accessibility Basic semantics All primary controls have accessible labels/identifiers Manual P0 iOS, Android, Web, Desktop Screen reader on Traverse major flows Controls are announced clearly Custom components lacking labels Accessibility identifiers partly defined Manual + lint 🟢 testA001_OnboardingPrimaryControlsAreReachable | testA003_CoreControlsExposeIdentifiers | testA004_ValuePropsScreenControlsAreReachable | testA005_NameResidenceScreenControlsAreReachable | testA006_CreateAccountScreenControlsAreReachable
131 A11Y-002 Accessibility Dynamic type Text scales correctly without clipping in key screens Manual P1 iOS, Android Large accessibility font settings Open forms/lists/dialogs Layout remains usable Long localized strings Design system supports flexible layout Manual
132 A11Y-003 Accessibility Keyboard navigation Tab/focus order valid on web/desktop forms Manual P1 Web, Desktop Hardware keyboard Navigate forms using keyboard only Logical focus traversal and visible focus states Modal dialogs focus trap Compose/web focus handling may differ Manual
133 A11Y-004 Accessibility Color contrast Theme variants meet minimum contrast requirements Manual + Tooling P1 iOS, Android, Web, Desktop Cycle themes Inspect text/icon contrast WCAG contrast thresholds met Error/success states on tinted backgrounds Multiple custom themes supported Manual + automated audit
134 I18N-001 Localization String coverage No missing keys/placeholders across supported locales Manual + Static check P1 iOS, Android, Web, Desktop Run app in each locale Traverse major screens No raw keys, no placeholder mismatches Pluralization and gender strings Locales include es/fr/de/it/ja/ko/nl/pt/zh etc. Automate (lint + screenshot)
135 I18N-002 Localization Layout expansion Long translations do not break onboarding/forms/buttons Manual P1 iOS, Android, Web, Desktop Switch to longest-string locale Review high-density screens No clipping/overlap RTL future locale support Current locales may be LTR only Manual
136 THEME-001 Theming Theme persistence Theme choice persists across app restarts Manual + Integration P1 iOS, Android, Web, Desktop Logged in or logged out Change theme then relaunch Selected theme reapplied Theme ID missing/corrupt in storage Theme stored separately from auth data Automate 🟢 defaultThemeIdIsDefault | setThemeIdUpdatesValue | clearDoesNotResetTheme | themeIdIsPreservedAsOceanAfterClear (ThemePersistenceTests) | test09_themePersistsAcrossRestart
137 THEME-002 Theming Theme switch live update Changing theme updates active screen without broken states Manual + UI P2 iOS, Android, Web, Desktop Open app on any tab Change theme in profile/settings Immediate UI recolor with legible components Transition while modal open Theme manager publishes updates Manual
138 NAV-001 Navigation Bottom tabs Residences/Tasks/Contractors/Documents tabs navigate and preserve expected state Manual + E2E UI P0 iOS, Android Logged in Switch tabs repeatedly Correct screens shown; no stuck navigation Push navigation then tab switch back Nested nav stacks differ per platform Automate 🟢 test03_navigationBetweenTabs | test10_navigateBetweenTabs | testR309_navigationAcrossPrimaryTabsAndBackToResidences
139 NAV-002 Navigation Back stack safety Back from details/forms returns to correct parent Manual + E2E UI P0 iOS, Android, Web, Desktop Navigate into detail/edit screens Use back gestures/buttons Parent state intact and refreshed as expected Direct deep-link entry without parent Saved-state refresh flags used in KMP nav Automate 🟢 test02_cancelRegistration | test04_cancelResidenceCreation | test02_cancelTaskCreation | test19_CancelDocumentCreation
140 NAV-003 Navigation Duplicate routes Avoid duplicate screen instances from repeated tap/navigation actions Manual P2 iOS, Android, Web, Desktop Rapidly tap nav actions Observe back stack and UI No duplicate stacking or loops Double tap race conditions NavHost popUpTo rules applied Manual 🟢 testP003_RapidDoubleTapOnValuePropsContinueLandsOnNameResidence | testP004_StartFreshThenBackToWelcomeThenJoinExistingDoesNotCorruptState | testP005_RepeatedLoginNavigationRemainsStable
141 ANL-001 Analytics Auth events Login/register/logout/verify events fire once with correct properties Manual + Integration P2 iOS, Android Analytics enabled in test env Perform auth flows Expected events emitted once Retries causing duplicate events Event taxonomy defined in analytics layer Automate with mocked sink
142 ANL-002 Analytics Core feature events Residence/task/document/contractor create-edit-delete events tracked Manual + Integration P2 iOS, Android Analytics test workspace Perform CRUD actions Events mapped to correct feature Failed actions should not emit success PostHog wrappers used consistently Automate
143 ANL-003 Analytics Subscription events Upgrade prompt open, purchase, restore, verification outcomes tracked Manual + Integration P2 iOS, Android Store sandbox + analytics Run subscription flows Lifecycle events present and correctly attributed Purchase canceled path No sensitive receipt data in events Manual
144 QA-001 Cross-platform parity Feature parity Core flows behave equivalently between KMP UI and iOS native UI Manual regression P0 iOS, Android, Web, Desktop Same seeded account Run same scenarios on each platform Equivalent outcomes and data integrity Known UX differences documented iOS native app is source for iOS UX Manual
145 QA-002 Cross-platform parity API contract consistency All clients handle new/unknown JSON fields gracefully Integration P1 iOS, Android, Web, Desktop Backend adds extra fields Run major endpoints No crash; fields ignored where unknown Type changes breaking parsing Kotlin serializers set ignoreUnknownKeys Automate 🟢 widgetTaskDecodesWithExtraFields | widgetTaskIgnoresUnknownNestedObjects (JSONUnknownFieldsResilienceTests)
146 QA-003 Release quality Smoke suite Minimal release gate across auth, residence, task, document, contractor, notification, subscription Manual + Automated P0 iOS, Android Release candidate build Run smoke checklist No blockers before release Environment instability Smoke should run against stable test backend Automate + manual signoff 🟢 test01_authenticationFlow | test02_residenceCRUDFlow | test03_taskLifecycleFlow | test08_contractorCRUD | test01_NavigateToDocumentsScreen
147 QA-004 Release quality Data migration Upgrade app version preserves critical local state safely Manual P1 iOS, Android, Web, Desktop Install old build with data then upgrade Launch and use app No corruption; expected resets only Schema/key changes in persistence Persistence keys remain compatible Manual