Skip to main content

Login To Branch To Home

This page documents the current mobile startup flow based on the implementation in apps/mobile.

Scope

This workflow is based on:

  • apps/mobile/App.tsx
  • apps/mobile/src/navigation/RootNavigator.tsx
  • apps/mobile/src/screens/loginScreen/index.tsx
  • apps/mobile/src/screens/branchScreen/index.tsx
  • apps/mobile/src/screens/homeScreen/index.tsx

Startup decision flow

Step 1. Login

The login screen collects username and password, then calls the auth service.

Required app update check

  • The login screen reads the native app versionCode through AppVersionModule.
  • JavaScript reads native version data through each app boundary: apps/mobile/src/native/appVersion.ts and apps/pos-terminal/src/native/appVersion.ts.
  • The screen reads Firestore version/vapp.
  • Required-update logic lives in apps/mobile/src/services/appUpdate.ts and apps/pos-terminal/src/services/appUpdate.ts.
  • The current check compares numeric values after converting both sides with Number(...).
  • The main remote field is versionNumber; the implementation also accepts platform-specific shapes if they are added later:
    • androidVersionNumber / androidVersion
    • iosVersionNumber / iosVersion
    • nested android.versionNumber / android.version
    • nested ios.versionNumber / ios.version
  • If the Firestore version number is greater than the native versionCode, the app shows a blocking modal: แอปของคุณจำเป็นต้องอัปเดทเป็นเวอร์ชั่น ....
  • The modal displays the numeric value from Firestore versionNumber.
  • The modal has no close action and ignores Android back dismiss requests.
  • POS Terminal runs the same check on UserSelectionScreen and blocks with the same modal before login actions can continue.

Main behavior

  • If username or password is missing, the app blocks submission and shows an alert.
  • On successful login, the app:
    • stores the auth token
    • stores the serialized user object
    • stores the login date in DD-MM-YYYY
    • refreshes the FCM token when possible
    • patches user permissions or flags back to the backend when userId exists
  • Before finishing login, the app runs verifyAlcoholCheckBeforeLogin.
  • If the login API reports missing required values, the screen switches into password-reset mode.

Output of the login step

  • isAuthenticated = true
  • branch is still unresolved until branch selection is completed

Step 2. Branch selection

After login, if no branch is stored, RootNavigator renders the branch-selection flow.

Main behavior

  • The screen loads two branch lists:
    • allBranches from fallback user code 999999
    • userBranches from the current stored user code
  • Step 1 of the screen is selecting a main branch.
  • After a main branch is selected, the app loads warehouse options for that branch by calling:
    • getWarehouses() for the global main-warehouse list
    • getWarehousesSub(branch.whsGrpCode) for sub-warehouses under the selected branch
  • The app removes any sub-warehouse whose whsCode already exists in the main-warehouse list.
  • If the selected branch also exists in userBranches, the app prepends the selected main warehouse itself back into the option list.
  • Step 2 of the screen is selecting the actual warehouse branch to store locally.
  • On warehouse selection, the app:
    • clears cached tax data
    • saves the selected branch into storage
    • notifies the navigator that branch selection is complete
    • fetches tax data as a best-effort background step

Firestore inventory index diagnostic

  • Long-press a warehouse in step 2 to run the same real-time Firestore inventory query used by the product picker for that warehouse. The normal tap action is suppressed, so the warehouse is not selected.
  • The temporary listener logs each received snapshot and stops automatically after five seconds. Starting a new diagnostic stops any previous listener first.
  • If Firestore rejects the query because a composite index is missing, the console prints [FIRESTORE CREATE INDEX] followed by the Firebase Console URL as a separate entry. React Native DevTools exposes that URL as a clickable link.

Stored branch payload

The selected branch is stored as a single JSON object in local storage under the branch key.

The payload shape is:

{
BranchId: string | number;
BranchCode: string;
whsGrpName: string;
whsGrpCode: string;
isMain: boolean;
}

Meaning:

  • BranchId is the selected main branch id
  • BranchCode is the selected main branch code
  • whsGrpCode is the actual warehouse code selected in step 2
  • whsGrpName is the selected warehouse label
  • isMain shows whether the selected warehouse is the main warehouse of that branch

Downstream usage note

  • Screens and services that need the selected warehouse typically read whsGrpCode.
  • Screens that need the owning main branch code can read BranchCode.
  • TransferWarehouseDetail now uses stored BranchCode to load warehouse options via getWarehousesSub(BranchCode), while still using the stored whsGrpCode as the selected source warehouse for item and batch flows.

Step 3. Home

When both auth and branch selection are satisfied, RootNavigator renders Home.

Main behavior

  • Home loads stored user data and selected branch from local storage.
  • Home checks the saved login date whenever it receives focus; if the stored login_date is no longer the current day, Home uses the normal mobile logout behavior.
  • Home header runs the same required app update check as Login, including when Home regains focus.
  • POS Terminal Home also reruns the required app update check when it regains focus.
  • The visible menu depends on:
    • deptCode from the authenticated user
    • whether the selected branch is marked as isMain
  • Menu cards route the user into the rest of the POS flows such as:
    • order list
    • booking price
    • invoice list
    • shipping
    • storefront
    • stock flows
    • customer and employee screens
  • Logout from the home header clears all session storage and returns the app to the login state.

Notes

  • Login validity is date-based, so the stored session expires when the saved login date is no longer equal to the current day.
  • Branch exists as a screen inside the authenticated stack, so users can re-open branch selection after reaching Home.
  • The Home screen is both a landing page and a permission gate for downstream workflows.