diff --git a/.commandcode/taste/taste/taste.md b/.commandcode/taste/taste/taste.md index 53fa3f5..c8e17be 100644 --- a/.commandcode/taste/taste/taste.md +++ b/.commandcode/taste/taste/taste.md @@ -22,7 +22,7 @@ - Prefers test plans written for a non-technical audience, using plain-language, click-by-click instructions ("tap this", "type that", "check there") rather than technical terms or API names. Confidence: 0.9 - When updating or creating a document, prefers the agent first compare it against existing source documents, identify missing items or gaps, and add them in the same established format. Confidence: 0.9 - Dislikes nested headers in mobile/drawer navigation; prefers a single, shared header (e.g., the drawer header) and relies on device back buttons or gestures for returning to previous screens. Confidence: 0.9 -- After reviewing a presented plan, prefers brief, action-oriented approval (e.g., "nice. go ahead", "go ahead and implement") before implementation proceeds, expecting the agent to autonomously execute the already-presented plan. Confidence: 0.85 +- After reviewing a presented plan, prefers brief, action-oriented approval (e.g., "nice. go ahead", "go ahead and implement") before implementation proceeds, expecting the agent to autonomously execute the already-presented plan. Confidence: 0.9 - Wants feature parity maintained between the web-ui and user-ui apps (port logic/data patterns, rebuild UI per platform) — e.g., when he asks for a link in the cart page "at the coupons section" of @apps/user-ui/components/cart-page.tsx, he means mirror user-ui's coupons section (card, header, icon) in web-ui and add the requested link there; and conversely asks for features added in one app to be added to the sibling app "too" (e.g., "add the coupon redirection on the user-ui cart-page too"), expecting the agent to locate the equivalent component/route and replicate it. Confidence: 0.98 - Wants the web-ui home page section/component order to match the reference user-ui home page exactly (e.g., "on the home page have the order same as that of @apps/user-ui/.../home/index.tsx"), including when deciding placement of sections like Explore, Stores, Slots, and All Products. Confidence: 0.7 - Wants brand/logo spots to use the single real brand logo asset (shared across apps, e.g., the Freshyo splash logo) displayed as an image, not a generic/decorative icon (e.g., a "meat piece" Meat/Beef icon) — web-ui should be on par with user-ui and show the same logo; applies to favicon, PWA icons, and every in-UI branding spot (sidebar, topbar, login, home banner). Confidence: 0.85 @@ -92,7 +92,9 @@ er-ui/app/(drawer)/(tabs)/home/index.tsx, I want similar here") and expects the - When deleting a record, prefers the existing soft-delete/invalidate path over hard-deleting rows: the supported delete already sets `isInvalidated: true` (keeping history/audit and avoiding broken FK joins), and a raw hard delete should only be considered when confirmed nothing references the row (no usage records), with related rows (couponApplicableUsers/Products) removed transactionally to avoid orphans. Confidence: 0.75 - When commissioning a dead-code audit of an app/package, expects a "close analysis" that is exhaustive across every category — dead, unreachable, and unused code: orphaned files, unreachable/unlinked routes, dormant or disabled-by-flag features, dead branches and commented-out blocks, and unused imports/exports — finding "every such code which serves no purpose" rather than only obviously-unreferenced files; findings should distinguish verified-dead items from merely dormant/judgment-call items. Confidence: 0.65 - When an analysis/audit has been produced for one app in the monorepo, expects the same analysis run for the sibling apps too — after the user-ui dead-code audit he immediately asked "now do the same for the @apps/admin-ui" — applying the identical exhaustive methodology and document style to each named app. Confidence: 0.85 -- For per-app analysis documents, expects a consistent naming pattern following the established convention (`user_ui_dpsk.md` → `admin_ui_dpsk.md`, i.e., `{app}_dpsk.md` at the repo root) rather than an ad-hoc filename — "make another md file with same naming pattern". Confidence: 0.9 +- For analysis documents, expects a consistent naming pattern following the established convention (`user_ui_dpsk.md` → `admin_ui_dpsk.md`, i.e., `{app}_dpsk.md` at the repo root) rather than an ad-hoc filename — "make another md file with same naming pattern"; the `_dpsk.md` suffix also applies to cross-cutting topic analyses (e.g., `repeat_types_dpsk.md` for the repeated-types scan). Confidence: 0.9 +- When commissioning a cross-cutting audit/analysis, expects the scan to span the entire monorepo in one pass — every app, the backend, AND the shared packages (e.g., "scan the entire @apps/user-ui/ @apps/admin-ui/ @apps/backend/ and also entire @packages/") — not just one app or one area. Confidence: 0.65 +- Values type-level hygiene alongside runtime structures: wants repeated type declarations across the monorepo hunted down and classified (identical duplicates, near-identical/unifiable shapes, same-name-different-shape collisions) and documented in a report before any refactor, rather than fixing types piecemeal. Confidence: 0.6 e changes. Confidence: 0.95 er-ui/app/(drawer)/(tabs)/home/index.tsx, I want similar here") and expects the agent to mirror that pattern exactly, including details like item counts and container styling. Confidence: 0.9 als) rather than introducing new brand palettes; approval of a redesign's layout/composition does not imply approval of color or theme changes. Confidence: 0.95 @@ -103,3 +105,11 @@ er-ui/app/(drawer)/(tabs)/home/index.tsx, I want similar here") and expects the y, including details like item counts and container styling. Confidence: 0.9 tes; approval of a redesign's layout/composition does not imply approval of color or theme changes. Confidence: 0.95 er-ui/app/(drawer)/(tabs)/home/index.tsx, I want similar here") and expects the agent to mirror that pattern exactly, including details like item counts and container styling. Confidence: 0.9 +olor or theme changes. Confidence: 0.95 +roducing new brand palettes; approval of a redesign's layout/composition does not imply approval of color or theme changes. Confidence: 0.95 +er-ui/app/(drawer)/(tabs)/home/index.tsx, I want similar here") and expects the agent to mirror that pattern exactly, including details like item counts and container styling. Confidence: 0.9 +tes; approval of a redesign's layout/composition does not imply approval of color or theme changes. Confidence: 0.95 +er-ui/app/(drawer)/(tabs)/home/index.tsx, I want similar here") and expects the agent to mirror that pattern exactly, including details like item counts and container styling. Confidence: 0.9 +y, including details like item counts and container styling. Confidence: 0.9 +tes; approval of a redesign's layout/composition does not imply approval of color or theme changes. Confidence: 0.95 +er-ui/app/(drawer)/(tabs)/home/index.tsx, I want similar here") and expects the agent to mirror that pattern exactly, including details like item counts and container styling. Confidence: 0.9 diff --git a/apps/backend/wrangler.dev.toml b/apps/backend/wrangler.dev.toml index bdcbe8b..1102f16 100644 --- a/apps/backend/wrangler.dev.toml +++ b/apps/backend/wrangler.dev.toml @@ -8,10 +8,10 @@ routes = [ [[d1_databases]] binding = "DB" -database_name = "freshyo-backend-dev" -database_id = "b2528bdb-0ec0-478e-8765-b118918153c0" -#database_name = "freshyo-dev" -#database_id = "3cad440f-dc14-4baa-ab05-04eb08e206de" +#database_name = "freshyo-backend-dev" +#database_id = "b2528bdb-0ec0-478e-8765-b118918153c0" +database_name = "freshyo-dev" +database_id = "3cad440f-dc14-4baa-ab05-04eb08e206de" migrations_dir="../../packages/db_helper_sqlite/drizzle" migrations_pattern="migration.sql" [durable_objects] diff --git a/change-log.txt b/change-log.txt index 10b9c8d..f374d1c 100644 --- a/change-log.txt +++ b/change-log.txt @@ -604,3 +604,31 @@ KEPT (per instruction / verification): §4 routes & affordances (rebalance-order Verification: - grep across apps/admin-ui: zero remaining references to any deleted file/symbol (only generated .expo cache regenerated clean). - tsc --noEmit: no errors in any file I edited. Remaining 19 admin-ui-local errors + backend errors are pre-existing (in untouched files: complaints, coupons/edit, customize-app, products, user-management, delivery-sequences lines 343/398 implicit-any, ProductGroupForm, ProductsSelector, ProductForm) — verified none are in modified regions. + +[2026-09-02 23:20:00] CREATED analysis script: scripts/dead-code/repeat-types.js (read-only type-declaration scanner, outputs scripts/dead-code/repeat-types-raw.json) + +[2026-09-03 00:10:00] EXECUTE repeat_types_dpsk.md cleanup — remove legacy doctor/hospital/token types (not relevant to meat-farmer app). + +PLANNED CHANGES: +=== packages/ui/shared-types.ts === +- DELETE all legacy doctor/hospital/token types (zero external references — verified by grep across apps + packages): + Person, User (hospital-era), Hospital, DoctorSpecialization, DoctorInfo, Doctor, DoctorDetails, + DashboardDoctor, TokenDoctor, UpcomingToken, PastToken, UpcomingAppointment, MyTokensResponse, + PastTokensResponse, BookTokenPayload, BookTokenResponse, DoctorAvailability, + DoctorAvailabilityWithDate, DoctorAvailabilityResponse, DoctorAvailabilityPayload, token_user, + PatientHistoryToken, PatientHistory, GetHospitalPatientHistoryResponse, PatientHistoryFilters +- DELETE shadowed meat-farmer duplicates that collide with packages/shared (also zero importers): + Order, Slot, Coupon (canonical copies live in packages/shared/types/{user.ts, admin.ts}) +- KEEP: CreateCouponPayload (only live export — imported by apps/admin-ui coupons via 'common-ui/shared-types') +- REMOVE trailing `export * from './token-types'` + +=== packages/ui/token-types.ts === +- DELETE entire file (DoctorTokenSummary, HospitalTodaysTokensResponse, DoctorTodayToken, DoctorTodaysTokensResponse — only re-exported by shared-types.ts:333, no external consumers) + +[2026-09-03 00:15:00] COMPLETED legacy doctor/hospital/token type removal. +- packages/ui/shared-types.ts: rewritten to contain ONLY CreateCouponPayload (the single live export). Removed 28 legacy doctor/hospital/token types + 3 shadowed meat-farmer duplicates (Order, Slot, Coupon — canonical copies live in packages/shared) + trailing `export * from './token-types'`. +- packages/ui/token-types.ts: deleted (4 token-summary types, zero external consumers). +Verification: +- grep across apps + packages: zero references to any removed legacy type name or the token-types module. +- CreateCouponPayload intact; its only importers (admin-ui coupons/edit/[id].tsx + src/components/CouponForm.tsx) unchanged. +- Pre-existing tsc error in coupons/edit/[id].tsx:92 (`skuIds` not in CreateCouponPayload) untouched and unrelated (predates this change; CreateCouponPayload body preserved byte-for-byte). diff --git a/packages/ui/shared-types.ts b/packages/ui/shared-types.ts index 6169ca5..4ce2601 100755 --- a/packages/ui/shared-types.ts +++ b/packages/ui/shared-types.ts @@ -1,275 +1,3 @@ -export type Person = { - name: string; - age: number; - email: string; -} - - -export interface User { - id: number; - name?: string | null; - email: string; - mobile: string; - profilePicUrl?: string; - address?: string; - joinDate?: Date; - specializations: DoctorSpecialization[] | null; - qualifications?: string; - hospital?: string; - hospitalId?: number; - consultationFee?: string; -} - -export interface Hospital { - id: number; - name: string; - description?: string; - address: string; - adminId?: number; - adminName?: string; - hospitalImages?: string[] -} - -export interface DoctorSpecialization { - id: number; - name: string | null; - description: string | null; -} - -export interface DoctorInfo { - id: number; - qualifications: string | null; - dailyTokenCount: number; - consultationFee: number | string; -} - -export interface Doctor { - id: number; - name: string; - username?: string | null; - email?: string | null; - mobile?: string; - doctorInfo?: DoctorInfo; - specializations?: DoctorSpecialization[] | null; - qualifications: string | null; -} - -export interface DoctorDetails { - id: number; - name: string; - username?: string | null; - email?: string | null; - mobile?: string; - profilePicUrl?: string | null; - address?: string | null; - joinDate?: string | null; - role: string; - roles: string[]; - doctorId: number; - qualifications?: string | null; - dailyTokenCount: number; - consultationFee: number; - hospital?: string; - hospitalId?: number; - description?: string | null; - yearsOfExperience?: number | null; - specializations: { - id: number; - name: string; - description: string | null; - }[]; - isConsultationsPaused: boolean; - pauseReason: string | null; -} - -// Define local DashboardDoctor type based on the API response structure -export interface DashboardDoctor { - availableTokens: number; - consultationFee: string; - consultationsDone: number; - currentConsultationNumber: number; - id: number; - isAvailable: boolean; - name: string; - profilePicUrl?: string | null; - qualifications: string | null; - tokensIssuedToday: number; - totalTokenCount: number; -} - -// Token types -export interface TokenDoctor { - id: number; - name: string; - mobile: string; - profilePicUrl: string | null; -} - -export interface UpcomingToken { - id: number; - tokenDate: string; - queueNumber: number; - description: string | null; - createdAt: string; - doctor: TokenDoctor; - currentConsultationNumber?: number; // Current consultation number for the doctor -} - -export interface PastToken { - id: number; - tokenDate: string; - queueNumber: number; - description: string | null; - createdAt: string; - doctor: TokenDoctor; - status?: 'COMPLETED' | 'MISSED' | 'CANCELLED'; - consultationNotes?: string | null; -} - -export interface UpcomingAppointment { - id: number; - doctorName: string; - doctorImageUrl?: string; - date: string; - hospital: string; - queueNumber: number; - status: string; -} - -export interface MyTokensResponse { - message: string; - tokens: UpcomingToken[]; -} - -export interface PastTokensResponse { - message: string; - tokens: PastToken[]; -} - -export interface BookTokenPayload { - doctorId: number; - userId: number; - tokenDate: string; - description?: string; -} - -export interface BookTokenResponse { - message: string; - token: { - id: number; - doctorId: number; - userId: number; - tokenDate: string; - queueNumber: number; - description: string | null; - createdAt: string; - }; -} - -// Doctor availability types -export interface DoctorAvailability { - id: number; - doctorId: number; - date: string; - totalTokenCount: number; - filledTokenCount: number; - consultationsDone: number; - isStopped: boolean; - availableTokens: number; - isPaused: boolean; - isLeave: boolean; - pauseReason: string | null; -} - -export interface DoctorAvailabilityWithDate { - date: string; - availability: DoctorAvailability | null; -} - -export interface DoctorAvailabilityResponse { - message: string; - doctorId: number; - availabilities: DoctorAvailabilityWithDate[]; -} - -export interface DoctorAvailabilityPayload { - doctorId: number; - date: string; - tokenCount: number; - isStopped?: boolean; - filledTokenCount?: number; - consultationsDone?: number; -} - - -export interface token_user { - id: number; - name: string; - mobile: string; - age: number; - gender: string; -} - -export interface Order { - id: string; - orderId: string; - readableId: string; - customerName: string; - address: string; - totalAmount: number; - items: { - name: string; - quantity: number; - price: number; - amount: number; - unit: string; - isPackaged: boolean; - isPackageVerified: boolean; - }[]; - deliveryTime: string; - status: 'pending' | 'delivered' | 'cancelled'; - isPackaged: boolean; - isDelivered: boolean; - isCod: boolean; - paymentMode: string; - paymentStatus: string; - slotId: number; -} - -export interface Slot { - id: number; - deliveryTime: string; - freezeTime: string; - isActive: boolean; - deliverySequence?: number[]; -} - -export interface Coupon { - id: number; - couponCode: string; - isUserBased: boolean; - discountPercent: string | null; - flatDiscount: string | null; - minOrder: string | null; - targetUser: { - id: number; - name: string | null; - mobile: string; - } | null; - productIds: number[] | null; - createdBy: number; - creator: { - id: number; - name: string | null; - } | null; - maxValue: string | null; - isApplyForAll: boolean; - validTill: Date | null; - maxLimitForUser: number | null; - isInvalidated: boolean; - createdAt: Date; -} - export interface CreateCouponPayload { couponCodes: string[]; discountPercent?: number; @@ -286,48 +14,3 @@ export interface CreateCouponPayload { applicableProducts?: number[]; exclusiveApply?: boolean; } - -// Patient History Types -export interface PatientHistoryToken { - id: number; - queueNum: number; - tokenDate: string; - doctorName: string; - status: string; - description: string; - consultationNotes?: string; -} - -export interface PatientHistory { - id: number; - name: string; - mobile: string; - age: number; - gender: string; - totalTokens: number; - completedTokens: number; - upcomingTokens: number; - firstVisitDate: string; - lastVisitDate: string; - tokens: PatientHistoryToken[]; -} - -export interface GetHospitalPatientHistoryResponse { - message: string; - patients: PatientHistory[]; - totalCount: number; - page: number; - limit: number; -} - -export interface PatientHistoryFilters { - patientIds?: string[]; - doctorIds?: string[]; - statuses?: string[]; - startDate?: string | null; - endDate?: string | null; -} - - -// Export the types from token-types.ts -export * from './token-types'; \ No newline at end of file diff --git a/packages/ui/token-types.ts b/packages/ui/token-types.ts deleted file mode 100755 index 9ff8e14..0000000 --- a/packages/ui/token-types.ts +++ /dev/null @@ -1,43 +0,0 @@ -// Adding the types for hospital today's tokens and doctor today's tokens -export interface DoctorTokenSummary { - id: number; - name: string; - specializations?: string[]; - totalTokens: number; - completedTokens: number; - inProgressTokens: number; - upcomingTokens: number; - currentTokenNumber?: number | null; - tokens?: DoctorTodayToken[]; // Added individual tokens -} - -export interface HospitalTodaysTokensResponse { - message: string; - hospitalId: number; - hospitalName: string; - date: string; - doctors: DoctorTokenSummary[]; -} - -export interface DoctorTodayToken { - id: number; - queueNumber: number; - patientId: number | null; - patientName: string; - patientMobile?: string; - description: string | null; - status: 'UPCOMING' | 'IN_PROGRESS' | 'COMPLETED' | 'MISSED' | 'CANCELLED'; // Made optional - // status: string; // 'UPCOMING' | 'IN_PROGRESS' | 'COMPLETED' | 'MISSED' | 'CANCELLED'; // Made optional - consultationNotes?: string | null; -} - -export interface DoctorTodaysTokensResponse { - message: string; - doctorId: number; - doctorName: string; - date: string; - currentTokenNumber?: number | null; - totalTokens: number; - completedTokens: number; - tokens: DoctorTodayToken[]; -} diff --git a/test-plan-neo.md b/test-plan-neo.md deleted file mode 100644 index 4d3f07f..0000000 --- a/test-plan-neo.md +++ /dev/null @@ -1,1489 +0,0 @@ -# Freshyo — Test Plan for Non-Technical Testers - -This plan tells you exactly what to do, step by step, and what you should see. You don't need to know any technical details. Just follow the steps and tick the tests that pass. - -**How to use this document** -- Each test has: - - **What you need** — the setup before you start. - - **Steps** — exactly what to tap/type/do. - - **Things to test** — the checklist of things you must try. - - **Expected** — what must happen for the test to PASS. -- If anything in **Expected** does not happen, that test has **FAILED** — note it down and tell the developer. -- Test on a phone/emulator with internet. Keep the app updated to the latest build. - ---- - -# PART 1 — ADMIN APP (the staff app, used by the shop team) - -## 1.1 Logging in - -### 1.1.1 Login with correct details -- **What you need:** Admin login (mobile + password) given by the developer. -- **Steps:** 1. Open the Admin app. 2. Type your mobile number. 3. Type your password. 4. Tap "Login". -- **Things to test:** Logging in with the correct mobile and password. -- **Expected:** The home screen (Dashboard) opens. - -### 1.1.2 Login with wrong password -- **What you need:** Admin app open on the login screen. -- **Steps:** 1. Type a wrong password. 2. Tap "Login". -- **Things to test:** What happens when the password is wrong. -- **Expected:** A red error message appears. You stay on the login screen. You are NOT logged in. - -### 1.1.3 Login with empty fields -- **What you need:** Login screen open. -- **Steps:** 1. Leave everything blank. 2. Tap "Login". -- **Things to test:** Tapping Login with nothing filled in. -- **Expected:** An error message appears telling you to fill the fields. Nothing else happens. - -### 1.1.4 Logout -- **What you need:** You are logged in. -- **Steps:** 1. Open the menu (side panel). 2. Tap "Logout". -- **Things to test:** Logging out from the menu. -- **Expected:** You go back to the login screen. - -### 1.1.5 Jump straight to a page without login -- **What you need:** You are logged out. -- **Steps:** 1. Ask the developer for a direct link to any page. 2. Open it. -- **Things to test:** Opening a protected page without being logged in. -- **Expected:** You are sent to the login screen first. - -## 1.2 Dashboard (home screen) - -### 1.2.1 Dashboard shows numbers -- **What you need:** Some orders, users and products exist. -- **Steps:** 1. Log in. 2. Look at the main screen. -- **Things to test:** The dashboard loads and shows the summary boxes. -- **Expected:** You see boxes with numbers: total orders, total users, total products. - -### 1.2.2 Refresh the dashboard -- **What you need:** Dashboard is open. -- **Steps:** 1. Put your finger on the screen and pull down. 2. Let go. -- **Things to test:** Pull-to-refresh. -- **Expected:** The numbers reload (may flicker). No error appears. - -### 1.2.3 Dashboard when there is no data -- **What you need:** A brand-new account with no data. -- **Steps:** 1. Log in with an empty account. -- **Things to test:** Dashboard with zero data. -- **Expected:** The numbers show 0. The screen does not crash. - -## 1.3 Products - -### 1.3.1 Product list -- **What you need:** At least 1 product exists. -- **Steps:** 1. Open the menu. 2. Tap "Products". -- **Things to test:** The product list loads and shows items. -- **Expected:** A list of products appears with pictures and names. - -### 1.3.2 Search products -- **What you need:** Many products exist. -- **Steps:** 1. Go to Products. 2. Type part of a product name in the search box. -- **Things to test:** Typing in the search box filters the list. -- **Expected:** Only matching products remain in the list. - -### 1.3.3 Add a normal product -- **What you need:** Admin login. -- **Steps:** 1. Go to Products. 2. Tap "Add Product". 3. Type a product name. 4. Add a photo. 5. Set a price. 6. Tap "Save". -- **Things to test:** Adding a product with all fields filled; the photo uploads. -- **Expected:** A success message appears. The new product is in the list. - -### 1.3.4 Add product without a name -- **What you need:** Add Product page open. -- **Steps:** 1. Leave the name empty. 2. Tap "Save". -- **Things to test:** Saving with a required field missing. -- **Expected:** A message tells you the name is required. Nothing is saved. - -### 1.3.5 Add a combo product -- **What you need:** Admin login. -- **Steps:** 1. Go to Products. 2. Tap "Add Product". 3. Choose "Combo" type. 4. Pick 2 or more items that make up the combo. 5. Set the combo price. 6. Tap "Save". -- **Things to test:** Adding a combo made of multiple items. -- **Expected:** The combo appears in the list. - -### 1.3.6 Edit a product -- **What you need:** A product exists. -- **Steps:** 1. Go to Products. 2. Tap a product. 3. Tap "Edit". 4. Change the name or price. 5. Tap "Save". -- **Things to test:** Changing a product's name and price. -- **Expected:** Success message. The product shows the new name/price. - -### 1.3.7 Delete a product -- **What you need:** A product exists. -- **Steps:** 1. Go to Products. 2. Tap a product. 3. Tap "Delete". 4. Confirm "Yes". -- **Things to test:** Deleting a product and the confirmation box. -- **Expected:** Success message. The product disappears from the list. - -### 1.3.8 View product details -- **What you need:** A product exists. -- **Steps:** 1. Go to Products. 2. Tap a product. -- **Things to test:** The details page shows all product information. -- **Expected:** You see the product's photos, prices, sizes, reviews and tags. - -### 1.3.9 Update many prices at once -- **What you need:** Products exist. -- **Steps:** 1. Open menu. 2. Tap "Prices Overview". 3. Change some prices in the table. 4. Tap "Save". -- **Things to test:** Changing several prices in one go. -- **Expected:** Success message. Prices are updated. - -### 1.3.10 Add a product with a name that already exists -- **What you need:** A product with the same name exists. -- **Steps:** 1. Go to Products. 2. Tap "Add Product". 3. Type the same name as an existing product. 4. Tap "Save". -- **Things to test:** Duplicate product names. -- **Expected:** An error message says a product with this name already exists. Nothing is saved. - -### 1.3.11 Add a product with zero or negative price -- **What you need:** Add Product page open. -- **Steps:** 1. Enter a price of 0 or a negative number (e.g. -10). 2. Tap "Save". -- **Things to test:** Invalid price values. -- **Expected:** A validation error says the price must be a positive number. Nothing is saved. - -### 1.3.12 Add a product with no SKU features -- **What you need:** Add Product page open. -- **Steps:** 1. Fill the product name and store. 2. Add a SKU but no feature (no size/quantity). 3. Tap "Save". -- **Things to test:** A SKU with no features. -- **Expected:** A validation error says at least one feature is required. - -### 1.3.13 Edit a product — replace the photo -- **What you need:** A product with a photo exists. -- **Steps:** 1. Open the product. 2. Tap "Edit". 3. Upload a new photo in place of the old one. 4. Tap "Save". -- **Things to test:** Replacing a product photo. -- **Expected:** The new photo is saved. The old photo is removed (not left behind). - -### 1.3.14 Add a product with a negative market price or flash price -- **What you need:** Add Product page open. -- **Steps:** 1. Enter a negative market price (e.g. -10). 2. Try to save. 3. Repeat with a negative flash price. -- **Things to test:** Negative market/flash prices. -- **Expected:** A validation error says the price cannot be negative. Nothing is saved. - -## 1.4 Product Tags (labels like "Chicken", "Bestseller") - -### 1.4.1 Tag list -- **What you need:** At least 1 tag exists. -- **Steps:** 1. Open menu. 2. Tap "Product Tags". -- **Things to test:** The tag list loads with cards. -- **Expected:** Cards appear, each with a tag name, picture (if any) and a green "Dashboard Tag" mark (if it is one). - -### 1.4.2 Add a tag -- **What you need:** Admin login. -- **Steps:** 1. Go to Product Tags. 2. Tap "Add New Tag". 3. Type a name. 4. (Optional) add a picture. 5. (Optional) tick "Mark as Dashboard Tag". 6. (Optional) pick related stores. 7. Tap "Create Tag". -- **Things to test:** Adding a tag with and without a picture; ticking the Dashboard Tag box; picking stores. -- **Expected:** Success message. The tag appears in the list. - -### 1.4.3 Add a tag with a name that already exists -- **What you need:** A tag with the same name exists. -- **Steps:** 1. Go to Product Tags. 2. Tap "Add New Tag". 3. Type the same name as an existing tag. 4. Tap "Create Tag". -- **Things to test:** Duplicate tag names. -- **Expected:** An error message says a tag with this name already exists. - -### 1.4.4 Add products to a tag -- **What you need:** At least 2 products exist. -- **Steps:** 1. Go to Product Tags. 2. Tap "Add New Tag". 3. Type a name. 4. Scroll to "Products". 5. Tap the product selector and pick 2–3 products. 6. Check the products appear as a list under it. 7. Tap "Create Tag". -- **Things to test:** Selecting products for a tag; the selected products appearing in a list in the order picked. -- **Expected:** The chosen products show as a list, in the order you picked them. - -### 1.4.5 Reorder products inside a tag -- **What you need:** You are on the Add/Edit Tag page with products added. -- **Steps:** 1. Press and hold the drag handle (six dots) of a product. 2. Drag it up or down. 3. Let go. 4. Tap Save/Create. -- **Things to test:** Dragging a product to a new position; the order is kept after saving and reopening. -- **Expected:** The product moves to the new position. After saving and reopening, the order is the same. - -### 1.4.6 Remove a product from a tag -- **What you need:** Tag page has products. -- **Steps:** 1. Tap the "X" on a product in the list. -- **Things to test:** Removing one product from the tag. -- **Expected:** The product disappears from the list. - -### 1.4.7 Edit a tag — products come back automatically -- **What you need:** A tag that already has products. -- **Steps:** 1. Go to Product Tags. 2. Tap the three dots on a tag. 3. Tap "Edit Tag". -- **Things to test:** That the products already in the tag are pre-filled when editing. -- **Expected:** The tag's products are already filled in the list, in the saved order. - -### 1.4.8 Delete a tag -- **What you need:** A tag exists. -- **Steps:** 1. Go to Product Tags. 2. Tap the three dots on a tag. 3. Tap "Delete". 4. Confirm. -- **Things to test:** Deleting a tag and the confirmation box. -- **Expected:** Success message. The tag disappears. - -### 1.4.9 Tag Orders page — reorder the tags themselves -- **What you need:** At least 2 tags exist. -- **Steps:** 1. Go to Product Tags. 2. Tap "Tag Orders". 3. Press and hold the drag handle of a tag. 4. Drag it to a new position. 5. Tap "Save". -- **Things to test:** Dragging tags into a new order and saving. -- **Expected:** Success message. The order is saved. (The customer app will show tabs in this order.) - -### 1.4.10 Tag Orders page — no tags -- **What you need:** No tags exist. -- **Steps:** 1. Go to Product Tags. 2. Tap "Tag Orders". -- **Things to test:** The page with zero tags. -- **Expected:** A message "No tags available" appears. - -### 1.4.11 Tag Orders — Save button before any change -- **What you need:** Tag Orders page open. -- **Steps:** 1. Look at the "Save" button without dragging anything. -- **Things to test:** The Save button state before any change. -- **Expected:** The Save button is greyed out / cannot be tapped. - -## 1.5 Product Groups - -### 1.5.1 Create a group -- **What you need:** Products exist. -- **Steps:** 1. Open menu. 2. Tap "Product Groupings". 3. Tap "Create". 4. Type a group name. 5. Pick products. 6. Tap "Save". -- **Things to test:** Creating a group with a name and products. -- **Expected:** Success message. Group appears in the list. - -### 1.5.2 Create group with duplicate name -- **What you need:** A group with the same name exists. -- **Steps:** 1. Create a group with the same name again. -- **Things to test:** Duplicate group names. -- **Expected:** Error message. - -### 1.5.3 Edit and delete a group -- **What you need:** A group exists. -- **Steps:** 1. Tap the group. 2. Edit the name. 3. Save. 4. Then delete it and confirm. -- **Things to test:** Editing then deleting a group. -- **Expected:** Edit saves; delete removes it from the list. - -## 1.6 Stores - -### 1.6.1 Store list -- **What you need:** Stores exist. -- **Steps:** 1. Open menu. 2. Tap "Stores". -- **Things to test:** The store list loads. -- **Expected:** Cards with store names and photos. - -### 1.6.2 Add a store -- **What you need:** Admin login. -- **Steps:** 1. Go to Stores. 2. Tap "Add". 3. Type a name. 4. Add a photo. 5. Type a description. 6. Tap "Save". -- **Things to test:** Adding a store with photo and description. -- **Expected:** Success message. Store appears. - -### 1.6.3 Edit a store -- **What you need:** A store exists. -- **Steps:** 1. Tap the store. 2. Tap "Edit". 3. Change the name. 4. Save. -- **Things to test:** Editing a store's name. -- **Expected:** New name is saved. - -### 1.6.4 Delete a store -- **What you need:** A store exists. -- **Steps:** 1. Tap the store. 2. Tap "Delete". 3. Confirm. -- **Things to test:** Deleting a store and the confirmation box. -- **Expected:** Store disappears. - -### 1.6.5 Add a store without a photo -- **What you need:** On Add Store page. -- **Steps:** 1. Fill name only, no photo. 2. Save. -- **Things to test:** Adding a store with no photo. -- **Expected:** Store is created; a placeholder icon shows instead of a photo. - -## 1.7 Delivery Slots (delivery times) - -### 1.7.1 Slot list -- **What you need:** Slots exist. -- **Steps:** 1. Open menu. 2. Tap "Slots". -- **Things to test:** The slot list loads. -- **Expected:** A list of slots with delivery time, order-close time and capacity. - -### 1.7.2 Add a slot -- **What you need:** Admin login. -- **Steps:** 1. Go to Slots. 2. Tap "Add". 3. Pick a delivery time (future). 4. Pick an order-close time (before delivery). 5. Pick products for this slot. 6. Tap "Save". -- **Things to test:** Adding a slot with future times and products. -- **Expected:** Success message. Slot appears in the list. - -### 1.7.3 Add a slot with a past delivery time -- **What you need:** Add Slot page open. -- **Steps:** 1. Pick a delivery time in the past. 2. Try to save. -- **Things to test:** Saving a slot with a past time. -- **Expected:** An error tells you the time must be in the future. - -### 1.7.4 Add a slot where close time is after delivery time -- **What you need:** Add Slot page open. -- **Steps:** 1. Set close time later than delivery time. 2. Try to save. -- **Things to test:** Close time after delivery time. -- **Expected:** An error appears. - -### 1.7.5 Edit a slot -- **What you need:** A slot exists. -- **Steps:** 1. Tap the slot. 2. Edit the time or products. 3. Save. -- **Things to test:** Editing a slot's time and products. -- **Expected:** Saved. (The customer app will show the change within a minute.) - -### 1.7.6 Delete a slot -- **What you need:** A slot exists. -- **Steps:** 1. Tap the slot. 2. Delete. 3. Confirm. -- **Things to test:** Deleting a slot and the confirmation box. -- **Expected:** Slot disappears. - -### 1.7.7 Turn slot capacity off -- **What you need:** A slot exists. -- **Steps:** 1. Tap the slot. 2. Find the "Capacity Full" switch. 3. Turn it on. 4. Check it stays on. -- **Things to test:** Marking a slot as full. -- **Expected:** The slot is now marked full and customers can no longer pick it. - -### 1.7.8 Copy (replicate) an existing slot -- **What you need:** A slot exists. -- **Steps:** 1. On the Slots page, find the "Replicate"/"Copy" option on a slot. 2. Tap it. 3. Change the delivery time to a new future time. 4. Tap "Save". -- **Things to test:** Copying a slot and saving it as a new one. -- **Expected:** The Add Slot form opens pre-filled with the copied slot's products and times. Saving creates a NEW slot (the original is unchanged). - -## 1.8 Manage Orders - -### 1.8.1 Orders list -- **What you need:** At least 1 order exists. -- **Steps:** 1. Open menu. 2. Tap "Manage Orders". 3. Tap "Orders". -- **Things to test:** The orders list loads with cards. -- **Expected:** Cards appear with customer name, order number, time, slot and total. - -### 1.8.2 Filter by slot -- **What you need:** More than 1 slot with orders. -- **Steps:** 1. On Orders, tap the "Select Slot" dropdown at top. 2. Pick one slot. -- **Things to test:** Filtering orders by a slot. -- **Expected:** Only orders for that slot remain. - -### 1.8.3 Flash orders filter -- **What you need:** At least 1 flash (1-hour) order. -- **Steps:** 1. Tap the dropdown. 2. Pick "⚡ Flash Deliveries". -- **Things to test:** The flash filter. -- **Expected:** Only flash orders remain. - -### 1.8.4 Packaged / Delivered filters -- **What you need:** Orders exist. -- **Steps:** 1. Tap the filter icon (funnel). 2. Tick "Packaged". 3. Tap Done. -- **Things to test:** Each status filter (Packaged, Delivered, Cancelled, Delivery Type). -- **Expected:** Only matching orders show for each filter. - -### 1.8.5 Mark an order as packaged -- **What you need:** An order exists. -- **Steps:** 1. On an order card, tap the "Packaged" checkbox. -- **Things to test:** Ticking the packaged box on the card. -- **Expected:** The box gets a tick. - -### 1.8.6 Mark an order as delivered -- **What you need:** An order exists. -- **Steps:** 1. On an order card, tap the "Delivered" checkbox. -- **Things to test:** Ticking the delivered box on the card. -- **Expected:** The box gets a tick. - -### 1.8.7 Items count on card -- **What you need:** An order with 3 items. -- **Steps:** 1. Look at the card. -- **Things to test:** The item count text. -- **Expected:** It says "3 items". - -### 1.8.8 Order menu (three dots) -- **What you need:** An order exists. -- **Steps:** 1. Tap the three dots on a card. -- **Things to test:** The menu opens with all options: View Details, Packaged, Delivered, Admin Notes, Cancel Order, Attach Location, WhatsApp, Dial. -- **Expected:** Menu opens and every option works when tapped. - -### 1.8.9 Open order details -- **What you need:** An order exists. -- **Steps:** 1. Tap an order card. -- **Things to test:** The order details page shows everything. -- **Expected:** Full order page: items, quantities, prices, address, status, notes. - -### 1.8.10 Toggle item packaging inside an order -- **What you need:** Order has items. -- **Steps:** 1. Open order details. 2. Tap "pkg" checkbox on an item. -- **Things to test:** The pkg and verf checkboxes on each item. -- **Expected:** Box ticks. Same for "verf". - -### 1.8.11 Remove delivery charge -- **What you need:** An order with delivery charge. -- **Steps:** 1. Open order details. 2. Find "Remove Delivery Charge". 3. Tap it. -- **Things to test:** Removing the delivery charge. -- **Expected:** Charge becomes zero; total drops. - -### 1.8.12 Add admin notes -- **What you need:** An order exists. -- **Steps:** 1. Open order details. 2. Tap "Admin Notes". 3. Type a note. 4. Tap "Save". -- **Things to test:** Adding and saving a note. -- **Expected:** Success message. Note shows when reopened. - -### 1.8.13 Cancel an order with a reason -- **What you need:** A non-cancelled order. -- **Steps:** 1. Open the three-dot menu. 2. Tap "Cancel Order". 3. Type a reason. 4. Confirm. -- **Things to test:** Cancelling with a reason; the reason is required. -- **Expected:** Order shows as Cancelled. - -### 1.8.14 Delivery sequence page -- **What you need:** A slot exists. -- **Steps:** 1. Open menu. 2. Tap "Manage Orders". 3. Tap "Delivery Sequences". 4. Pick a slot. -- **Things to test:** Viewing and reordering the delivery sequence. -- **Expected:** The delivery order of orders shows. You can reorder and save. - -### 1.8.15 Rebalance orders -- **What you need:** 2 slots with orders. -- **Steps:** 1. Open menu. 2. Tap "Rebalance Orders". 3. Pick source and target slots. 4. Tap "Rebalance". -- **Things to test:** Moving orders between slots. -- **Expected:** Orders move; success message. - -### 1.8.16 Loading more orders -- **What you need:** 50+ orders. -- **Steps:** 1. On Orders, scroll to the bottom. -- **Things to test:** Infinite scroll. -- **Expected:** More orders load automatically. - -### 1.8.17 Cancel an order that is already cancelled or delivered -- **What you need:** A cancelled order (or a delivered order). -- **Steps:** 1. Open the order. 2. Try to cancel it again. -- **Things to test:** Cancelling an already-cancelled or delivered order. -- **Expected:** An error appears or the cancel option is disabled. The order state does not change. - -### 1.8.18 Delivery sequence — bulk unassign and reassign orders -- **What you need:** A slot with orders assigned to delivery staff. -- **Steps:** 1. Open Delivery Sequences. 2. Select several orders. 3. Tap "Unassign". 4. Select the orders again. 5. Assign them to a different staff member. 6. Save. -- **Things to test:** Unassigning multiple orders at once and moving them to another staff member. -- **Expected:** Unassigned orders leave the staff member's list. After reassigning and saving, they appear under the new staff member. - -## 1.9 Coupons (discount codes) - -### 1.9.1 Coupon list -- **What you need:** Coupons exist. -- **Steps:** 1. Open menu. 2. Tap "Coupons". -- **Things to test:** The coupon list loads. -- **Expected:** Coupons listed with code and discount. - -### 1.9.2 Create a percentage coupon -- **What you need:** Admin login. -- **Steps:** 1. Go to Coupons. 2. Tap "Create". 3. Type a code. 4. Choose Percentage. 5. Enter 10 (for 10%). 6. Pick which products it applies to. 7. Pick an expiry date. 8. Save. -- **Things to test:** Creating a percentage coupon with products and expiry. -- **Expected:** Success message. Coupon in the list. - -### 1.9.3 Create a coupon with discount over 100% -- **What you need:** Create Coupon page. -- **Steps:** 1. Choose Percentage. 2. Enter 150. 3. Try to save. -- **Things to test:** An invalid discount value. -- **Expected:** An error says the discount is invalid. - -### 1.9.4 Edit and delete a coupon -- **What you need:** A coupon exists. -- **Steps:** 1. Tap the coupon. 2. Edit the discount. 3. Save. 4. Then delete and confirm. -- **Things to test:** Editing then deleting a coupon. -- **Expected:** Edit saves; delete removes it. - -### 1.9.5 Reserved coupons -- **What you need:** Admin login. -- **Steps:** 1. Go to Coupons. 2. Tap "Reserved Coupons". 3. Create one and assign it to a user. -- **Things to test:** Creating a reserved coupon for a specific user. -- **Expected:** The coupon shows as reserved for that user. - -### 1.9.6 Create a coupon with BOTH percentage and flat discount -- **What you need:** Create Coupon page open. -- **Steps:** 1. Fill in a percentage discount AND a flat amount. 2. Try to save. -- **Things to test:** Both discount types at once. -- **Expected:** An error says you can only have one discount type. Nothing is saved. - -### 1.9.7 Create a coupon with NO discount -- **What you need:** Create Coupon page open. -- **Steps:** 1. Leave both percentage and flat discount empty. 2. Try to save. -- **Things to test:** No discount at all. -- **Expected:** An error says a discount is required. Nothing is saved. - -### 1.9.8 Coupon code format and auto-uppercase -- **What you need:** Create Coupon page open. -- **Steps:** 1. Type a code with spaces or symbols (e.g. "SAVE 20!"). 2. Type a code in lowercase (e.g. "save10"). -- **Things to test:** Invalid characters and lowercase codes. -- **Expected:** Invalid characters are rejected with an error. A valid code is auto-uppercased when saved. - -### 1.9.9 Create a coupon with a code that already exists -- **What you need:** A coupon with the same code exists. -- **Steps:** 1. Create a coupon with the same code as an existing one. -- **Things to test:** Duplicate coupon codes. -- **Expected:** An error says the coupon code already exists. - -### 1.9.10 User-based coupon without users and without "apply to all" -- **What you need:** Create Coupon page open. -- **Steps:** 1. Mark the coupon as user-based. 2. Do NOT pick any users. 3. Do NOT tick "apply to all". 4. Try to save. -- **Things to test:** User-based coupon with no recipients. -- **Expected:** An error asks you to add users or enable apply-to-all. - -### 1.9.11 User-based coupon AND "apply to all" both on -- **What you need:** Create Coupon page open. -- **Steps:** 1. Mark the coupon as user-based. 2. Pick users. 3. ALSO tick "apply to all". 4. Try to save. -- **Things to test:** Conflicting coupon audience settings. -- **Expected:** An error says the coupon cannot be both user-based and apply-to-all. - -## 1.10 Users - -### 1.10.1 User list -- **What you need:** Users exist. -- **Steps:** 1. Open menu. 2. Tap "Users" or "User Management". -- **Things to test:** The user list loads. -- **Expected:** Users listed with names and numbers. - -### 1.10.2 Open a user's details -- **What you need:** A user exists. -- **Steps:** 1. Tap a user. -- **Things to test:** The user details page. -- **Expected:** Profile, orders and incidents show. - -### 1.10.3 Suspend a user -- **What you need:** A user exists. -- **Steps:** 1. Open the user. 2. Tap "Suspend". 3. Confirm. -- **Things to test:** Suspending a user. -- **Expected:** User is suspended. (That user can no longer log in to the customer app.) - -### 1.10.4 Unsuspend a user -- **What you need:** A suspended user. -- **Steps:** 1. Open the user. 2. Tap "Unsuspend". -- **Things to test:** Unsuspending a user. -- **Expected:** User can log in again. - -### 1.10.5 Add an incident to a user -- **What you need:** A user exists. -- **Steps:** 1. Open the user. 2. Tap "Add Incident". 3. Type a note. 4. Save. -- **Things to test:** Adding an incident note. -- **Expected:** The incident shows in the user's history. - -### 1.10.6 Send a notification -- **What you need:** Users exist. -- **Steps:** 1. Open menu. 2. Tap "Send Notifications". 3. Pick users. 4. Type a message. 5. Send. -- **Things to test:** Sending a push notification. -- **Expected:** Success message. The customers receive a phone notification. - -### 1.10.7 Create a user by mobile number -- **What you need:** Admin login. -- **Steps:** 1. Go to Users. 2. Tap "Create User". 3. Type a valid mobile number. 4. Tap "Save". -- **Things to test:** Creating a user by mobile only. -- **Expected:** Success message. The user appears in the user list. - -### 1.10.8 Staff with a limited role -- **What you need:** A staff account with a limited role (ask the developer to set one up). -- **Steps:** 1. Log in with the limited-role staff account. 2. Open the menu and try to open every section. 3. Try an action you should NOT be allowed to do. -- **Things to test:** What a limited-role staff member can and cannot see/do. -- **Expected:** The staff member sees only the sections their role allows. Tapping a restricted section shows an error or hides it — never lets them in. - -## 1.11 Banners (big pictures on the customer home) - -### 1.11.1 Banner list -- **What you need:** Banners exist. -- **Steps:** 1. Open menu. 2. Tap "Dashboard Banners". -- **Things to test:** The banner list loads. -- **Expected:** Banners listed. - -### 1.11.2 Create a banner -- **What you need:** Admin login. -- **Steps:** 1. Go to Banners. 2. Tap "Create". 3. Add a picture. 4. Link a product (optional). 5. Save. -- **Things to test:** Creating a banner with a picture and a linked product. -- **Expected:** Success message. Banner in the list. - -### 1.11.3 Edit and delete a banner -- **What you need:** A banner exists. -- **Steps:** 1. Tap the banner. 2. Edit. 3. Save. 4. Then delete and confirm. -- **Things to test:** Editing then deleting a banner. -- **Expected:** Edit saves; delete removes it. - -### 1.11.4 Banner order (position) -- **What you need:** At least 2 banners exist. -- **Steps:** 1. Open Dashboard Banners. 2. Set position 1 on one banner and position 2 on another. 3. Save. 4. Wait up to 1 minute. 5. Open the customer app Home. -- **Things to test:** Banner positions 1–4. -- **Expected:** Banners appear on the customer home in the order of their positions. Setting a position that's taken moves the other banner. - -### 1.11.5 Create a banner with a name that already exists -- **What you need:** A banner with the same name exists. -- **Steps:** 1. Create a banner with the same name as an existing one. -- **Things to test:** Duplicate banner names. -- **Expected:** An error says a banner with this name already exists. - -## 1.12 Customize App (settings) - -### 1.12.1 Change a setting -- **What you need:** Admin login. -- **Steps:** 1. Open menu. 2. Tap "Customize App". 3. Change a value (e.g. delivery charge). 4. Save. -- **Things to test:** Changing and saving a setting. -- **Expected:** Success message. Value saved. - -### 1.12.2 Popular items order -- **What you need:** Products exist. -- **Steps:** 1. Go to Customize App. 2. Tap "Popular Items". 3. Drag items into a new order. 4. Save. -- **Things to test:** Dragging items to reorder. -- **Expected:** Order saved. (Customer app home shows those products.) - -### 1.12.3 All items order -- **What you need:** Products exist. -- **Steps:** 1. Go to Customize App. 2. Tap "All Items Order". 3. Drag items. 4. Save. -- **Things to test:** Dragging items to reorder. -- **Expected:** Order saved. - -## 1.13 Complaints (customer issues) - -### 1.13.1 Complaint list -- **What you need:** Complaints exist. -- **Steps:** 1. Open menu. 2. Tap "Complaints". -- **Things to test:** The complaint list loads. -- **Expected:** Complaints listed with status. - -### 1.13.2 Resolve a complaint -- **What you need:** A pending complaint. -- **Steps:** 1. Tap the complaint. 2. Tap "Resolve". -- **Things to test:** Resolving a complaint. -- **Expected:** Status changes to Resolved. - -### 1.13.3 Reply to a complaint (chat) -- **What you need:** An open complaint with messages. -- **Steps:** 1. Open the complaint. 2. Type a reply to the customer. 3. Send. -- **Things to test:** Two-way complaint chat. -- **Expected:** The reply is saved. When the customer opens the complaint, they see your reply. - -## 1.14 Vendor Snippets - -### 1.14.1 Snippet list -- **What you need:** Snippets exist. -- **Steps:** 1. Open menu. 2. Tap "Vendor Snippets". -- **Things to test:** The snippet list loads. -- **Expected:** Snippets listed. - -### 1.14.2 Create a snippet -- **What you need:** Admin login. -- **Steps:** 1. Go to Vendor Snippets. 2. Tap "Create". 3. Type a code. 4. Pick products. 5. Set valid-until date. 6. Save. -- **Things to test:** Creating a snippet with code and products. -- **Expected:** Success. Snippet in list. - -### 1.14.3 Create snippet with a code that already exists -- **What you need:** Same code exists. -- **Steps:** 1. Create with the same code. -- **Things to test:** Duplicate snippet codes. -- **Expected:** Error message. - -### 1.14.4 Edit and delete a snippet -- **What you need:** A snippet exists. -- **Steps:** 1. Tap the snippet. 2. Edit. 3. Save. 4. Then delete and confirm. -- **Things to test:** Editing then deleting a snippet. -- **Expected:** Edit saves; delete removes it. - -## 1.15 General checks on every admin page - -### 1.15.1 Loading sign -- **What you need:** Any page. -- **Steps:** 1. Open a page with slow internet (switch to slow network). -- **Things to test:** The loading indicator on a slow connection. -- **Expected:** A spinner shows while loading, then the page appears. - -### 1.15.2 Empty page -- **What you need:** A page with no data. -- **Steps:** 1. Open any list page with nothing in it. -- **Things to test:** Every list page with zero items. -- **Expected:** A friendly "No ... yet" message shows. No crash. - -### 1.15.3 Server error -- **What you need:** Developer switches the server off. -- **Steps:** 1. Open any page. -- **Things to test:** The error screen and the Retry button. -- **Expected:** An error screen or red message shows with a "Retry" button. Tapping Retry works when the server is back. - -### 1.15.4 Double-tap save -- **What you need:** Any Create page. -- **Steps:** 1. Fill the form. 2. Tap Save twice very fast. -- **Things to test:** Double-tapping Save. -- **Expected:** Only one item is created (no duplicates). - -### 1.15.5 Red warning text -- **What you need:** Any screen. -- **Steps:** 1. Watch the bottom of the screen for red/yellow warning boxes while using the app. -- **Things to test:** No developer warnings on any screen. -- **Expected:** No warnings like "Text strings must be rendered..." appear. - -### 1.15.6 Session expired while using the app -- **What you need:** You are logged in. Ask the developer to expire your login session. -- **Steps:** 1. Use the app after the session has expired (open a page or tap an action). -- **Things to test:** What happens when the login expires mid-use. -- **Expected:** The app signs you out and returns you to the login screen with a message. No crash. - -### 1.15.7 Leaving a form with unsaved changes -- **What you need:** Any admin form (e.g. Add/Edit Product). -- **Steps:** 1. Type or change something in the form. 2. Tap the back button / navigate away WITHOUT saving. -- **Things to test:** Navigating away with unsaved changes. -- **Expected:** The app warns you that you have unsaved changes (or you return to the form). You are not silently taken away losing your work. - ---- - -# PART 2 — CUSTOMER APP (the app customers use) - -## 2.1 Login / Sign up - -### 2.1.1 Login with OTP -- **What you need:** Your mobile number. -- **Steps:** 1. Open the app. 2. Type your mobile number. 3. Tap "Get OTP". 4. Enter the OTP you receive by SMS. 5. Tap "Verify". -- **Things to test:** Receiving the OTP, entering it, and getting logged in. -- **Expected:** You are logged in and land on the Home screen. - -### 2.1.2 Wrong OTP -- **What you need:** OTP screen open. -- **Steps:** 1. Type a wrong OTP. 2. Tap Verify. -- **Things to test:** Entering an incorrect OTP. -- **Expected:** Error message "Invalid OTP". You can try again. - -### 2.1.3 Resend OTP -- **What you need:** OTP sent, not entered. -- **Steps:** 1. Wait for the resend timer. 2. Tap "Resend OTP". -- **Things to test:** The resend timer and resend button. -- **Expected:** A new OTP arrives. - -### 2.1.4 Register a new account -- **What you need:** A mobile number never used. -- **Steps:** 1. On login, tap "New user / Register". 2. Enter your name and number. 3. Verify OTP. -- **Things to test:** Creating a brand-new account. -- **Expected:** Account created. You are logged in. - -### 2.1.5 Register with a number already used -- **What you need:** An existing number. -- **Steps:** 1. Try to register with a number already registered. -- **Things to test:** Registering with a used number. -- **Expected:** A message says the number is already registered (use login). - -### 2.1.6 Change password -- **What you need:** Logged in. -- **Steps:** 1. Go to Me. 2. Tap "Change Password". 3. Enter old and new password. 4. Save. -- **Things to test:** Changing the password with old + new. -- **Expected:** Success. Old password no longer works. - -### 2.1.7 Delete account -- **What you need:** Logged in. -- **Steps:** 1. Go to Me. 2. Tap "Delete Account". 3. Confirm. -- **Things to test:** Deleting the account and the confirmation. -- **Expected:** Account deleted. You are logged out. - -### 2.1.8 Delete account — wrong mobile number -- **What you need:** Logged in, on the Delete Account screen. -- **Steps:** 1. When asked to confirm your mobile number, type a DIFFERENT number. 2. Tap Confirm. -- **Things to test:** Confirming deletion with the wrong number. -- **Expected:** An error says the number does not match. The account is NOT deleted. - -### 2.1.9 Login with email + password -- **What you need:** An account that has a password set. -- **Steps:** 1. On the login screen, switch to "Password" login. 2. Type your email. 3. Type your password. 4. Tap Login. -- **Things to test:** Logging in with email and password. -- **Expected:** You are logged in and land on Home. - -### 2.1.10 Login with mobile + password -- **What you need:** An account with a password. -- **Steps:** 1. On password login, type your mobile number instead of email. 2. Type your password. 3. Tap Login. -- **Things to test:** Logging in with mobile and password. -- **Expected:** Login succeeds. - -### 2.1.11 Register with email + password -- **What you need:** A fresh email and mobile. -- **Steps:** 1. Tap "Register". 2. Enter name, email, mobile and a password (6+ characters). 3. Accept the terms. 4. Tap Register. -- **Things to test:** Registering with full details. -- **Expected:** Account created. You are logged in and land on Home. - -### 2.1.12 Register — weak password or mismatched confirm -- **What you need:** Registration form open. -- **Steps:** 1. Enter a password shorter than 6 characters. 2. Try again entering different passwords in the two password boxes. -- **Things to test:** Weak and mismatched passwords. -- **Expected:** A validation error appears. Nothing is submitted. - -### 2.1.13 Terms checkbox blocks login/register -- **What you need:** Login or Register screen open. -- **Steps:** 1. Fill in valid details but do NOT tick the Terms checkbox. 2. Tap Login/Register. -- **Things to test:** Proceeding without accepting terms. -- **Expected:** The button is disabled or an error asks you to accept the terms. - -### 2.1.14 OTP — reuse a code already used -- **What you need:** You logged in once with an OTP. -- **Steps:** 1. Log out. 2. Try to log in again with the SAME OTP code. -- **Things to test:** Reusing an OTP. -- **Expected:** An error says the OTP is not valid or has expired. The code can only be used once. - -### 2.1.15 OTP — verify without requesting one -- **What you need:** Login screen open. -- **Steps:** 1. Type any 4-digit code without ever tapping "Get OTP". -- **Things to test:** Verifying an OTP that was never sent. -- **Expected:** An error says "OTP not sent or expired". - -### 2.1.16 OTP — expired code -- **What you need:** An OTP sent more than 5 minutes ago (or ask the developer to expire it). -- **Steps:** 1. Enter the old OTP. 2. Tap Verify. -- **Things to test:** Using an expired OTP. -- **Expected:** An error says the OTP is not valid or has expired. You must request a new one. - -### 2.1.17 OTP resend cooldown survives closing the app -- **What you need:** An OTP was just sent. -- **Steps:** 1. Close the app completely. 2. Reopen it. 3. Look at the resend button. -- **Things to test:** The resend timer after restarting the app. -- **Expected:** The resend cooldown is still running (button still disabled with a timer). You cannot resend before it finishes. - -### 2.1.18 Google sign-in button -- **What you need:** Login screen open. -- **Steps:** 1. Tap the "Sign in with Google" button. -- **Things to test:** The Google sign-in button. -- **Expected:** The app does not crash. (If Google sign-in is not ready yet, the button may do nothing or show a "coming soon" message — that is acceptable for now.) - -### 2.1.19 Session expired while using the app -- **What you need:** Logged in. Ask the developer to expire your login. -- **Steps:** 1. Use the app after the session has expired. -- **Things to test:** What happens when the login expires mid-use. -- **Expected:** You are signed out and returned to the login screen. No crash. - -## 2.2 Home screen - -### 2.2.1 App opens fast without a loading screen -- **What you need:** You have used the app before (data saved on phone). -- **Steps:** 1. Close the app completely. 2. Open it again. -- **Things to test:** The app start speed with saved data. -- **Expected:** The home screen appears right away. You do NOT see "Loading app settings…" for a long time. - -### 2.2.2 First ever open (no saved data) -- **What you need:** Fresh install. -- **Steps:** 1. Install the app fresh. 2. Open it. -- **Things to test:** The very first launch with no saved data. -- **Expected:** Home appears. Products do NOT show as "out of stock" during loading, then settle to correct status. - -### 2.2.3 Search bar -- **What you need:** Products exist. -- **Steps:** 1. Tap the search bar at top. 2. Type a product name. 3. Tap search. -- **Things to test:** Searching for a product. -- **Expected:** A search results page opens with matching products. - -### 2.2.4 Our Stores section -- **What you need:** Stores exist. -- **Steps:** 1. Scroll the home screen. 2. Look at "Our Stores". -- **Things to test:** The stores grid and tapping a store. -- **Expected:** Store logos in a grid (4 per row). Tapping one opens the Stores tab. - -### 2.2.5 Banner pictures -- **What you need:** Banners exist. -- **Steps:** 1. Look at the top of home. -- **Things to test:** The banner slideshow and dots; tapping a banner. -- **Expected:** Big pictures slide automatically with dots. Tapping one opens a product. - -### 2.2.6 Explore Products tabs -- **What you need:** Tags exist. -- **Steps:** 1. Scroll to "Explore Products". 2. Look at the tabs. -- **Things to test:** The tab row order; sliding it left/right. -- **Expected:** Tabs appear in the order set by the admin (see test 1.4.9). You can slide the row left-right. - -### 2.2.7 Products inside a tab are in admin order -- **What you need:** A tag with an ordered product list. -- **Steps:** 1. Tap a tab. 2. Compare the products with the order set in admin (test 1.4.5). -- **Things to test:** The product order inside a tab; out-of-stock at the end. -- **Expected:** Products appear in the same order. Out-of-stock ones are at the end. - -### 2.2.8 Tab with no products -- **What you need:** An empty tag exists. -- **Steps:** 1. Tap that tab. -- **Things to test:** An empty tab. -- **Expected:** "No products in this category yet" shows. - -### 2.2.9 Swipe between tabs -- **What you need:** 2+ tags. -- **Steps:** 1. Swipe left/right on the products area. -- **Things to test:** Swiping between tabs. -- **Expected:** The tab switches and its products show. - -### 2.2.10 Sticky tabs while scrolling -- **What you need:** Enough content to scroll. -- **Steps:** 1. Scroll the home page down until Explore Products is off the top. -- **Things to test:** The tabs sticking to the top while scrolling. -- **Expected:** A row of tabs sticks to the top of the screen while you scroll. - -### 2.2.11 Upcoming Delivery Slots -- **What you need:** Slots exist. -- **Steps:** 1. Scroll to "Upcoming Delivery Slots". -- **Things to test:** The slots rail shows future slots only. -- **Expected:** Cards with delivery time and "Order By" time. Only future slots. - -### 2.2.12 "Closing Soon" badge -- **What you need:** A slot closing within 4 hours. -- **Steps:** 1. Look at that slot's card. -- **Things to test:** The closing-soon badge. -- **Expected:** An amber "CLOSING SOON" badge shows. - -### 2.2.13 All Available Products grid -- **What you need:** Products exist. -- **Steps:** 1. Scroll to "All Available Products". -- **Things to test:** The 2-column grid; out-of-stock placement. -- **Expected:** A 2-column grid. Out-of-stock products are at the bottom. - -### 2.2.14 Product card -- **What you need:** A product exists. -- **Steps:** 1. Look at a product card. -- **Things to test:** What a product card shows. -- **Expected:** Photo, name, price and quantity unit show. There is an add-to-cart button. - -### 2.2.15 Pull to refresh -- **What you need:** Home open. -- **Steps:** 1. Pull the screen down from the top and release. -- **Things to test:** Pull-to-refresh on home. -- **Expected:** A spinner shows and data reloads. - -### 2.2.16 Open a product -- **What you need:** A product exists. -- **Steps:** 1. Tap a product card. -- **Things to test:** Navigating to product detail. -- **Expected:** The product detail page opens. - -### 2.2.17 Product prices are real (never zero) -- **What you need:** Products exist. -- **Steps:** 1. Look at every product card on Home, in categories, and in the full list. -- **Things to test:** Prices on every product card. -- **Expected:** Every card shows the correct, real price — never zero and never blank. - -### 2.2.18 Flash badge on flash-eligible products -- **What you need:** A flash-eligible product exists (1-hour delivery). -- **Steps:** 1. Look at that product's card on Home. -- **Things to test:** The flash badge. -- **Expected:** The card shows a "1 Hour"/flash badge or option. - -## 2.3 Stores - -### 2.3.1 Stores list -- **What you need:** Stores exist. -- **Steps:** 1. Tap the "Stores" tab at the bottom. -- **Things to test:** The stores tab. -- **Expected:** Stores listed. - -### 2.3.2 Store detail -- **What you need:** A store exists. -- **Steps:** 1. Tap a store. -- **Things to test:** The store detail page. -- **Expected:** Store header, its products, and tag chips (labels) show. - -### 2.3.3 Filter store products by tag -- **What you need:** Store has tags. -- **Steps:** 1. On store detail, tap a tag chip. -- **Things to test:** Filtering by a tag chip. -- **Expected:** Only products of that tag remain. - -### 2.3.4 Clear the tag filter -- **What you need:** A tag filter is active. -- **Steps:** 1. Tap "Clear". -- **Things to test:** Clearing the tag filter. -- **Expected:** All store products show again. - -## 2.4 Product detail - -### 2.4.1 Product page -- **What you need:** A product exists. -- **Steps:** 1. Open any product. -- **Things to test:** Everything shown on the product page. -- **Expected:** Photos, price, old price (if any) with discount %, unit and quantity show. - -### 2.4.2 Add to cart -- **What you need:** Product in stock. -- **Steps:** 1. On product page, tap "Add to Cart". 2. Choose quantity. -- **Things to test:** Adding to cart with a chosen quantity. -- **Expected:** A confirmation dialog shows. The floating cart bar count increases. - -### 2.4.3 Out-of-stock product -- **What you need:** An out-of-stock product exists. -- **Steps:** 1. Open it. 2. Try to add to cart. -- **Things to test:** Adding an out-of-stock product. -- **Expected:** The button is disabled or an error shows. - -### 2.4.4 Reviews -- **What you need:** A product with reviews. -- **Steps:** 1. Scroll to Reviews. -- **Things to test:** The reviews section. -- **Expected:** Ratings and text show. - -### 2.4.5 Write a review -- **What you need:** You bought the product. -- **Steps:** 1. Tap "Write Review". 2. Pick stars (1–5). 3. Type text. 4. Submit. -- **Things to test:** Writing and submitting a review. -- **Expected:** Success. Review appears in the list. - -### 2.4.6 Review without stars -- **What you need:** Review form open. -- **Steps:** 1. Tap Submit without picking stars. -- **Things to test:** Submitting a review with no rating. -- **Expected:** Error asking for a rating. - -### 2.4.7 Compare price (selling vs original) -- **What you need:** A product with an original (higher) price. -- **Steps:** 1. Open the product. 2. Look at the price area. -- **Things to test:** The original price display. -- **Expected:** The selling price is shown, and the original price is shown crossed out with the discount %. - -### 2.4.8 "Get in 1 Hour" moves item to flash cart -- **What you need:** A flash-eligible product. -- **Steps:** 1. Open the product. 2. Tap "Get in 1 Hour". -- **Things to test:** Moving a product to the flash cart. -- **Expected:** The item is added to the flash (1-hour) cart and you are taken to the flash cart. The regular cart is not affected. - -### 2.4.9 "Buy Now" goes straight to checkout -- **What you need:** A product in stock. -- **Steps:** 1. Open the product. 2. Tap "Buy Now". -- **Things to test:** The Buy Now shortcut. -- **Expected:** You are taken to checkout with just that item. - -### 2.4.10 Quantity offers ("buy more, save") -- **What you need:** A product with quantity-based offers. -- **Steps:** 1. Open the product. 2. Look for offers. -- **Things to test:** Bulk/quantity offers. -- **Expected:** The offers are listed (e.g. "Buy 2 for ₹X"). Choosing a quantity that matches applies the offer price. - -### 2.4.11 Combo product contents -- **What you need:** A combo product exists. -- **Steps:** 1. Open the combo product. -- **Things to test:** The combo's included items. -- **Expected:** The items inside the combo are listed with images, and an "OFFER"/combo badge is shown. - -## 2.5 Cart - -### 2.5.1 Cart page -- **What you need:** Items in cart. -- **Steps:** 1. Tap the cart icon / floating cart bar. -- **Things to test:** The cart page contents. -- **Expected:** Items, quantities and total show. - -### 2.5.2 Change quantity -- **What you need:** An item in cart. -- **Steps:** 1. Tap the + button. -- **Things to test:** Increasing quantity. -- **Expected:** Quantity and total update. - -### 2.5.3 Remove an item -- **What you need:** An item in cart. -- **Steps:** 1. Tap the remove/trash on an item. -- **Things to test:** Removing an item. -- **Expected:** Item disappears; total updates. - -### 2.5.4 Empty cart -- **What you need:** Items in cart. -- **Steps:** 1. Tap "Clear Cart". 2. Confirm. -- **Things to test:** Clearing the whole cart. -- **Expected:** Cart is empty. - -### 2.5.5 Empty cart message -- **What you need:** No items. -- **Steps:** 1. Open cart with nothing in it. -- **Things to test:** The empty cart state. -- **Expected:** "Your cart is empty" message. - -### 2.5.6 Floating cart bar -- **What you need:** Items in cart. -- **Steps:** 1. Look at the bottom of the home screen. -- **Things to test:** The floating cart bar. -- **Expected:** A bar shows the item count. Tapping it opens the cart. - -### 2.5.7 Choose a delivery slot for each item -- **What you need:** At least 2 items in the regular cart. -- **Steps:** 1. Open the cart. 2. Tap the slot selector on one item and pick a slot. 3. Pick a DIFFERENT slot on another item. -- **Things to test:** Per-item slot selection. -- **Expected:** Each item can carry its own delivery slot. Only future, non-full slots are shown. - -### 2.5.8 Item with no delivery slot -- **What you need:** A product that has no upcoming slots (ask the developer to set one up). -- **Steps:** 1. Add that product to the cart. 2. Open the cart. -- **Things to test:** An item with no available slot. -- **Expected:** The item shows "No delivery slots available". Checkout is blocked or asks you to remove the item. - -### 2.5.9 Bill breakdown in cart -- **What you need:** Items in cart, one with a coupon. -- **Steps:** 1. Open the cart. 2. Look at the bill section. -- **Things to test:** Item total, discount, delivery fee, to-pay. -- **Expected:** The numbers add up: Item Total − Discount + Delivery Fee = To Pay. Delivery is free (₹0) when the total is above the free-delivery threshold. - -### 2.5.10 Quantity limits (minimum/maximum per product) -- **What you need:** A product with a set step size (e.g. 500g steps). -- **Steps:** 1. In the cart, keep tapping + on that item. 2. Try to go below the minimum quantity. -- **Things to test:** Quantity step size and limits. -- **Expected:** The quantity only changes by the product's step size, and cannot go below the minimum or above the maximum allowed. The price updates with each step. - -## 2.6 Checkout - -### 2.6.1 Checkout page -- **What you need:** Cart + address. -- **Steps:** 1. On cart, tap "Checkout". -- **Things to test:** The checkout page sections. -- **Expected:** Delivery address, delivery slot, coupons and totals show. - -### 2.6.2 Address cards with dots -- **What you need:** 2+ saved addresses. -- **Steps:** 1. Look at "Delivery Address". 2. Slide the address cards left/right. -- **Things to test:** The dots under the address cards and sliding. -- **Expected:** Small dots under the cards; the active dot moves as you slide. - -### 2.6.3 Only one address — no dots -- **What you need:** Exactly 1 saved address. -- **Steps:** 1. Look at "Delivery Address". -- **Things to test:** One address = no dots. -- **Expected:** No dots show. - -### 2.6.4 Select an address -- **What you need:** 2+ addresses. -- **Steps:** 1. Tap an address card. -- **Things to test:** Selecting an address. -- **Expected:** It gets a blue border and a tick. The list scrolls back to start. - -### 2.6.5 Add a new address -- **What you need:** Checkout open. -- **Steps:** 1. Tap "+ Add New". 2. Fill the form. 3. Save. -- **Things to test:** Adding an address from checkout. -- **Expected:** Dialog closes. New address is selected automatically. - -### 2.6.6 Attach current location -- **What you need:** An address without location. -- **Steps:** 1. Tap "+ Attach Current Location". 2. Allow location permission. -- **Things to test:** Attaching GPS location to an address. -- **Expected:** "Attaching…" then success. Location saved. - -### 2.6.7 Apply a coupon -- **What you need:** An eligible coupon exists. -- **Steps:** 1. Tap "Apply Coupon". 2. Pick a coupon. -- **Things to test:** Applying a coupon. -- **Expected:** Discount shows in the total. - -### 2.6.8 Order with Cash on Delivery -- **What you need:** Cart + address + slot. -- **Steps:** 1. Choose COD. 2. Tap "Place Order". -- **Things to test:** Placing a COD order. -- **Expected:** Success screen with order confirmation. - -### 2.6.9 Order with card/UPI (Razorpay) -- **What you need:** Cart + address + slot. -- **Steps:** 1. Choose Online Payment. 2. Pay. -- **Things to test:** Placing an online-payment order. -- **Expected:** Payment screen opens; after paying, success screen. - -### 2.6.10 Place order with no address -- **What you need:** No saved address. -- **Steps:** 1. Try to place an order. -- **Things to test:** Ordering without an address. -- **Expected:** Error "select an address". - -### 2.6.11 Place order with a full slot -- **What you need:** A slot marked full. -- **Steps:** 1. Try to place an order in the full slot. -- **Things to test:** Ordering in a full slot. -- **Expected:** Error "slot full". You can pick another slot. - -### 2.6.12 Place order with an out-of-stock item -- **What you need:** An item went out of stock. -- **Steps:** 1. Try to place the order. -- **Things to test:** Ordering with an out-of-stock item. -- **Expected:** Error about the out-of-stock item. - -### 2.6.13 Delivery instructions field -- **What you need:** Checkout open with an address selected. -- **Steps:** 1. Find the "Delivery instructions" box. 2. Type a note (e.g. "Call before delivery"). 3. Place the order. -- **Things to test:** Adding delivery instructions. -- **Expected:** The note is saved and shown on the order details. - -### 2.6.14 Place order without selecting a slot -- **What you need:** A cart item with no slot selected. -- **Steps:** 1. Try to place the order. -- **Things to test:** Ordering with no slot. -- **Expected:** The app prompts you to select a delivery slot. The order is not placed. - -## 2.7 My Orders - -### 2.7.1 Orders list -- **What you need:** You have orders. -- **Steps:** 1. Go to Me. 2. Tap "My Orders". -- **Things to test:** The orders list. -- **Expected:** Orders listed with status. - -### 2.7.2 Order details -- **What you need:** An order exists. -- **Steps:** 1. Tap an order. -- **Things to test:** The order detail page. -- **Expected:** Items, status, address and notes show. - -### 2.7.3 Cancel an order (allowed time) -- **What you need:** A recent order. -- **Steps:** 1. Open the order. 2. Tap "Cancel". 3. Pick a reason. 4. Confirm. -- **Things to test:** Cancelling within the allowed time. -- **Expected:** Order becomes Cancelled. - -### 2.7.4 Cancel an order (too late) -- **What you need:** An order past its close time. -- **Steps:** 1. Try to cancel it. -- **Things to test:** Cancelling after the allowed time. -- **Expected:** Cancellation is disabled or an error shows. - -### 2.7.5 Add a note to an order -- **What you need:** An order exists. -- **Steps:** 1. Open the order. 2. Tap "Add Note". 3. Type. 4. Save. -- **Things to test:** Adding a note. -- **Expected:** Note saved and shows. - -### 2.7.6 "Order again" hint on home -- **What you need:** You have past orders. -- **Steps:** 1. Look at the home screen for the "Order again / Next order" box. -- **Things to test:** The order-again box. -- **Expected:** Past products show. Tapping one opens the product. - -### 2.7.7 Reorder a past order -- **What you need:** A past order exists. -- **Steps:** 1. Open the order. 2. Tap "Reorder" / "Order Again". -- **Things to test:** Reordering a past order. -- **Expected:** The order's items are added back to the cart. You can then check out. - -### 2.7.8 Cancel an order that is already cancelled -- **What you need:** A cancelled order. -- **Steps:** 1. Open the cancelled order. 2. Try to cancel it again. -- **Things to test:** Cancelling twice. -- **Expected:** The cancel option is disabled or an error appears. The order stays cancelled. - -## 2.8 Offers tab - -### 2.8.1 Offers tab exists -- **What you need:** Any build. -- **Steps:** 1. Look at the bottom menu. -- **Things to test:** The bottom menu tab. -- **Expected:** There is a tab with a price-tag icon labelled "Offers". - -### 2.8.2 Combos on Offers page -- **What you need:** Combos exist. -- **Steps:** 1. Tap the "Offers" tab. -- **Things to test:** The Combos row. -- **Expected:** A "Combos" row with products shows. - -### 2.8.3 Offers on Offers page -- **What you need:** Offers exist. -- **Steps:** 1. Scroll down on the Offers page. -- **Things to test:** The Offers row. -- **Expected:** An "Offers" row shows. - -### 2.8.4 Empty offers -- **What you need:** No combos/offers. -- **Steps:** 1. Open Offers tab. -- **Things to test:** Empty rows. -- **Expected:** "No combos available right now" / "No offers available right now" messages. - -### 2.8.5 Open a product from Offers -- **What you need:** A product exists. -- **Steps:** 1. Tap a product in a row. -- **Things to test:** Opening a product from the Offers page. -- **Expected:** Product detail opens. Back returns to Offers. - -## 2.9 Flash (1-Hour) Delivery - -### 2.9.1 Flash tab when enabled -- **What you need:** Admin has flash enabled. -- **Steps:** 1. Tap the centre "1 Hr Delivery" button. -- **Things to test:** The flash page opens fast. -- **Expected:** Flash page opens immediately — no long loading spinner. - -### 2.9.2 Flash tab when disabled -- **What you need:** Admin disabled flash. -- **Steps:** 1. Tap the "1 Hr Delivery" button. -- **Things to test:** The flash disabled screen. -- **Expected:** "1 Hr Delivery Unavailable" screen with a button to go to scheduled delivery. - -### 2.9.3 Flash products -- **What you need:** Flash products exist. -- **Steps:** 1. On flash page, look at products. -- **Things to test:** The flash product list. -- **Expected:** Flash product list shows. - -### 2.9.4 Flash cart and checkout -- **What you need:** Flash items. -- **Steps:** 1. Add a flash product to cart. 2. Checkout. -- **Things to test:** The flash cart and checkout flow. -- **Expected:** Flash flow works with a 30-minute delivery time. - -### 2.9.5 Flash order success -- **What you need:** Order placed. -- **Steps:** 1. Complete a flash order. -- **Things to test:** The flash success screen. -- **Expected:** Success screen. - -## 2.10 Me tab - -### 2.10.1 Profile -- **What you need:** Logged in. -- **Steps:** 1. Tap "Me" tab. -- **Things to test:** The profile info. -- **Expected:** Your name and number show. - -### 2.10.2 Edit profile -- **What you need:** Logged in. -- **Steps:** 1. Tap "Edit Profile". 2. Change name. 3. Save. -- **Things to test:** Editing the profile. -- **Expected:** New name saved. - -### 2.10.3 My Addresses -- **What you need:** —. -- **Steps:** 1. Tap "Addresses". 2. Add, edit, delete, set default. -- **Things to test:** Add, edit, delete and set-default for addresses. -- **Expected:** Each action works; one address is marked default. - -### 2.10.4 My Coupons -- **What you need:** Coupons exist. -- **Steps:** 1. Tap "Coupons". -- **Things to test:** The coupon list and redeeming a reserved coupon. -- **Expected:** Your coupons listed. A reserved coupon can be redeemed once. - -### 2.10.5 My Complaints -- **What you need:** —. -- **Steps:** 1. Tap "Complaints". 2. Raise a new complaint. 3. Submit. -- **Things to test:** Raising a complaint. -- **Expected:** It appears in the list as Open. - -### 2.10.6 Terms & About -- **What you need:** —. -- **Steps:** 1. Tap "Terms" and "About". -- **Things to test:** The Terms and About pages. -- **Expected:** Pages open with text. - -## 2.11 Search and Slot view - -### 2.11.1 Search with results -- **What you need:** Products exist. -- **Steps:** 1. Search for a real product name. -- **Things to test:** Searching for a real product. -- **Expected:** Matching products show. Tapping opens product. - -### 2.11.2 Search with no results -- **What you need:** —. -- **Steps:** 1. Search for "zzzzzz". -- **Things to test:** Searching for a nonsense word. -- **Expected:** "No results" message. - -### 2.11.3 Slot view -- **What you need:** A slot exists. -- **Steps:** 1. From home, tap a slot card. -- **Things to test:** The slot view page. -- **Expected:** The slot's products show with add-to-cart. - -## 2.12 Offline and saving data on the phone - -### 2.12.1 Data saved after first load -- **What you need:** You opened the app once with internet. -- **Steps:** 1. Close the app. 2. Turn off internet (aeroplane mode). 3. Open the app. -- **Things to test:** Offline launch with saved data. -- **Expected:** Products, stores and slots still show (from the phone's saved copy). - -### 2.12.2 No "invalid key" errors -- **What you need:** Any usage. -- **Steps:** 1. Watch the screen/log for red errors mentioning "Invalid key". -- **Things to test:** No storage errors. -- **Expected:** No such errors. - -### 2.12.3 Update after admin changes -- **What you need:** Admin changed something (e.g. a price). -- **Steps:** 1. Keep the app open. 2. Wait up to 1 minute. -- **Things to test:** The app picking up an admin change automatically. -- **Expected:** The app picks up the change by itself (only the changed part reloads). - -### 2.12.4 Server is down -- **What you need:** Developer stops the server. -- **Steps:** 1. Open the app with saved data. -- **Things to test:** App behaviour when the server is down. -- **Expected:** Saved data still shows. An error screen appears only where new data is needed. - -### 2.12.5 Slow network -- **What you need:** Switch to 2G/slow. -- **Steps:** 1. Browse the app. -- **Things to test:** App behaviour on a slow connection. -- **Expected:** Loading signs appear; no crash; things load when network allows. - -### 2.12.6 App with no data at all -- **What you need:** Empty database. -- **Steps:** 1. Browse every tab. -- **Things to test:** Every screen with zero data. -- **Expected:** Empty messages everywhere; no crash. - -### 2.12.7 Rapid tapping -- **What you need:** Any screen. -- **Steps:** 1. Tap buttons very fast, switch tabs fast. -- **Things to test:** Rapid taps and tab switching. -- **Expected:** No crash, no double navigation. - -### 2.12.8 Back button -- **What you need:** You navigated deep. -- **Steps:** 1. Press the back button several times. -- **Things to test:** Back navigation. -- **Expected:** Goes back one screen at a time, correctly. - -## 2.13 Notifications & security checks - -### 2.13.1 Push notification permission -- **What you need:** A fresh install (or reinstall). -- **Steps:** 1. Open the app. 2. When the phone asks for notification permission, tap "Allow". -- **Things to test:** Allowing push notifications. -- **Expected:** The app continues normally. Later, order updates can arrive as notifications. - -### 2.13.2 Push notification permission denied -- **What you need:** A fresh install (or reinstall). -- **Steps:** 1. When the phone asks for notification permission, tap "Don't Allow". -- **Things to test:** Denying push notifications. -- **Expected:** The app does not crash and still works. No error loop. - -### 2.13.3 Old-version notice (webview overlay) -- **What you need:** Ask the developer to make the backend send an update notice. -- **Steps:** 1. Open the app. 2. Look for a full-screen notice about updating the app. -- **Things to test:** The update-notice screen. -- **Expected:** The notice appears full-screen. The close button (if shown) closes it. The app does not crash. - -### 2.13.4 You cannot see another user's order -- **What you need:** Two customer accounts with orders. -- **Steps:** 1. Ask the developer for the order link of the OTHER account. 2. Open it while logged in as your account. -- **Things to test:** Opening someone else's order. -- **Expected:** An error appears or you are blocked. You never see the other user's order details. - -### 2.13.5 Expired or used-up coupon at checkout -- **What you need:** An expired coupon (ask the developer to set one up). -- **Steps:** 1. Try to apply the expired coupon at checkout. -- **Things to test:** Expired/used-up coupons. -- **Expected:** The coupon is rejected with a clear reason. The discount is not applied. - -### 2.13.6 Odd text in search (no crash) -- **What you need:** Home screen. -- **Steps:** 1. In search, type something like `