AI-powered skill directory for informal workers across Africa — conversational profile builder that removes literacy and digital barriers
# Sokoni
A skill directory built by talking, not typing. Three flows share one live backend:
1. **Build my profile** — a web chat that interviews you into a "trade card"
2. **By text message** — a simulated SMS thread (phone mockup on the page)
3. **Find someone** — a searchable directory of published cards, nearest first
Both conversational channels open by asking which of the two things you are here
to do, rather than assuming you are a worker. On the web that is a pair of
buttons; over SMS it is `1` to list a trade and `2` to find someone. The older
`SKILL` and `FIND ` word commands still work.
## Architecture
```
public/index.html Static frontend. Chat, SMS simulation, and directory.
api/chat.js Serverless function. Holds ANTHROPIC_API_KEY, proxies to Claude.
BOTH the web chat and the SMS simulation POST here.
api/profiles.js Serverless function. Publishes and reads the directory,
and holds the demo seed profiles.
lib/store.js Redis (Upstash) over REST + per-IP rate limiting.
scripts/dev-local.mjs Local dev server, isolated from production. See "Run locally".
```
**One backend, two channels.** `callClaude(channel, messages)` in the frontend is
the only place either flow talks to Claude. It always POSTs to `/api/chat`; the
`channel` field (`"web"` or `"sms"`) only selects which system prompt the server
applies. Same deployed URL, same API key, same rate limiter, same model.
The two system prompts live in `api/chat.js` rather than the browser, so a public
endpoint holding a real API key can't be driven with arbitrary prompts. They
began as a verbatim copy of the prototype's wording and have since been extended
to collect the worker's name, a town-level location, and a phone number.
## What a profile holds
| Field | Required | Notes |
|---|---|---|
| `skill` | **Yes** | Rendered as the card headline |
| `location` | **Yes** | Town or village, ideally with a neighbourhood or landmark |
| `experience` | **Yes** | Free tex …