UX GUIDELINE
VietGara — Multi-Tenant SaaS Platform for Auto Garage Management & Maintenance
Version 1.5 — October 2, 2026 · Cloud: Google Cloud Platform (GCP) · Backend: Go
Superseded. Version 2 (
../v2/01_UX_Guideline.md) replaces this document; it is kept for history, and where the two differ, v2 is the decision.
1. Introduction
1.1. Purpose
This document sets out the user experience (UX) principles for the VietGara platform, serving as the basis for the design team to build wireframes, user flows, and screen specifications in Figma, before moving on to the UI Design Spec (detailed per-screen specification) and the Design System (component library).
1.2. Design Tool
All of VietGara’s UI/UX design work is done in Figma — the standard tool for real-time collaborative design, with strong support for building a Design System as a Team Library, a Dev Mode for handoff to engineers, and a rich plugin ecosystem (color contrast checking, mock data generation, design token syncing).
1.3. Related Documents
- 02_UI_Design_Spec.md — detailed specification for each screen
- 03_Design_System.md — component library, color/typography tokens
- Functional Requirements Document (FRD), Vision & Scope — source of business requirements
2. Core UX Principles
VietGara serves users with widely varying levels of technical proficiency — from garage owners/accountants comfortable at a computer, to technicians working in the shop with dirty hands or gloves, to end customers who only open the app for a few minutes at a time. The following 6 principles, based on Nielsen’s Usability Heuristics, are prioritized for VietGara’s real-world usage context:
| Principle | Specific Application at VietGara |
|---|---|
| Clear visibility of system status | Always show the status of quotes/repair orders/sync (especially important for the offline-capable Technician App) |
| Match real users’ language & mental model | Use familiar garage terminology (“Quote”, “Repair Order”), avoid technical jargon (“entity”, “record”) |
| User control & freedom | Always provide an escape route (cancel, go back) before irreversible actions (delete, close a repair order) |
| Consistency & standards | Use a single Design System (03_Design_System.md) across every screen — never invent a new pattern per feature |
| Error prevention over error handling | Validate input as it’s entered (e.g. phone numbers), disable the submit button when required fields are missing |
| Minimal interaction for mobile contexts | The Technician App is optimized for one-handed use, large buttons (at least 44x44pt), minimal typing, preferring selection/photo capture |
3. User Personas
| Persona | Usage Context | Primary Goal | Pain Point |
|---|---|---|---|
| Garage Owner (Minh, 38) | Desktop at the garage office, occasionally on phone | Get an overview of revenue, oversee staff across multiple garages | No time to learn complex software; needs to see key numbers immediately upon opening the app |
| Garage Accountant (Hoa, 29) | Desktop, focused work at end of day/month | Accurate settlement, error-free invoicing | Fears amount/tax errors; needs clear confirmation before issuing an invoice |
| Service Advisor (Tuan, 26) | Desktop/tablet at the front desk, direct customer interaction | Create quotes quickly while the customer waits | Needs fast interaction, doesn’t want to keep the customer waiting during data entry |
| Technician (Nam, 24) | Phone, in the workshop, hands may be dirty/gloved, weak signal | Know exactly what to do, update progress quickly | Doesn’t want to type much; fears losing data if connectivity drops mid-task |
| Inventory Staff (Lan, 31) | Desktop/tablet near the stock area | Accurate stock in/out, know when to reorder | Easily confuses units/quantities if the interface isn’t clear |
| Supplier (Sang, 45; Phase 17 portal) | Desktop or phone at the supplier’s sales desk; works from the garage’s purchase orders | Confirm what he can deliver and when, attach the delivery note | Orders arrive by phone or chat and get mixed up; wants one list of open orders per garage |
| Customer (Thao, 34) | Personal phone, used for a few minutes at a time, infrequently | Know what stage the car is at, no surprise charges | Unfamiliar with auto-repair terminology; concerned about price transparency |
4. Information Architecture
4.1. Owner Web (garage owners and staff)
flowchart TD
auth["Sign in / Sign up<br/>e-mail + password or Google<br/>Forgot password (e-mail OTP)"] --> verify{"E-mail verified?"}
verify -- no --> ve["Verify e-mail (6-digit OTP, 2 minutes)<br/>only Account is reachable meanwhile"]
ve --> sel
verify -- yes --> sel["Select active garage<br/>(owned or working in)"]
sel --> dash[Dashboard]
sel --> quotes["Quotes (1.2)"]
sel --> ros["Repair Orders (1.3)"]
sel --> inv["Inventory (1.3)"]
sel --> cus["Customers & Vehicles, Partners"]
sel --> bill["Billing & Receivables (1.4)"]
sel --> rpt["Reports (1.5)"]
sel --> staff["Staff: members, invitations"]
sel --> gs["Garage settings: profile, hours, numbering, logo, status"]
auth -.-> acct["Account: profile, language"]
sel -.-> roles["Roles & groups (owners)"]
sel -.-> sub["Subscription: plan, usage, change plan"]
sel -.-> invs["My invitations"]
Menu entries are shown only when the member’s permissions in the active garage allow them (e.g. Customers needs customer.read); the server enforces the same rules.
4.1a. Admin Web (platform admins and admin staff)
A separate web app (vietgara-admin-web) with no garage context: sign in (no self-registration; the account must be listed as a platform admin) → Plans · Subscriptions · Payments (review queue, payment details and QR code, Release 5.2) · Account. Accounts that are not platform admins see an “Access denied” page that points them to the owner web.
flowchart TD
auth["Sign in / Forgot password"] --> pa{"Platform admin?"}
pa -- no --> deny["Access denied + Sign out"]
pa -- yes --> plans["Plans"]
pa -- yes --> subs["Subscriptions: search, extend"]
pa -- yes --> pay["Payment requests: review, approve, reject; payment details"]
pa -. yes .-> acct["Account: profile, language"]
From Phase 12 (Release 12.4) a Dashboard opens first after sign-in: new joiners and new licenses per day / month / year, conversions and active garages (FR-ADM-01..03).
4.1b. Owner App (Flutter, garage owners)
vietgara-owner-app is the mobile companion of the owner web for garage owners (Phase 2, Release 2.0). It covers what an owner checks or decides away from the counter. Setup and data entry stay on the web.
The bottom navigation has five tabs:
- Dashboard
- Quotes: send, record the decision, convert
- Repairs: one tab per board column; line progress and technicians, close
- Receivables: payments, insurer split, receipt PDF
- More: customers, vehicles, inventory, staff, subscription, invitations, user, language, sign out
The garage name in each app bar switches garage. A plan notice (trial, read-only, suspended) sits above the tabs.
4.1c. Admin App (Flutter, VietGara operators)
vietgara-admin-app is the mobile companion of the admin web (Phase 2, Release 2.1). It uses the same sign-in rule and access-denied screen as Section 4.1a, with Plans · Subscriptions (search, extend) · Payments (review queue and payment details, Release 5.2) · Account. The platform Dashboard is added in Release 12.4 and becomes the first screen.
4.2. Customer App
flowchart TD login["Login (phone OTP or Google)"] --> veh[My Vehicles] veh --> hist["Vehicle detail → repair history"] veh --> appr["Quotes awaiting approval → approve / reject"] veh --> prog[Real-time repair progress] veh --> pay["Payment → e-invoice"]
4.3. Technician App
flowchart TD login[Login] --> list["Today's repair orders (time-prioritized)"] list --> det["Order detail → update status per line item"] list --> photo[Take before/after photos] list --> sync["Sync indicator (online / offline / syncing)"]
5. Key User Flows
5.1. New Garage Onboarding
flowchart TD reg["Register: e-mail, password, name, optional phone<br/>(or Continue with Google)"] --> otp["Enter the 6-digit code e-mailed<br/>(valid 2 minutes, resend after 30 s)"] reg -. Google .-> welcome otp --> welcome["Garages page (empty state):<br/>create the first garage"] otp -. "also e-mailed (1.5)" .-> email["Registration-confirmation e-mail"] welcome --> garage["Create garage: name, address, phone, e-mail, tax ID"] garage --> invite["Suggest inviting staff (skippable):<br/>look up an existing user by e-mail or phone"] invite --> dash["Dashboard with trial banner (14 days)"]
5.2. Joining a Garage as Staff
flowchart TD
e["Invitation e-mail<br/>'{owner} invites you to {garage}'"] --> signin["Sign in (the invitee already has a user)"]
signin --> page["/invitations/:id — Accept or Decline"]
page -- accept --> ws["Garage appears in the selector;<br/>menus follow the groups' permissions"]
5.3. Quote → Approval → Repair (multi-role touchpoints)
flowchart TD
sa1["Service Advisor: create quote → choose Link or Manual → send"] --> mode{"Approval mode?"}
mode -->|Link| c["Customer (link, e-mailed automatically if on file): view → approve/reject each line"]
mode -->|Manual| sa1b["Service Advisor: asks the customer face to face → records the decision"]
c --> sa2["Service Advisor: approval notification → convert to repair order → assign technician(s) per line"]
sa1b --> sa2
sa2 --> t["Technician (Owner Web Kanban board): update each line's progress → advisor closes once every line is completed"]
Design note: every hand-off between roles needs a proactive notification (push/SMS) — users should never have to check the app manually to find out something happened. In Manual mode there is no customer-facing touchpoint at all, by the owner’s own choice (FR-QUO-02) — the advisor’s own confirmation after recording the decision takes its place. The last step runs on the Owner Web Kanban board through Release 1.3 (FR-REP-03); the dedicated Technician App and before/after photos (FR-REP-04/05) are Phase 11.
5.4. Repair → Settlement → Collection (Release 1.4)
flowchart TD
ro["Service Advisor closes the repair order"] --> acc["Garage Accountant: open the closed order → Create settlement (FR-BIL-01)"]
acc --> split{"Insurance involved?"}
split -->|no| coll["Record payment(s) as collected: amount, method (FR-BIL-03)"]
split -->|yes| alloc["Allocate customer / insurer split, pick the insurer partner (FR-BIL-02)"]
alloc --> coll
coll --> status["Status badge updates live: Pending → Partially paid → Paid"]
status --> pdf["Export settlement receipt PDF (FR-DOC-01), handed or e-mailed to the customer"]
Design note: there is no separate Receivables screen — “Billing & Receivables” (Section 4.1) is the same settlement list, with an “outstanding only” filter serving FR-REC-01 (Database Design 6.1). A settlement is never created automatically when a repair order closes; the Accountant creates it deliberately from the closed order, the same direct-action pattern quote and repair order creation already use, so the amount is confirmed by a person before it becomes a bill.
6. Interaction Principles
- Irreversible actions (deleting a customer, cancelling an invoice, closing a repair order) always show a confirmation dialog stating the consequence clearly — avoid vague wording (“Are you sure?” → replace with “Close this repair order? Line items cannot be edited after closing.”).
- Long forms (e.g. creating a multi-item quote) are grouped logically, with auto-save drafts to prevent data loss on interruption.
- Data tables (customer list, inventory) support filtering/sorting/search right at the top of the table, not hidden in a secondary menu.
- Technician App: every data-writing action must work offline, with a consistent icon clearly showing “saved locally, pending sync” status.
7. Accessibility
Comply with at least WCAG 2.1 Level A for the main user flows (NFR-US-04): a minimum text/background contrast ratio of 4.5:1, a minimum tap target of 44x44pt on mobile, keyboard navigation support on Owner Web, and clear labels on every input field rather than relying on placeholder text alone.
8. Language & Tone (Content/UX Writing)
- The interface is bilingual: Vietnamese (default) and English, switchable at any time from the header or the sign-in pages and saved on the user. Every string, error message and e-mail exists in both languages; no text is hard-coded in components.
- Standard, friendly but professional Vietnamese — avoid being overly casual (no internet slang) and avoid overly stiff, bureaucratic phrasing.
- Error messages always state the cause and how to fix it, never just “An error occurred”. The API returns stable error codes (API Specification, Section 1.2) that the interface translates, e.g.
PLAN_LIMIT_REACHED→ “Your plan’s limit is reached. Upgrade your plan.” - Action button labels use specific verbs (“Send Quote”, “Confirm Payment”) rather than generic ones (“OK”, “Continue”).
9. Working with Figma
9.1. Project Structure
Figma Team: VietGara Project: VietGara Design System -> file "Design System" (03_Design_System) Project: VietGara Product file "Owner Web - Wireframes" file "Owner Web - UI Screens" file "Customer App - UI Screens" file "Technician App - UI Screens" file "Prototype - Stakeholder Demo"9.2. Naming Convention
- Pages within a file: named by business module (e.g. 01-Quote, 02-Repair-Order).
- Frames: [Platform]/[Module]/[Screen Name]/[State] — e.g. OwnerWeb/Quote/CreateQuote/Empty.
- Component instances: always pulled from the Design System file’s Team Library, never a locally detached copy in a product file.
9.3. Developer Handoff
- Use Figma Dev Mode: attach annotations for spacing, color, and typography directly on the frame instead of writing a separate Word document per screen.
- Every finished frame is linked to its corresponding ticket (Jira/Linear) so developers can cross-check requirements.
9.4. Usability Testing
- Run usability tests with at least 3-5 real users per role (especially technicians and customers) before finalizing the UI Design Spec for each major module, using a click-through Figma prototype.