# Showing this to the client

Written 5 August 2026 against `dev` at `c64b01b`, and amended the same day for
self-set recurring to-dos (`3130aae`) and temporary cover (`16e217f`). It is a
running order, not a sales script: every step names the account to use, what the
screen should show, and the one question worth asking while it is up.

The demonstration is the cheapest chance to close the questions that are
blocking work. Ten of them are waiting on a sentence from somebody who will be
in the room, and each is attached below to the screen that makes it obvious.
Ask them there rather than in a document nobody opens.

## Before anybody is watching

Four commands and then the server, in this order. All four are safe to run
twice: none of them truncates anything and a second run performs nothing.

```
bun run db:seed      # the client's own roster, 193 people in 46 departments
bun run db:demo      # a month of plausible work, simulated through the engine
bun run db:panel     # the eleven accounts in docs/test-accounts.csv
bun run job:daily    # generate today, mark what ran out of time, drain the outbox
bun run dev          # http://localhost:3000
```

`db:demo` is worth understanding before you are asked about it, because it is
the first thing a sceptical client will probe. **It never writes a status.** It
generates instances with the real generator, walks the month one day at a time
performing the acts a person would have performed through the same functions
the buttons call, and runs the missed sweep each night. Every `missed` row on
screen is the sweep's own answer. Nothing was arranged to look good.

Sign in with the accounts in `docs/test-accounts.csv`. The passwords are
guessable on purpose and none may survive a deployment (ELEVA-221).

**Every count in this file and in that CSV drifts.** The demonstration data is
generated and then aged by the nightly job, so a task due today is overdue
tomorrow and the missed sweep adds to its own total each night. The numbers
below were measured on 5 August 2026 by calling the services directly. Treat
them as the shape to expect, re-measure before you present, and never read one
out as a fact if the screen beside you disagrees. The screen is right.

## The running order

### 1. The way in

`/login`, signed out. Both languages stacked on every label, no language switch,
because nobody is signed in yet to have a preference. Then `/login/help`, which
is the only recovery path a person has on a network with no email.

**Ask here.** Where do the Admin and HR desks actually sit, what hours, what
extension, and can both really reset a password? Every line on that card was
invented by us, and it is the screen a forgotten password sends 193 people to
(ELEVA-234).

### 2. A worker's morning

Sign in as **nattikan** (English, Accessory Center). Hers is the plate with the
most gone wrong on it: 41 tasks in all, 10 of them missed, and 11 carried over
on the day view as this was written.

`/tasks` opens on the day: 1 task due, with those 11 carried over pinned above
it. Switch to the week (7 in the window) and the month (18). The carried-over
group is work that was owed before the window and still is, and `missed` sits
in it like anything else outstanding, which is the whole of the client's
answer that work owed is work owed. Open one task and finish it with a note.

**Ask here.** What should a person hand in when they finish? A note is captured
and shown to the checker. Whether it should also be a reading, a number, a
photo or a link decides what this screen asks for, and nothing can be built
until somebody says (ELEVA-121).

**And ask.** A missed task stays on this list, because the client answered on 4
August that work owed is work owed. Confirm that is still what they want now
that they can see eleven of them stacked on one person.

### 3. Work she sets for herself

Still as **nattikan**, open **My recurring to-dos** in the sidebar. She can
write a duty on her own position and nobody else's: the position box offers one
choice and the checker box offers one person, herself.

Write one, daily. It becomes an ordinary duty, the engine generates it like any
other, and it will appear on her manager's `/team` with no marking to say it was
self-set. That is the client's answer read exactly: recurring self to-dos are
**visible** to the manager, not approvable by them.

Show that she can stop the one she wrote, and that the duties her manager
assigned to the same position have no such control.

**Say here, do not ask.** One-time personal to-dos are deliberately not built.
The client said not needed, and a private scratch list the system stores is a
list a manager eventually asks to see.

### 4. The check

Sign in as **malai** (Thai, Line Leader Accessory Stock). She is nattikan's
checker on the task just finished, and 7 were already waiting on her.

`/review` is her queue. Approve one and send another back. Show that send-back
returns the task to the assignee as started rather than as new, with the first
attempt's timestamp intact.

Leave nattikan signed in on a second window if you can: the notification
arrives without a page reload.

**Ask here.** `/review` is deliberately not restricted to managers, because
three of the seven checkers in the roster are staff. Confirm that checking is a
job somebody is given and not a rank they hold (ELEVA-148 was decided that way).

### 5. The floor, this morning

Still as **malai**, open `/team`. Her department today: what is late, what is
due, what is waiting at the check, and a thirty-day completion tile. The counts
are the navigation, and repeats of the same duty collapse into one line with a
number rather than filling the screen.

The whole state is in the URL, so a manager can send a colleague exactly what
they are looking at.

### 6. The month, and who may see it

Still as **malai**, open `/kpi`. A row per person in her department over thirty
days: due, done, late, missed.

Then sign back in as **nattikan** and open `/kpi` again. She sees her own four
figures and no table: 28 due, 16 done, 1 late, 10 missed over the thirty days.
They are the same four numbers, to the digit, that her manager saw on the row
for her a moment earlier. That identity was measured rather than assumed, and
it is worth saying out loud, because it is the difference between a number
somebody is judged by and a number they can act on.

