Local Development and Repo Structure
Main POS Code Areas
active/
emali2/
emali2-pos-suite/
apps/
pos-backoffice/
pos-cashier-web/
packages/
pos-auth-client/
pos-ui/
pos-api-contracts/
mobile/
pos-android/
services/
pos-shared/
pos-service/
docs/
pos/
k8s/
emali2-card-present/
services/
pos-shared/
card-present-service/
k8s/
Detailed POS Structure
POS Backoffice
emali2-pos-suite/apps/pos-backoffice/
src/
api/
components/
context/
pages/
utils/
App.tsx
main.tsx
types.ts
POS Cashier Web
emali2-pos-suite/apps/pos-cashier-web/
src/
api/
components/
context/
pages/
utils/
App.tsx
main.tsx
types.ts
Android
emali2-pos-suite/mobile/pos-android/
app/
core-api/
core-db/
core-model/
docs/architecture/
Backend
emali2-pos-suite/services/
pom.xml
pos-shared/
src/main/java/com/emali2/posshared/security/
pos-service/
src/main/java/com/emali2/posservice/
External Card-Present Integration
emali2-card-present/services/
pom.xml
pos-shared/
src/main/java/com/emali2/posshared/security/
card-present-service/
src/main/java/com/emali2/cardpresentservice/
Documentation
emali2-pos-suite/docs/
pos/
assets/
images/
stylesheets/
javascripts/
mkdocs.yml
Local Dev Commands
POS Backoffice
cd /Users/njorogemaina/Personal/Projects/active/emali2-pos-suite
pnpm --filter @emali2-pos/backoffice dev --host localhost
POS Cashier Web
cd /Users/njorogemaina/Personal/Projects/active/emali2-pos-suite
pnpm --filter @emali2-pos/cashier-web dev --host localhost
POS Android
cd /Users/njorogemaina/Personal/Projects/active/emali2-pos-suite/mobile/pos-android
./gradlew :app:assembleDebug
POS Backend
cd /Users/njorogemaina/Personal/Projects/active/emali2-pos-suite
mvn -f services/pom.xml -pl pos-service -am -DskipTests compile
Terminal request proof is disabled by default for local API work. To exercise the fail-closed Android, dedicated-terminal and browser-WebCrypto policy against an enrolled test terminal, start the service with:
export POS_TERMINAL_REQUEST_PROOF_ENABLED=true
export POS_TERMINAL_REQUEST_PROOF_REQUIRED_PLATFORMS=ANDROID,HARDWARE_POS,WEB
export POS_TERMINAL_REQUEST_PROOF_MAXIMUM_CLOCK_SKEW=PT5M
This uses the enrolled public key and the POS-owned
terminal_request_nonces table. It does not require a terminal client secret.
Cashier web must run on localhost or HTTPS so WebCrypto can create its
non-exportable key; IndexedDB must be enabled.
Card-Present Backend
cd /Users/njorogemaina/Personal/Projects/active/emali2-card-present
mvn -f services/pom.xml -pl card-present-service -am -DskipTests compile
POS Docs
cd /Users/njorogemaina/Personal/Projects/active/emali2-pos-suite/docs
python3 -m mkdocs serve -f mkdocs.yml -a localhost:8020
Recommended Local Ports
pos-backoffice: existing Vite dev portpos-cashier-web: existing Vite dev portplatform core: 8800platform api gateway: 8801POS API: 8821Keycloak: 8181 in the local emali2 setup
Developer Notes
- Keep the cashier web online-first.
- Keep Android offline-first.
- Treat POS Backoffice as online-only in v1.
- Keep item-image bytes in private S3-compatible storage, not in the database; local metadata stays in PostgreSQL.
- Treat card-present as an external sibling repo and service boundary, even while sponsor integration is still sandboxed.
- Treat platform organizations, users, units, and emali settlement as external contracts from the POS suite point of view.
- Configure
VITE_API_BASE_URLfor the POS origin andVITE_PLATFORM_API_BASE_URLfor the platform origin; using the same gateway locally is allowed, but ownership remains path-explicit and the POS service does not proxy platform routes.