# EloSync Mobile (tenant app)
Official tenant workspace mobile client (EloSync-Mobile repo). Tenant API only � no Central admin surface.
Stack
| Piece | Choice |
|---|---|
| Framework | Expo SDK 57 + React Native |
| Navigation | Expo Router |
| Dev workflow | EAS development builds (expo-dev-client) � not App Store Expo Go |
| API | Axios → /api/tenant/v1 |
| Auth | Laravel Sanctum Bearer tokens |
| Token storage | expo-secure-store |
App Store Expo Go remains on SDK 54; this project targets SDK 57. Use a development build or EAS production/preview binaries for devices.
Configuration
EXPO_PUBLIC_API_URL=https://api.example.comTenant API base: ${EXPO_PUBLIC_API_URL}/api/tenant/v1
Native apps do not use browser CORS. Pin API TLS and rate limits on the backend as for any API client.
Physical devices cannot use http://elosync-backend.test unless that host resolves on the phone � use a LAN IP or production API URL in .env / eas.json profiles.
Development builds (EAS)
Identifiers: iOS com.diligentcreators.elosync, Android com.diligentcreators.elosync, scheme elosync.
npm ci
eas login
eas init
npm run build:dev:android # internal APK
npm run build:dev:ios # internal IPA (Apple Developer)
npm run build:dev:ios:simulator # iOS Simulator onlyAfter installing the dev client on a device:
npm run start:dev-clientOpen the EloSync dev build and scan the Metro QR code.
Rebuild when changing native modules, app.json plugins, or EAS native settings.
Push notifications (FCM)
Mobile OS push reuses the tenant /fcm-device-tokens API and FcmChannel (same as web). The app uses expo-notifications + getDevicePushTokenAsync() and registers platform: android|ios.
Required after this feature lands: a new EAS development/preview/production build (native plugin change). Metro alone is not enough.
Firebase ops (before production smoke):
- Add Android + iOS apps to the same Firebase project used for web FCM.
- Upload the APNs auth key to Firebase Cloud Messaging (iOS).
- Provide
google-services.json/GoogleService-Info.plistto EAS (do not commit secrets). - Smoke: Profile enable →
fcm_device_tokensrow → kill app → assign → OS toast → tap opens record.
Until Firebase native apps are configured, Profile shows that push is unsupported / soft-fails enable without breaking login. API FCM_* credentials already power delivery once tokens exist.
EAS profiles
| Profile | Purpose |
|---|---|
development | Dev client, internal, physical devices |
development-simulator | Dev client for iOS Simulator |
preview | Internal release-like build |
production | Store binaries (npm run build:production) |
Store submission: eas submit after a production build.
Authentication
Mirrors the tenant web login (EloSync-Frontend login-page.tsx + auth-store.ts):
POST /auth/loginwithemail,password, optionalremember, optionalworkspaceslug/domain, optionallatitude/longitude(attendance check-in side-effect on the API).- Response:
token,user(roles, permissions),modules,workspace. GET /meon cold start and after login to refresh session payload.POST /me/logout+ clear SecureStore on sign out.- When
email_verified_atis null, gate the app until verification (resend viaPOST /me/email/verification-notification).
Workspace resolution (InitializeTenancy on the backend):
- Login can resolve tenant from email alone (tenant user emails are globally unique).
- Optional
workspacebody orX-Tenant-Domainheader disambiguates branding (GET /public/settings) and forgot-password flows. - After login, tenant context is carried by the Bearer token.
Forgot password on mobile always includes workspace + email (the app is never host-bound like a workspace subdomain).
Authorization gates
Reuse the web SPA model:
- Modules:
user.modulesfrom login//me� hide nav when module slug not entitled. - Permissions: Spatie permission strings on
user.permissions;superadminrole bypasses checks.
Module development
New mobile module screens should mirror the Leads web module (list / create / view / edit) and gate by module + permission. Shared API contracts live in EloSync-Docs/docs/api/.
Store release
One multi-tenant binary (Play Store + App Store) via EAS production profile. Workspace users sign in with email � not per-customer white-label builds unless product adds that later.
Mobile module rollout
Extend config/modules.ts and add app/(app)/(tabs)/{slug}/ stack screens per module PR. Each PR should include:
- API service + types
- List / create / view / edit (or justified subset)
- Nav registration in
config/modules.tswithcategory+icon+ tab visibility gates (More groups by category) - User guide slice + changelog line
Shell UX: Dashboard Quick Actions (permission-gated create shortcuts); Tasks list filters (status, my_tasks, overdue); More screen categories (Work, Sales, Billing, Purchasing, Inventory, Finance, HR, Tools).
Current shipped mobile modules: leads, tasks, contacts, companies, opportunities, activities, todos, quotations, calendar, meetings, projects, notifications (shell), profile.
Leads (module:leads)
| Piece | Location |
|---|---|
| API client | lib/api/leads.ts � GET/POST /leads, GET/PUT/DELETE /leads/{id}, GET /lead-stages |
| Types | types/leads.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/leads/ � index (list + search), new, [id]/index (view), [id]/edit |
| Nav | config/modules.ts � permission: leads.view, tab /(app)/(tabs)/leads |
| Permissions | leads.view, leads.create, leads.update, leads.delete |
Tasks (module:tasks)
Mirrors the Leads mobile pattern (list / create / view / edit stack, React Query, permission gates).
| Piece | Location |
|---|---|
| API client | lib/api/tasks.ts � GET/POST /tasks, GET/PUT/DELETE /tasks/{id}, POST /tasks/{id}/complete, POST /tasks/{id}/reopen |
| Types | types/tasks.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/tasks/ � index (list + search), new, [id]/index (view + complete/reopen), [id]/edit |
| Nav | config/modules.ts � permission: tasks.view, tab /(app)/(tabs)/tasks |
| Permissions | tasks.view, tasks.create, tasks.update, tasks.delete, tasks.complete |
Contacts (module:contacts)
Mirrors the Leads mobile pattern (list / create / view / edit stack, React Query, permission gates).
| Piece | Location |
|---|---|
| API client | lib/api/contacts.ts � GET/POST /contacts, GET/PUT/DELETE /contacts/{id} |
| Types | types/contacts.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/contacts/ � index (list + search), new, [id]/index (view), [id]/edit |
| Nav | config/modules.ts � permission: contacts.view, tab /(app)/(tabs)/contacts |
| Permissions | contacts.view, contacts.create, contacts.update, contacts.delete |
Companies (module:companies)
Mirrors the Contacts mobile pattern (list / create / view / edit stack, React Query, permission gates).
| Piece | Location |
|---|---|
| API client | lib/api/companies.ts � GET/POST /companies, GET/PUT/DELETE /companies/{id} |
| Types | types/companies.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/companies/ � index (list + search), new, [id]/index (view), [id]/edit |
| Nav | config/modules.ts � permission: companies.view, tab /(app)/(tabs)/companies |
| Permissions | companies.view, companies.create, companies.update, companies.delete |
Opportunities (module:opportunities)
Mirrors the Leads mobile pattern with pipeline stage picker (GET /opportunity-stages).
| Piece | Location |
|---|---|
| API client | lib/api/opportunities.ts � GET/POST /opportunities, GET/PUT/DELETE /opportunities/{id}, GET /opportunity-stages |
| Types | types/opportunities.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/opportunities/ � index (list + search), new, [id]/index (view), [id]/edit |
| Nav | config/modules.ts � permission: opportunities.view, tab /(app)/(tabs)/opportunities (label Pipeline) |
| Permissions | opportunities.view, opportunities.create, opportunities.update, opportunities.delete |
Activities (module:activities)
CRM engagement log (call, email, note, follow-up) with required link to at least one contact, company, or lead.
| Piece | Location |
|---|---|
| API client | lib/api/activities.ts � GET/POST /activities, GET/PUT/DELETE /activities/{id}, POST /activities/{id}/complete |
| Types | types/activities.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/activities/ � index (list + search), new, [id]/index (view + complete), [id]/edit |
| Shared UI | components/forms/RelatedEntityPickers.tsx � contact/company/lead chips when entitled |
| Nav | config/modules.ts � permission: activities.view, tab /(app)/(tabs)/activities (label Log) |
| Permissions | activities.view, activities.create, activities.update, activities.delete, activities.complete |
ToDos (module:todos)
Personal creator-scoped checklists (list CRUD on mobile; board view remains web-only).
| Piece | Location |
|---|---|
| API client | lib/api/todos.ts � GET/POST /todos, GET/PUT/DELETE /todos/{id} |
| Types | types/todos.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/todos/ � index (list + search), new, [id]/index (view + mark complete), [id]/edit |
| Nav | config/modules.ts � permission: todos.view, tab /(app)/(tabs)/todos (label ToDos) |
| Permissions | todos.view, todos.create, todos.update, todos.delete |
Tenant API reference: Tenant API � ToDos.
Quotations (module:quotations)
Sales quotes linked to pipeline opportunities (draft edit, send/accept on mobile; convert/email/PDF remain web).
| Piece | Location |
|---|---|
| API client | lib/api/quotations.ts � GET/POST /quotations, GET/PUT/DELETE /quotations/{id}, POST /quotations/{id}/send, POST /quotations/{id}/accept |
| Types | types/quotations.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/quotations/ � index (list + search), new, [id]/index (view + send/accept), [id]/edit (draft only) |
| Nav | config/modules.ts � permission: quotations.view, tab /(app)/(tabs)/quotations (label Quotes) |
| Permissions | quotations.view, quotations.create, quotations.update, quotations.delete, quotations.send, quotations.accept |
Tenant API reference: Tenant API � Quotations.
Calendar (module:calendar)
Agenda-style mobile surface for scheduled events (week/day grids remain web-only).
| Piece | Location |
|---|---|
| API client | lib/api/calendar.ts � GET /calendar/upcoming, GET/POST /calendar/events, GET/PUT/DELETE /calendar/events/{id}, POST /calendar/events/{id}/cancel |
| Types | types/calendar.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/calendar/ � index (60-day range + search), new, [id]/index (view + cancel), [id]/edit (manual scheduled only) |
| Nav | config/modules.ts � permission: calendar.view, tab /(app)/(tabs)/calendar (label Calendar) |
| Permissions | calendar.view, calendar.create, calendar.update, calendar.delete, calendar.view_all |
Tenant API reference: Tenant API � Calendar.
Meetings (module:meetings)
Meeting scheduling with manual join links on mobile (Zoom/Google OAuth and integrations remain web).
| Piece | Location |
|---|---|
| API client | lib/api/meetings.ts � GET/POST /meetings, GET/PUT/DELETE /meetings/{id}, POST /meetings/{id}/cancel, POST /meetings/{id}/complete |
| Types | types/meetings.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/meetings/ � index (60-day range + search), new, [id]/index (view + join link + complete/cancel), [id]/edit (scheduled only) |
| Nav | config/modules.ts � permission: meetings.view, tab /(app)/(tabs)/meetings (label Meetings) |
| Permissions | meetings.view, meetings.create, meetings.update, meetings.delete, meetings.view_all |
Tenant API reference: Tenant API � Meetings.
Projects (module:projects)
Delivery tracking with status workflow (board view remains web-only).
| Piece | Location |
|---|---|
| API client | lib/api/projects.ts � GET/POST /projects, GET/PUT/DELETE /projects/{id}, POST /projects/{id}/status |
| Types | types/projects.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/projects/ � index (list + search), new, [id]/index (view + status actions), [id]/edit |
| Shared UI | components/forms/ProjectLinkPickers.tsx � optional contact/company/opportunity links |
| Nav | config/modules.ts � permission: projects.view, tab /(app)/(tabs)/projects (label Projects) |
| Permissions | projects.view, projects.create, projects.update, projects.delete, projects.assign |
Tenant API reference: Tenant API � Projects.
Contracts (module:contracts)
Opportunity-linked agreements with draft-only edit and status workflow (convert-to-invoice remains web-only on mobile v1).
| Piece | Location |
|---|---|
| API client | lib/api/contracts.ts � GET/POST /contracts, GET/PUT/DELETE /contracts/{id}, POST /contracts/{id}/status |
| Types | types/contracts.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/contracts/ � index (list + search), new, [id]/index (view + status actions), [id]/edit (draft only) |
| Shared UI | components/forms/ContractLinkPickers.tsx � required opportunity + optional quotation filtered by opportunity |
| Nav | config/modules.ts � permission: contracts.view, tab /(app)/(tabs)/contracts (label Contracts) |
| Permissions | contracts.view, contracts.create, contracts.update, contracts.delete, contracts.assign, contracts.convert |
Tenant API reference: Tenant API � Contracts.
Invoices (module:invoices)
Customer billing documents with draft-only edit, send, and void (recurring series, email, and PDF remain web-only on mobile v1).
| Piece | Location |
|---|---|
| API client | lib/api/invoices.ts — GET/POST /invoices, GET/PUT/DELETE /invoices/{id}, POST /invoices/{id}/send, POST /invoices/{id}/void |
| Types | types/invoices.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/invoices/ — index (list + search), new, [id]/index (view + send/void), [id]/edit (draft only) |
| Shared UI | components/forms/InvoiceLinkPickers.tsx — optional contact, company, and quotation links |
| Nav | config/modules.ts — permission: invoices.view, tab /(app)/(tabs)/invoices (label Invoices) |
| Permissions | invoices.view, invoices.create, invoices.update, invoices.delete, invoices.assign, invoices.send, invoices.void |
Tenant API reference: Tenant API — Invoices.
Payments (module:payments)
Customer payment recording with draft-only edit, post, and void (email receipt, PDF, deposit account, and withholding remain web-only on mobile v1). Requires Invoices module entitlement.
| Piece | Location |
|---|---|
| API client | lib/api/payments.ts — GET/POST /payments, GET/PUT/DELETE /payments/{id}, POST /payments/{id}/post, POST /payments/{id}/void |
| Types | types/payments.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/payments/ — index (list + search), new, [id]/index (view + post/void), [id]/edit (draft only) |
| Shared UI | components/forms/PaymentLinkPickers.tsx — optional contact and company links; unpaid invoice picker on create/edit when Invoices is entitled |
| Nav | config/modules.ts — permission: payments.view, tab /(app)/(tabs)/payments (label Payments) |
| Permissions | payments.view, payments.create, payments.update, payments.delete, payments.post, payments.void |
Tenant API reference: Tenant API — Payments.
Credit Notes (module:credit-notes)
Issue credits against customer invoices with draft-only edit, issue, apply, refund (applied only), and void (email and PDF remain web-only on mobile v1). Requires Invoices module entitlement.
| Piece | Location |
|---|---|
| API client | lib/api/credit-notes.ts — GET/POST /credit-notes, GET/PUT/DELETE /credit-notes/{id}, POST /credit-notes/{id}/issue, POST /credit-notes/{id}/apply, POST /credit-notes/{id}/refund, POST /credit-notes/{id}/void |
| Types | types/credit-notes.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/credit-notes/ — index (list + search), new, [id]/index (view + issue/apply/refund/void), [id]/edit (draft only) |
| Shared UI | unpaid-invoice picker on create; PaymentLinkPickers for optional contact/company overrides |
| Nav | config/modules.ts — permission: credit-notes.view, tab /(app)/(tabs)/credit-notes (label Credits) |
| Permissions | credit-notes.view, credit-notes.create, credit-notes.update, credit-notes.delete, credit-notes.issue, credit-notes.apply, credit-notes.refund, credit-notes.void |
Tenant API reference: Tenant API — Credit Notes.
Estimates (module:estimates)
Pre-sale cost estimates with draft-only edit, send, accept, reject, and convert to invoice (email and PDF remain web-only on mobile v1). Requires Invoices module entitlement for convert.
| Piece | Location |
|---|---|
| API client | lib/api/estimates.ts — GET/POST /estimates, GET/PUT/DELETE /estimates/{id}, POST /estimates/{id}/send, POST /estimates/{id}/accept, POST /estimates/{id}/status, POST /estimates/{id}/convert |
| Types | types/estimates.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/estimates/ — index (list + search), new, [id]/index (view + send/accept/reject/convert), [id]/edit (draft only) |
| Shared UI | components/forms/EstimateLinkPickers.tsx — optional contact, company, quotation, and opportunity links |
| Nav | config/modules.ts — permission: estimates.view, tab /(app)/(tabs)/estimates (label Ests) |
| Permissions | estimates.view, estimates.create, estimates.update, estimates.delete, estimates.send, estimates.accept, estimates.convert |
Tenant API reference: Tenant API — Estimates.
Expenses (module:expenses)
Workspace expense claims with draft-only edit, submit, approve, reject, pay (when Accounting is not installed), and cancel. Record notes and activity timeline on view. Receipt upload, vendor/PO links, and accounting account pickers remain web-only on mobile v1.
| Piece | Location |
|---|---|
| API client | lib/api/expenses.ts — GET/POST /expenses, GET/PUT/DELETE /expenses/{id}, POST /expenses/{id}/submit, approve, reject, pay, cancel |
| Categories | lib/api/expense-categories.ts — GET /expense-categories (picker on create/edit) |
| Types | types/expenses.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/expenses/ — index (list + search), new, [id]/index (view + workflow actions), [id]/edit (draft only) |
| Nav | config/modules.ts — permission: expenses.view, tab /(app)/(tabs)/expenses (label Spend) |
| Permissions | expenses.view, expenses.create, expenses.update, expenses.delete, expenses.submit, expenses.approve, expenses.reject, expenses.pay, expenses.cancel |
Tenant API reference: Tenant API — Expenses.
Products (module:products)
Product catalogue CRUD with category picker, pricing fields, and stock-tracking toggle. Record notes and activity timeline on view. Rich-text description and category management remain web-only on mobile v1.
| Piece | Location |
|---|---|
| API client | lib/api/products.ts — GET/POST /products, GET/PUT/DELETE /products/{id}, GET /products/next-sku |
| Categories | lib/api/product-categories.ts — GET /product-categories (picker on create/edit) |
| Types | types/products.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/products/ — index (list + search), new, [id]/index (view), [id]/edit |
| Nav | config/modules.ts — permission: products.view, tab /(app)/(tabs)/products (label Products) |
| Permissions | products.view, products.create, products.update, products.delete |
Tenant API reference: Tenant API — Products.
Warehouses (module:warehouses)
Warehouse location CRUD with active and default toggles. Record notes and activity timeline on view.
| Piece | Location |
|---|---|
| API client | lib/api/warehouses.ts — GET/POST /warehouses, GET/PUT/DELETE /warehouses/{id} |
| Types | types/warehouses.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/warehouses/ — index (list + search), new, [id]/index (view), [id]/edit |
| Nav | config/modules.ts — permission: warehouses.view, tab /(app)/(tabs)/warehouses (label WH) |
| Permissions | warehouses.view, warehouses.create, warehouses.update, warehouses.delete |
Tenant API reference: Tenant API — Warehouses.
Inventory (module:inventory)
Stock level browsing, quantity adjustments, and warehouse transfers with draft-only transfer edit. Movement history and multi-line transfer UI remain web-only on mobile v1. Requires Products (stock-tracked SKUs) and Warehouses for transfers.
| Piece | Location |
|---|---|
| API client | lib/api/inventory.ts — GET /inventory/stock, POST /inventory/stock/adjust, transfer CRUD + dispatch/complete/cancel |
| Types | types/inventory.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/inventory/ — index (stock list), adjust, transfers/* |
| Nav | config/modules.ts — permission: inventory.view, tab /(app)/(tabs)/inventory (label Stock) |
| Permissions | inventory.view, inventory.adjust, inventory.transfer, inventory.delete |
Tenant API reference: Tenant API — Inventory.
Communication Templates (module:communication-templates)
Reusable WhatsApp message templates with context picker on create/edit. Placeholder picker, preview, render, and use-from-record flows remain web-only on mobile v1.
| Piece | Location |
|---|---|
| API client | lib/api/communication-templates.ts — GET/POST /communication-templates, GET/PUT/DELETE /communication-templates/{id}, GET /communication-templates/meta/contexts |
| Types | types/communication-templates.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/communication-templates/ — index (list + search), new, [id]/index (view), [id]/edit |
| Nav | config/modules.ts — permission: communication-templates.view, tab /(app)/(tabs)/communication-templates (label Tmpl) |
| Permissions | communication-templates.view, communication-templates.create, communication-templates.update, communication-templates.delete |
Tenant API reference: Tenant API — Communication Templates.
Email (module:email)
Read synced personal mailboxes: pick account and folder, search messages, open detail, and mark read when permitted. Compose, IMAP account setup, labels, attachment download, templates, and signatures remain web-only on mobile v1.
| Piece | Location |
|---|---|
| API client | lib/api/email.ts — GET /email/accounts, GET /email/accounts/{uuid}/folders, GET /email/folders/{uuid}/messages, GET /email/messages/{uuid}, PUT /email/messages/{uuid} (mark read) |
| Types | types/email.ts (re-exported from types/api.ts) |
| Helpers | lib/email-format.ts — address formatting and plain-text body preview |
| Routes | app/(app)/(tabs)/email/ — index (mailbox + folder list), [id]/index (message view) |
| Nav | config/modules.ts — permission: email.view, tab /(app)/(tabs)/email (label Mail) |
| Permissions | email.view, email.update (mark read) |
Tenant API reference: Tenant API — Email.
Announcements (module:announcements)
Workspace announcements with read tracking. Every entitled member sees the inbox; users with announcements.create / update / delete manage drafts and publishes. No separate view permission — module entitlement gates the tab.
| Piece | Location |
|---|---|
| API client | lib/api/announcements.ts — GET /announcements/inbox, admin GET /announcements, CRUD, POST /announcements/{id}/read |
| Types | types/announcements.ts (re-exported from types/api.ts) |
| Routes | app/(app)/(tabs)/announcements/ — index, new, [id]/index, [id]/edit |
| Nav | config/modules.ts — module only (no view permission), tab /(app)/(tabs)/announcements (label News) |
| Permissions | announcements.create, announcements.update, announcements.delete |
Tenant API reference: Tenant API — Announcements.
Assets (module:assets)
Company equipment, vehicles, and licences with status, category, purchase, and warranty fields. Assignee, vendor, and employee links display on view when populated by the API; pickers and assign action remain web-only on mobile v1.
| Piece | Location |
|---|---|
| API client | lib/api/assets.ts — GET/POST /assets, GET/PUT/DELETE /assets/{id} |
| Types | types/assets.ts (re-exported from types/api.ts) |
| Labels | lib/asset-labels.ts — status and category display labels |
| Routes | app/(app)/(tabs)/assets/ — index, new, [id]/index, [id]/edit |
| Nav | config/modules.ts — permission: assets.view, tab /(app)/(tabs)/assets |
| Permissions | assets.view, assets.create, assets.update, assets.delete |
Tenant API reference: Tenant API — Assets.
Short links (module:short-links)
Branded short URLs with optional vanity slug, destination URL, expiry, and basic UTM fields. Click analytics and click log remain web-only on mobile v1.
| Piece | Location |
|---|---|
| API client | lib/api/short-links.ts — GET/POST /short-links, GET/PUT/DELETE /short-links/{id} |
| Types | types/short-links.ts (re-exported from types/api.ts) |
| Labels | lib/short-link-labels.ts — status display labels |
| Routes | app/(app)/(tabs)/short-links/ — index, new, [id]/index, [id]/edit |
| Nav | config/modules.ts — permission: short-links.view, tab /(app)/(tabs)/short-links (label Links) |
| Permissions | short-links.view, short-links.create, short-links.update, short-links.delete |
Tenant API reference: Tenant API — Short links.
Documents (module:documents)
Workspace file library on Storage — upload files from the device, browse/search, edit title/description/category, download/share, and soft-delete. Requires entitled Storage plus Documents.
| Piece | Location |
|---|---|
| API client | lib/api/documents.ts — GET/POST /documents, GET/PUT/DELETE /documents/{id}; GET /documents/{id}/download via lib/document-download.ts |
| Categories | lib/api/document-categories.ts — read-only list for create/edit pickers |
| Types | types/documents.ts (re-exported from types/api.ts) |
| Helpers | lib/document-labels.ts — file size formatting; lib/document-upload.ts — multipart file append |
| Routes | app/(app)/(tabs)/documents/ — index, new, [id]/index, [id]/edit |
| Nav | config/modules.ts — permission: documents.view, tab /(app)/(tabs)/documents (label Docs) |
| Permissions | documents.view, documents.create, documents.update, documents.delete |
| Native modules | expo-document-picker, expo-file-system, expo-sharing |
Record links, category CRUD, trash filters, restore/force delete, bulk delete, and file replace remain web-only on mobile v1.
Tenant API reference: Tenant API — Documents.
Help desk (module:help-desk)
Support tickets with subject, description, priority, category, due date, notes, close/reopen, and status transitions. Assignee scoping matches web when the actor lacks help-desk.assign.
| Piece | Location |
|---|---|
| API client | lib/api/help-desk.ts — GET/POST /help-desk, GET/PUT/DELETE /help-desk/{id}, POST .../close, POST .../reopen, POST .../status, POST .../notes |
| Categories | lib/api/help-desk-categories.ts — read-only list for create/edit pickers |
| Types | types/help-desk.ts (re-exported from types/api.ts) |
| Labels | lib/help-desk-labels.ts — status and priority display labels |
| Routes | app/(app)/(tabs)/help-desk/ — index, new, [id]/index, [id]/edit |
| Nav | config/modules.ts — permission: help-desk.view, tab /(app)/(tabs)/help-desk (label Tickets) |
| Permissions | help-desk.view, help-desk.create, help-desk.update, help-desk.delete, help-desk.close, help-desk.reopen |
Attachments, assign, contact/company/KB links, category CRUD, stats, and trash/restore remain web-only on mobile v1. Record notes and activity timeline on view.
Tenant API reference: Tenant API — Help desk.
Knowledge base (module:knowledge-base)
Help articles with title, excerpt, plain-text body (stored as simple HTML), category, and draft/published/archived status. View-only actors see published articles from the API; editors can manage drafts and lifecycle.
| Piece | Location |
|---|---|
| API client | lib/api/knowledge-base.ts — GET/POST /knowledge-base, GET/PUT/DELETE /knowledge-base/{id} |
| Categories | lib/api/knowledge-base-categories.ts — read-only list for create/edit pickers |
| Types | types/knowledge-base.ts (re-exported from types/api.ts) |
| Labels | lib/knowledge-base-labels.ts — status display labels |
| HTML helpers | lib/knowledge-base-html.ts — plain text ↔ simple HTML for body |
| Routes | app/(app)/(tabs)/knowledge-base/ — index, new, [id]/index, [id]/edit |
| Nav | config/modules.ts — permission: knowledge-base.view, tab /(app)/(tabs)/knowledge-base (label KB) |
| Permissions | knowledge-base.view, knowledge-base.create, knowledge-base.update, knowledge-base.delete |
Rich TipTap editor, attachments, category CRUD, slug field, and trash/restore remain web-only on mobile v1. Record notes and activity timeline on view.
Tenant API reference: Tenant API — Knowledge base.
Team chat (module:team-chat)
Workspace channels and direct messages. List conversations, open a thread, join channels you can access, start DM or group DM (requires users.list for the people picker), send text messages when team-chat.messages.create is granted, and mark conversations read on open.
| Piece | Location |
|---|---|
| API client | lib/api/team-chat.ts — GET/POST /conversations, messages, join, read |
| Users picker | lib/api/users.ts — GET /users (per_page: 100) for new DM/group flows |
| Types | types/team-chat.ts (re-exported from types/api.ts) |
| Helpers | lib/team-chat-utils.ts — conversation titles and message sort |
| Routes | app/(app)/(tabs)/team-chat/ — index, new, [id]/index |
| Nav | config/modules.ts — permission: team-chat.view, tab /(app)/(tabs)/team-chat (label Chat) |
| Permissions | team-chat.view, team-chat.messages.create (+ channel/message manage permissions on web) |
Realtime (Reverb), attachments, reactions, pins, threads, channel create/settings, message edit/delete, member management, and global message search remain web-only on mobile v1.
Tenant API reference: Tenant API — Team chat.
WhatsApp Cloud (module:whatsapp-cloud)
Customer WhatsApp inbox when the workspace connection is active. Browse conversations, read threads, mark read, open chats by phone number (whatsapp-cloud.send), send free-form text inside the customer service window, and send approved templates when the window is closed.
| Piece | Location |
|---|---|
| API client | lib/api/whatsapp-cloud.ts — integration status, conversations, messages, templates |
| Types | types/whatsapp-cloud.ts (re-exported from types/api.ts) |
| Labels | lib/whatsapp-cloud-labels.ts — display names and message body helpers |
| Routes | app/(app)/(tabs)/whatsapp-cloud/ — index, new, [id]/index |
| Nav | config/modules.ts — permission: whatsapp-cloud.view, tab /(app)/(tabs)/whatsapp-cloud (label WA) |
| Permissions | whatsapp-cloud.view, whatsapp-cloud.send |
OAuth connect, media send/download, lead link/assign, template sync, integration settings, and realtime inbox updates remain web-only on mobile v1.
Tenant API reference: Tenant API — WhatsApp Cloud.
Automation (module:automation)
Monitor workspace workflows, toggle active state, trigger manual runs (automation.run), and inspect execution history with step logs.
| Piece | Location |
|---|---|
| API client | lib/api/automation.ts — workflows CRUD subset, activate/deactivate, run, runs list/detail |
| Types | types/automation.ts (re-exported from types/api.ts) |
| Labels | lib/automation-labels.ts — status and run title helpers |
| Routes | app/(app)/(tabs)/automation/ — index, [id]/index, runs/index, runs/[id]/index |
| Nav | config/modules.ts — permission: automation.view, tab /(app)/(tabs)/automation (label Auto) |
| Permissions | automation.view, automation.update, automation.delete, automation.run |
Visual builder, create/edit workflows, templates, and trigger/action catalog browsing remain web-only on mobile v1.
Tenant API reference: Tenant API — Automation.
Analytics (module:analytics)
Executive KPI overview and domain reports when the workspace has entitled source modules. Preset period filters (this month through last year); open CRM, Sales, Billing, Purchasing, or People for metrics plus row lists.
| Piece | Location |
|---|---|
| API client | lib/api/analytics.ts — overview and domain reports |
| Types | types/analytics.ts (re-exported from types/api.ts) |
| Labels | lib/analytics-labels.ts — area titles and metric formatting |
| Periods | lib/dashboard-period.ts + components/analytics/AnalyticsPeriodField.tsx |
| Routes | app/(app)/(tabs)/analytics/ — index, [area]/index |
| Nav | config/modules.ts — permission: analytics.view, tab /(app)/(tabs)/analytics (label Stats) |
| Permissions | analytics.view |
Charts, CSV export, and custom date ranges remain web-only on mobile v1.
Tenant API reference: Tenant API — Analytics.
Financial Reports (module:financial-reports)
Posted-journal financial statements: trial balance, profit and loss, balance sheet, and aged receivables. Pick a report, set as-of or from/to dates (YYYY-MM-DD), and run on device.
| Piece | Location |
|---|---|
| API client | lib/api/financial-reports.ts — trial balance, P&L, balance sheet, aged receivables |
| Types | types/financial-reports.ts (re-exported from types/api.ts) |
| Labels | lib/financial-reports-labels.ts — report titles and ledger amount formatting |
| Dates | lib/datetime.ts — todayAppDate() helper |
| Routes | app/(app)/(tabs)/financial-reports/ — index |
| Nav | config/modules.ts — permission: financial-reports.view, tab /(app)/(tabs)/financial-reports (label Fin) |
| Permissions | financial-reports.view |
CSV export remains web-only on mobile v1.
Tenant API reference: Tenant API — Financial reports.
Accounting (module:accounting)
Chart of accounts and manual journal entries: browse accounts, create draft journals with balanced debit/credit lines, post, and void.
| Piece | Location |
|---|---|
| API clients | lib/api/accounts.ts, lib/api/journal-entries.ts — accounts CRUD, journal CRUD, post, void |
| Types | types/accounting.ts (re-exported from types/api.ts) |
| Labels | lib/accounting-labels.ts — account types, journal status, picker labels |
| Form | components/forms/JournalEntryForm.tsx — balanced multi-line journal editor |
| Routes | app/(app)/(tabs)/accounting/ — hub, accounts/*, journals/* |
| Nav | config/modules.ts — permission: accounting.view, tab /(app)/(tabs)/accounting (label Acct) |
| Permissions | accounting.view, accounting.create, accounting.update, accounting.delete, accounting.post, accounting.void |
General ledger inquiry, transfers, bank reconciliation, accounting periods, opening balances, tax types, and set-balance on cash/bank accounts remain web-only on mobile v1.
Tenant API reference: Tenant API — Accounting.
Employees (module:employees)
Workspace employee directory: browse people records, create and edit employment details, and link workspace users when permitted.
| Piece | Location |
|---|---|
| API clients | lib/api/employees.ts, lib/api/departments.ts (picker when Departments entitled) |
| Types | types/employees.ts (re-exported from types/api.ts) |
| Labels | lib/employee-labels.ts — status, employment type, department formatting |
| Form | components/forms/EmployeeFormFields.tsx — shared create/edit fields |
| Routes | app/(app)/(tabs)/employees/ — index, new, [id]/index, [id]/edit |
| Nav | config/modules.ts — permission: employees.view, tab /(app)/(tabs)/employees (label Staff) |
| Permissions | employees.view, employees.create, employees.update, employees.delete |
Payroll, department stats/reports, and trash/restore remain web-only on mobile v1.
Tenant API reference: Tenant API — Employees.
Attendance (module:attendance)
Daily attendance records per employee: list and filter, record attendance, self check-in/check-out for linked employees, and manager corrections.
| Piece | Location |
|---|---|
| API client | lib/api/attendance-records.ts — list, CRUD on /attendance-records |
| Types | types/attendance.ts (re-exported from types/api.ts) |
| Labels | lib/attendance-labels.ts — status labels and time formatting |
| Access | lib/attendance-access.ts — manager vs self-service role gate |
| Form | components/forms/AttendanceFormFields.tsx — shared create/edit + employee picker |
| Routes | app/(app)/(tabs)/attendance/ — index, new, [id]/index, [id]/edit |
| Nav | config/modules.ts — permission: attendance.view, tab /(app)/(tabs)/attendance (label Clock) |
| Permissions | attendance.view, attendance.create, attendance.update, attendance.delete |
KPI stats, date-range filters, trash/restore, geolocation, and office-hours automation remain web-only on mobile v1. Requires Employees module entitlement.
Tenant API reference: Tenant API — Attendance.
Leave Management (module:leave-management)
Leave requests workflow: list and filter requests, create and edit drafts, submit for approval, approve or reject pending requests, cancel, and view employee leave balances for the request year.
| Piece | Location |
|---|---|
| API clients | lib/api/leave-requests.ts, lib/api/leave-types.ts (picker), lib/api/leave-balances.ts (read-only on view) |
| Types | types/leave-management.ts (re-exported from types/api.ts) |
| Labels | lib/leave-management-labels.ts — status labels |
| Access | lib/leave-management-access.ts — admin vs self-service employee gate |
| Form | components/forms/LeaveRequestFormFields.tsx — shared create/edit fields |
| Routes | app/(app)/(tabs)/leave-management/ — index, new, [id]/index, [id]/edit |
| Nav | config/modules.ts — permission: leave-management.view, tab /(app)/(tabs)/leave-management (label Leave) |
| Permissions | leave-management.view, create, update, delete, approve |
Leave type CRUD, balance administration, trash/restore, salary-deduction override UI, and date-range list filters remain web-only on mobile v1. Requires Employees module entitlement for employee picker and deep links.
Tenant API reference: Tenant API — Leave Management.
Payroll (module:payroll)
Payroll profiles per employee and pay run workflow: generate periods from profiles, review lines, approve, mark paid, and post to the journal.
| Piece | Location |
|---|---|
| API clients | lib/api/payroll-profiles.ts, lib/api/pay-runs.ts |
| Types | types/payroll.ts (re-exported from types/api.ts) |
| Labels | lib/payroll-labels.ts — frequency, status, amount formatting |
| Forms | components/forms/PayrollProfileFormFields.tsx, components/forms/PayRunFormFields.tsx |
| Routes | app/(app)/(tabs)/payroll/ — hub, profiles/*, pay-runs/* |
| Nav | config/modules.ts — permission: payroll.view, tab /(app)/(tabs)/payroll (label Pay) |
| Permissions | payroll.view, create, update, delete, approve, pay, post |
Pay run line editing, journal debit/credit account picker, trash/restore, and employee self pay stubs remain web-only on mobile v1. Requires Employees module entitlement for profile employee picker and deep links.
Tenant API reference: Tenant API — Payroll.
Departments (module:departments)
Organize workspace teams: create departments, assign managers, tag users and employees, and review Leads/Tasks performance for linked members.
| Piece | Location |
|---|---|
| API client | lib/api/departments.ts — list, CRUD, performance read |
| Types | types/departments.ts (re-exported from types/api.ts) |
| Labels | lib/department-labels.ts — status labels and manager gate |
| Form | components/forms/DepartmentFormFields.tsx — shared create/edit fields |
| Routes | app/(app)/(tabs)/departments/ — index, new, [id]/index, [id]/edit |
| Nav | config/modules.ts — permission: departments.view, tab /(app)/(tabs)/departments (label Depts) |
| Permissions | departments.view, create, update, delete, manage_members, assign_manager, view_performance |
Stats dashboard, full performance reports, trash/restore, and dedicated attach/detach member endpoints remain web-only on mobile v1. Employee deep links require Employees module entitlement.
Tenant API reference: Tenant API — Departments.
Vendors (module:vendors)
Supplier directory for purchasing: list vendors, capture billing details, assign owners, and add notes from your phone.
| Piece | Location |
|---|---|
| API client | lib/api/vendors.ts — list, CRUD, assign, add note |
| Types | types/vendors.ts (re-exported from types/api.ts) |
| Labels | lib/vendor-labels.ts — status labels |
| Form | components/forms/VendorFormFields.tsx — shared create/edit fields |
| Routes | app/(app)/(tabs)/vendors/ — index, new, [id]/index, [id]/edit |
| Nav | config/modules.ts — permission: vendors.view, tab /(app)/(tabs)/vendors (label Vend) |
| Permissions | vendors.view, create, update, delete, assign |
Stats dashboard, trash/restore, dedicated assign endpoint UI, and default withholding tax picker remain web-only on mobile v1. Record notes and activity timeline on view.
Tenant API reference: Tenant API — Vendors.
Purchase Orders (module:purchase-orders)
Create supplier purchase orders, send them, mark receipt (with optional warehouse for stock), cancel, convert to expenses, and add notes from your phone. Requires Vendors module entitlement for vendor picker.
| Piece | Location |
|---|---|
| API client | lib/api/purchase-orders.ts — list, CRUD, send, receive, cancel, convert, add note |
| Types | types/purchase-orders.ts (re-exported from types/api.ts) |
| Labels | lib/purchase-order-labels.ts — status labels and money formatting |
| Routes | app/(app)/(tabs)/purchase-orders/ — index, new, [id]/index, [id]/edit |
| Nav | config/modules.ts — permission: purchase-orders.view, tab /(app)/(tabs)/purchase-orders (label POs) |
| Permissions | purchase-orders.view, create, update, delete, assign, send, receive, cancel, convert |
PDF download, email vendor, stats dashboard, trash/restore, multi-line editor, and product picker remain web-only on mobile v1. Record notes and activity timeline on view.
Tenant API reference: Tenant API — Purchase Orders.
Resellers (module:resellers)
Partner directory with commission rates: list resellers, capture contact and company details, assign owners, and add notes from your phone.
| Piece | Location |
|---|---|
| API client | lib/api/resellers.ts — list, CRUD, assign, add note |
| Types | types/resellers.ts (re-exported from types/api.ts) |
| Labels | lib/reseller-labels.ts — status and commission labels |
| Form | components/forms/ResellerFormFields.tsx — shared create/edit fields |
| Routes | app/(app)/(tabs)/resellers/ — index, new, [id]/index, [id]/edit |
| Nav | config/modules.ts — permission: resellers.view, tab /(app)/(tabs)/resellers (label Resel) |
| Permissions | resellers.view, create, update, delete, assign |
Stats dashboard, trash/restore, invite login, and dedicated assign endpoint UI remain web-only on mobile v1. Record notes and activity timeline on view.
Tenant API reference: Tenant API — Resellers.
Reseller Payouts (module:reseller-payouts)
Commission ledger for reseller and owner payouts: browse accrued entries, filter by status and party, and approve, mark paid, or void from your phone.
| Piece | Location |
|---|---|
| API client | lib/api/reseller-payouts.ts — list, stats, get, approve, pay, void |
| Types | types/reseller-payouts.ts (re-exported from types/api.ts) |
| Labels | lib/reseller-payout-labels.ts — status, party, rate, and money labels |
| Routes | app/(app)/(tabs)/reseller-payouts/ — index, [id]/index |
| Nav | config/modules.ts — permission: reseller-payouts.view, tab /(app)/(tabs)/reseller-payouts (label Payout) |
| Permissions | reseller-payouts.view, approve, pay, void |
Stats dashboard KPI strip remains web-only on mobile v1. Entries are system-generated when linked invoices are fully paid (no create/edit on mobile).
Tenant API reference: Tenant API — Reseller Payouts.
Storage (module:storage)
Workspace file storage usage: see how much content storage your workspace has consumed and which capacity pack is active.
| Piece | Location |
|---|---|
| API client | lib/api/storage.ts — usage summary |
| Types | types/storage.ts (re-exported from types/api.ts) |
| Labels | lib/storage-labels.ts — byte formatting and pack labels |
| Routes | app/(app)/(tabs)/storage/ — index (usage dashboard) |
| Nav | config/modules.ts — permission: storage.view, tab /(app)/(tabs)/storage (label Store) |
| Permissions | storage.view |
Marketplace pack purchase and Settings → Storage panel remain web-only on mobile v1.
Tenant API reference: Tenant API — Storage.
Branded (module:branded)
Custom website address for the workspace: view connection status, copy/share DNS records, propose a hostname, verify DNS, and remove the address when permitted.
| Piece | Location |
|---|---|
| API client | lib/api/branded.ts — show, propose, verify, remove |
| Types | types/branded.ts (re-exported from types/api.ts) |
| Labels | lib/branded-labels.ts — hosting status labels |
| Routes | app/(app)/(tabs)/branded/ — index (setup wizard) |
| Nav | config/modules.ts — permission: branded.view, tab /(app)/(tabs)/branded (label Brand) |
| Permissions | branded.view, branded.manage |
Settings → General logo upload and full branding panel remain web-only on mobile v1.
Tenant API reference: Tenant API — Branded.
EloSync AI (module:ai)
Workspace assistant chat: list conversations, start threads, send prompts, view credit balance, read structured insights and references, and confirm/cancel pending write actions when permitted.
| Piece | Location |
|---|---|
| API client | lib/api/ai.ts — conversations, messages, credits, confirm/cancel actions, lead/opportunity copilot |
| Types | types/ai.ts (re-exported from types/api.ts) |
| Starters | lib/ai-starter-prompts.ts — module/permission-gated quick prompts (includes Search workspace via ai + ai.use) |
| Utils | lib/ai-utils.ts — labels, reference routes, action previews |
| Components | components/ai/AiMessageBubble.tsx, components/ai/AiStructuredResult.tsx, components/records/RecordAiCopilotSection.tsx |
| Routes | app/(app)/(tabs)/ai/ — index, [id]/index |
| Nav | config/modules.ts — permission: ai.use, tab /(app)/(tabs)/ai (label AI) |
| Permissions | ai.use, ai.confirm |
Settings → AI provider configuration remains web-only on mobile v1. Record copilot also mounts on Lead and Opportunity view screens when AI + record view permissions apply.
Tenant API reference: Tenant API — AI.
Module polish (shared record UX)
Reusable record affordances added after the core module program shipped:
| Piece | Location |
|---|---|
| Notes UI | components/records/RecordNotesSection.tsx — list note entries + add note form |
| Timeline UI | components/records/RecordTimelineSection.tsx — read-only activity/audit timeline from show activities |
| Note type | types/notes.ts — shared RecordNote shape |
| Timeline type | types/timeline.ts — shared RecordTimelineEntry shape |
| Record copilot | components/records/RecordAiCopilotSection.tsx — summarize, next action, draft follow-up modal |
| Wired on view | Leads, Opportunities (notes + copilot + timeline), Contacts, Companies, Tasks, Activities, Products, Assets, Expenses, Quotations, Contracts, Projects, Invoices, Payments, Credit notes, Estimates, Warehouses, Knowledge base (notes + timeline); Vendors, Purchase orders, Help desk, Resellers (notes + timeline) |
Notes require {module}.update on each API. Copilot requires module:ai, ai.use, and the parent record view permission.