**Say here, do not ask.** A person evaluated on a number can see that number.
That was a real decision (ELEVA-116) and the alternative was defensible; if the
client disagrees, it is one guard.

### 7. The two people who are not ordinary

Sign in as **aranya** (Thai, Department Manager Accounting). She is a named
verifier with 4 audits owed, so the Verify button can actually be pressed.
Verification is a sample audit after the check, and it is deliberately not a
sixth status: a task is complete when it is checked, and an audit that never
happens must not leave it reading as unfinished.

Then **narisara** (Thai, staff, Accounting), also a verifier, with 2 owed.
Verification is not a manager's privilege.

### 8. HR, which is where this system is used most

Sign in as **narin** (admin, English, Managing Director) or **hr.manager**
(admin, Thai).

`/admin/people` is the roster. Open one person: the screen opens a login,
generates a first password once, and archives a leaver. Show the generated
password: three groups of four, from an alphabet with no O, 0, I, l or 1,
because it is read off a paper slip and typed on a factory terminal.

Then try to sign in as **somsak.left**. She is refused, and her seventeen past
tasks still carry her name.

**Ask here.** How do 193 people get a username on the day this goes live? HR
chooses one per person today, which is right for a new hire and wrong for a
roster where given names collide (ELEVA-159). And ask what a password must be
worth: it is six characters so the development logins can be short, and
everybody types it on a shared terminal several times a day (ELEVA-221).

**And ask, holding the roster open.** Employee 00000001 is a Director and the
client's own export labels them Staff, so they see only their own tasks. One
cell decides it, and it is theirs to say, not ours (ELEVA-158).

### 9. The structure, which only admin touches

Still signed in as admin.

`/positions` lists all 193, including the two positions with nobody in them.
Open one: the job description and its duties, which is the only place a duty is
written. Everything else in the system is a projection of this screen, and a
projection that disagrees with it is the bug.

On the same position page, under the holder, is **temporary cover**: who is
standing in, from when to when, and a way to end it. Open one for a few days
with somebody from another department, which is what covering usually is.

Say what it does and what it deliberately does not: the duties of that position
go to the stand-in for those days and leave the holder's list, the stand-in's
own work carries on untouched, and their working week is the one that decides
which days the work falls on, because they are the person who has to be there.
Ending it early does not take back work already handed out. A cover scheduled
but not started is labelled differently, because ending that one deletes it
rather than shortening it.

**Ask here.** The client's answer said the tasks should be "copied temporarily"
onto the covering person's position. We did not copy rows, because that would
make the stand-in's own job description list duties that are not their job.
Confirm the behaviour is what they meant, since it is the same result by a
different route.

`/admin/holidays` is the calendar, imported once a year as a CSV. It is the
third input to every date the engine computes.

**Ask here, and this one is blocking.** Eight Buddhist observances are loaded,
every date checked against the weekday the file itself states. The government
holidays are missing, and two of the eight fall on a Sunday with no replacement
day recorded. Until the full 2026 calendar arrives the engine will put work on
days the factory is shut, silently (ELEVA-150).

**And ask, with the calendar on screen.** Does any work continue on a holiday?
The engine stops everything and moves it to the next working day. If the night
guard still walks his round on New Year's Day, that work disappears on the day
it matters most, and nothing today can say otherwise (ELEVA-151).

`/admin/recurrence` explains the recurrence rules in words, so they can be
argued with by people who will never open `lib/recurrence.ts`. Use it if
anybody challenges a due date.

**Ask here.** A weekly task is given until the end of Sunday. The specification
recommends the end of the last working day, now Saturday. One day, on the day
nobody works, and it changes what counts as missed (ELEVA-223).

### 10. The language

On any screen, switch to Thai from the sidebar. Names, titles and departments
stay exactly as the roster spells them, because they are data. Everything
around them changes, and Thai dates are Buddhist Era: 2569, not 2026.

The switch sits above the person's own menu on purpose. Somebody who cannot
read the interface should not have to open a menu labelled in the language they
cannot read in order to change it.

**Say here.** The preference lives on the person, not in the browser. Terminals
are shared, and a preference left on a device is inherited by whoever walks up
next.

### 11. Session length, if anybody sits down

**Ask.** A session lasts eight hours, which is a shift. It was seven days,
which was the library's default and nobody's decision. Whether an office
machine should behave like a screen at the end of a line is unanswered
(ELEVA-220).

## What not to show, and why

**Two sidebar entries point nowhere.** My job description and Reminders are
`#` and are not built. Say so if asked rather than clicking them.

**Notifications are in-app only.** The outbox, the fan-out and the live stream
work. There is no delivery to a phone or to any other channel yet, and the
server for it exists only in a compose file (ELEVA-154).

**Nothing has been deployed.** `deploy/` holds a Dockerfile and a compose file
for the Raspberry Pi target and none of it has run at the factory. Do not
promise a date from this room.

**The palette is not settled.** The screens do not match the design mockups and
will not until somebody decides the colours. Show the behaviour and say the
appearance is open.

## What a human still has to look at

Nothing in the build loop has eyes. Every number in this document and in
`docs/test-accounts.csv` was measured by querying the services directly, which
proves the data and proves nothing about the screen. Layout, contrast, Thai
line breaking, what a screen reader announces and how any of it behaves on a
small display have not been checked by anybody. That is ELEVA-171, and it
should be done before the demonstration rather than during it.
