# ORIENTATION — what IRIS Chat is, and how to try it

## The problem it solves

A pharmaceutical company's field doctors have to file regular reports on which
products they used, at which hospital, for which patient. Today they do this
through an older app that forces them to **memorize codes**: a code for each
product, a pseudonym for each hospital, an alias for each doctor. It's slow and
error-prone, and doctors put it off.

IRIS Chat lets a doctor **type in plain language instead** — "gave 6 Kenzolin to
Maria Santos, 52, at Cardinal Santos" — and the app does the rest.

## The one design idea that matters

Everything hinges on this: **real names are converted to codes on the doctor's
phone, before anything leaves the device.**

So when the doctor types "gave 6 Kenzolin to Maria Santos, 52, at Cardinal
Santos," what actually gets sent is:

> gave 6 **PRAZ** to **MS 52** at **SATURN 33**

- **Kenzolin** (a product) → `PRAZ`
- **Maria Santos** (the patient) → `MS 52` (initials + age only — never the name)
- **Cardinal Santos** (the hospital) → `SATURN 33`

The conversion happens locally, on the phone, using look-up tables built into the
app. The AI that helps interpret the message, and the network it travels over,
**only ever see the codes.** The patient's real name is never transmitted
anywhere. That's the whole point of the product, and every part of the system is
arranged to preserve it.

(The playful vocabulary — products are "Avatars," hospitals are "Locations,"
doctors are "Players," a report is a "play" — is deliberate. If someone glances at
a doctor's screen, they see a game, not confidential medical activity.)

## The three pieces, and how they connect

```
   ┌─────────────────────┐        codes only         ┌──────────────────────────┐
   │  1. DOCTOR PHONE APP │ ───────────────────────▶ │  2. PROXY SERVER + DB     │
   │  - doctor types      │   (masked message,        │  - holds the AI key       │
   │    plain language    │    codes-only reports)    │  - forwards masked text   │
   │  - converts names to │                           │    to the AI, returns     │
   │    CODES on-device   │ ◀─────────────────────────│    the reply              │
   │  - shows codes only  │      AI reply (codes)     │  - stores codes-only      │
   └─────────────────────┘                            │    reports + the roster   │
                                                       └───────────┬──────────────┘
                                                                   │ reads
                                                       ┌───────────▼──────────────┐
                                                       │  3. ADMIN CONSOLE         │
                                                       │  - back-office web page   │
                                                       │  - sees the filed reports │
                                                       │  - authorized admins can  │
                                                       │    see the few sanctioned │
                                                       │    real names             │
                                                       └──────────────────────────┘
```

1. **The doctor phone app** (`mobile/` folder). What doctors install. It does the
   name-to-code conversion on the device, shows only codes on screen, and sends
   only codes to the server. All the confidentiality logic lives here. The
   packaged phone build (`mobile/www/index.html`) is **generated** from a single
   source — the doctor web app `app/iris_chat_app.html` — and is never hand-edited:
   a change is made in that one file and the phone build is regenerated from it, so
   the two can never quietly drift apart.

2. **The proxy server + database** (`server/` folder). A small program that:
   - **holds the secret AI key** so it never has to live in the app;
   - **forwards the doctor's already-coded message** to the AI service and returns
     the reply;
   - **stores the filed reports** (all codes) and the **roster** — the master
     table that maps each code back to a real product / hospital / doctor.

   The roster is the sensitive part: it's the key that could turn codes back into
   real names. It lives here, on the server, inside company control — **never on a
   doctor's phone.**

3. **The admin console** (`admin/` folder). A single web page the back office uses
   to see what doctors have filed. Most of what it shows is codes. A small number
   of **sanctioned** real names are visible to authorized administrators (explained
   in the tour below). It's a separate page from the doctor app and is never
   installed on a phone.

---

## Hands-on: run it on your laptop in ~15 minutes

You need **Python 3.8 or newer**. Nothing else to install — the server uses only
Python's standard library.

### What will and won't work locally

- **Works fully offline / no key needed:** the name-to-code conversion, filing
  reports, the admin console, sign-in, roles, the audit log. This is enough to see
  everything that matters.
- **Needs a real AI key:** the app's conversational replies (the assistant
  answering back). For this tour you can start the server with a **dummy** key —
  the conversion and the console work; only the chat reply won't come back. To get
  live replies, put a real Anthropic API key in the server's `.env` instead.

### Two terminals

**Terminal 1 — start the server (the proxy + database).**

```bash
cd server
cp .env.example .env          # a starter config file
# Open .env and set ANTHROPIC_API_KEY to any placeholder for the tour,
# e.g.  ANTHROPIC_API_KEY=dummy-key-for-local-test
python3 proxy.py              # starts on http://localhost:8765
```

Check it's alive: open `http://localhost:8765/health` — you should see
`{"ok": true, ...}`. On first start it creates a local database file and fills it
with **demo** doctors, hospitals, and products (all fictional — see FAQ).

**Terminal 2 — serve the two web pages.**

```bash
# from the repository's top folder (not inside server/)
python3 -m http.server 8080   # serves the files on http://localhost:8080
```

One local-only tweak so the phone app can reach your server: open
`mobile/www/config.js` and set

```js
window.IRIS_PROXY_BASE = "http://localhost:8765";
```

(That's just for this local test — don't commit it.)

### The guided tour

**A. Be the doctor, and watch a name become a code.**

1. Open **`http://localhost:8080/mobile/www/index.html`**.
2. Sign in with the demo doctor card: **card ID `IRIS-2607`, PIN `1234`.**
3. Type: **`gave 6 kenzolin to Maria Santos, 52 at Cardinal Santos`** and send.
4. Watch the message you sent appear as **`gave 6 PRAZ to MS 52 at SATURN 33`** —
   the product, patient, and hospital are already codes. The real names never left
   the page. (If you used a dummy key, the assistant's reply won't come; that's
   expected.)

**B. Be the back office, and find that same report.**

5. Open **`http://localhost:8080/admin/index.html?base=http://localhost:8765`**.
6. Sign in as an **admin**: username **`admin`**, password **`admin-demo`**.
7. Go to the **Reports** tab and find the play you just filed. Notice it is stored
   as **codes** (`SATURN 33`, `PRAZ`, `MS 52`) — the report the company keeps
   never contains the patient's name.

**C. Compare what an admin sees versus a viewer.**

8. Sign out, and sign back in as a **viewer**: username **`viewer`**, password
   **`viewer-demo`**.
9. A viewer sees **codes only**. In the **Review queue** and **Feedback** tabs,
   where an admin would see a sanctioned real name, a viewer sees `🔒 admin only`.
   This is enforced on the **server** — the viewer's browser never receives the
   name, so it can't be revealed by fiddling with the page.
10. Sign back in as `admin` and look at those same tabs to see the difference.

**D. Look at the audit log.**

11. As `admin`, open the **Audit log** tab. Every sign-in, and every time an admin
    reveals a real name or makes a change, is recorded — who, what, when. This is
    the accountability trail for the small, controlled set of times a real name is
    ever seen.

That's the system. When you're done, stop both terminals (Ctrl-C) and, if you
edited `mobile/www/config.js`, revert it.

**Next:** [HOSTING.md](HOSTING.md) is your actual task — putting this on a
reachable internal test host.
