Orazaka
Pages of the documentation

The mobile app, screen by screen

What the iOS and Android app does today, how to run it against the local stack, its tests, and which screens do not read the server yet.

The app is krizaka/orazaka-mobile-client: Expo SDK 53, React Native 0.79, React Navigation, cloned in the workspace at orazaka-apps/ui/orazaka-mobile-client. It talks to the edge (:8088) with Authorization: Bearer — the same services, the same interceptor pipeline and the same entitlements as the web client.

What this page describes was run on 2026-10-12 on the iOS 27 simulator (iPhone 17, Xcode 27) and the Android 16 emulator (Pixel 8 image) against the local Orazaka stack, signed in as the demo persona (Eric, orazaka demo seed). Where a screen shows something that does not come from the server, it says so.

PlatformState
iOS simulator (iOS 27)✅ builds and runs against the local stack — sign-in, Studios, chat, jobs, connectors, profile
Android emulator (Android 16)✅ development build runs against the local stack — sign-in, Studios, jobs, profile
iPhone / store builds✅ EAS project orazaka-mobile (EAS-managed credentials); iOS builds ship to an internal TestFlight group (App Store Connect record com.krizaka.orazaka), never submitted for review; Android: a preview APK (internal distribution). Every profile of eas.json points at https://dev.orazaka.com/edge
Expo SDK⚠️ 53 — the move to SDK 57 (the other Krizaka apps) is planned; two stopgaps below keep 53 building and launching on Xcode 27 / iOS 27

1. What the app does today

Sign in

E-mail and password (POST /api/v1/auth/login); create an account (/api/v1/auth/register, which may ask to verify the e-mail first), forgot and reset password. The session (token, username, authorities) is kept in the device's secure storage only (expo-secure-store); the navigator shows the app stack only while a session exists.

Sign in

Eric signs in and lands on the Studios (12 s)

Studios

The Studio catalogue (GET /api/v1/studios) — locked Studios listed, not hidden, exactly as on the web — then a Studio's page (GET /api/v1/studios/<key>: price per run, install — or "Ouvrir" for a toolkit Studio such as image, video and voice, which has no installation and runs on its own key, POST /api/v1/studios/<key>/runs) and its run screen (the Studio's input form — an enum input such as a size or an aspect is a row of chips, a number is sent as a number — then the run started and polled: /api/v1/studios/runs/<id>). The run screen shows each step's status while it works, then the outputs as the blueprint typed them: a picture shown inline, a clip or a voice-over played with expo-video (the edge's assets are private: the Bearer goes on the request), a rules report (a lease checked against the law) as cards — failures first, with the passage quoted and the article cited — and a model's text as Markdown (headings, lists, bold, links; never a literal **), the run's own facts (provider, duration) apart from the words.

The Studio catalogue A Studio's page

Eric runs “Qualification de Prospects” from the phone: the form, the steps running, the results (typing and the model’s wait cut, 28 s)

Chat

A message is streamed back token by token (Server-Sent Events, /api/v1/chat/stream/<conversation>), through the interceptor pipeline and the model routing of the stack it runs on. Below, Eric's question and the answer of the local stack. Before the first message the screen shows a presentation card of the sovereign chat — an illustration, not a conversation.

A streamed answer, on the local stack

Eric asks for a note and the answer streams in, from a model on the local stack (24 s)

Jobs

The account's jobs (GET /api/v1/jobs): jobs per day and by kind (charts from @krizaka/charts), then each job with its status and its age.

Jobs

Eric's jobs: per day, by kind, then each one (6 s)

Connectors and profile

Connecteurs lists the account's connector credentials (GET /api/v1/credentials; none for Eric). Profil reads GET /api/v1/profile (name, e-mail, roles) and leads to Abonnement, Console d'intentions (POST /api/v1/intent/route) and Gouvernance, then sign-out.

Profile

What does not come from the server yet

  • Système (the "System Entropy" tab) draws fixed values written in the app — it is not a measure of the stack.
  • Gouvernance lists sample interceptor policies written in the app.
  • Abonnement shows plan cards written in the app; subscribing happens on the web.

Système — fixed values, not a measure

On Android (development build, Android 16 emulator):

The Studios on Android Jobs on Android

A short recording of the smoke run (sign in → a Studio → jobs → profile → sign out): ios-smoke.mp4.


2. Run it on a simulator

Requirements: macOS with Xcode 27 and an iOS simulator runtime, CocoaPods, Node 22, JDK 21 for the stack, and the workspace cloned (node scripts/workspace.mjs clone, then npm install in orazaka-apps/ui).

bash
# 1. The stack: infrastructure, then the services the app calls
orazaka start --mode dev
orazaka dev --only edge,identity,studio,job,billing,router
orazaka demo seed                      # the demo persona (local only)

# 2. The app
cd orazaka-apps/ui/orazaka-mobile-client
npx expo run:ios                       # prebuild, pods, build, install, Metro

The iOS simulator shares the Mac's network, so the default edge address (http://localhost:8088) works. On a phone or the Android emulator, set EXPO_PUBLIC_EDGE_URL (http://10.0.2.2:8088 for the emulator, then npx expo run:android; a development build allows plain HTTP).

Two stopgaps keep SDK 53 working with today's tools, both to delete with the move to SDK 57:

  • Xcode 27 / iOS 27 — plugins/with-xcode27.js: fmt (React Native 0.79) compiled in C++17, no pod below iOS 15.1, and the scene life cycle iOS 27 requires (an app built with the iOS 27 SDK that does not adopt UIScene is stopped at launch).
  • React — React Native renders with its own copy of React's renderer, which must match React exactly: 0.79 ships 19.0.0 while the web apps of the workspace run 19.2.x. The workspace installs React 19.0.0 for this package only (overrides in orazaka-apps/ui/package.json) and metro.config.js resolves every react import to it.

3. Tests

WhatWhere
Unitthe SSE parser, the API client, the session store, job statistics, Studio input schemassrc/**/__tests__/*.test.ts (Jest project logic)
Renderthe app on edge responses recorded as the demo persona: sign-in and its refusal, a stored session, the Studios, the jobs, the profile and sign-out, an unreachable edgesrc/__tests__/app.test.tsx (Jest project screens), fixtures in src/__fixtures__/api
SmokeMaestro: sign in → a Studio → jobs → profile → sign out, on a simulator.maestro/smoke.yaml

The repository's CI builds the workspace and runs npm run validate (lint, type-check, both Jest projects) on every pull request. The Maestro flow runs on a Mac with a simulator and the stack up:

bash
maestro test .maestro/smoke.yaml -e ORAZAKA_EMAIL=<email> -e ORAZAKA_PASSWORD=<password>

4. What is missing

  • Expo SDK 57 — and with it the end of the two stopgaps above.
  • Android: a run on a physical phone (the preview APK is run on the Android 16 emulator and signs in as the persona on dev).
  • Push notifications: the APNs key is still manual; no push yet.
  • Words: the app has an English and a French catalogue (src/i18n/en.json, fr.json); a few server messages still arrive in the server's language.
  • Système, Gouvernance, Abonnement: read from the server instead of values written in the app.
  • Theme: the app follows the device (userInterfaceStyle: automatic); the tab bar carries the same @krizaka/icons glyphs as the web rail.

Edit this page on GitHub