尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Homilador ayollar xavfini tuman darajasida real vaqtda kuzatish.
A perinatal risk registry for Xorazm: when a pregnant woman's results worsen,
the district maternal-and-child-health specialist (OvaBMU) sees it on screen,
live, instead of finding out days later. (ona is the internal package name.)
Built for the Xorazm AI Xakaton, problem #9: *"Homilador ayollar va chaqaloqlar
salomatligi tuman darajasida real vaqtda monitoring qilinmaydi: tahlillar
yomonlashsa, OvaBMU mutaxassislari kech xabar topadi."*
AI design — what the model does and what it never does查看完整 README ↗Homilador ayollar xavfini tuman darajasida real vaqtda kuzatish.
A perinatal risk registry for Xorazm: when a pregnant woman's results worsen,
the district maternal-and-child-health specialist (OvaBMU) sees it on screen,
live, instead of finding out days later. (ona is the internal package name.)
Built for the Xorazm AI Xakaton, problem #9: "Homilador ayollar va chaqaloqlar salomatligi tuman darajasida real vaqtda monitoring qilinmaydi: tahlillar yomonlashsa, OvaBMU mutaxassislari kech xabar topadi."
| Who | Where | What they do |
|---|---|---|
| Midwife (akusherka) | /entry, /patients/new, /visits — phone-first | Registers a woman, types a visit note or photographs a lab sheet / uploads a PDF, lets the AI fill the form, checks every value, saves. Sees the zone, the factors behind it, the WHO visit schedule and static protocol reminders. Sees who is due today and who is late. |
| OvaBMU specialist | /dashboard, /registry, /escalations, /visits, /patients/:id | Dashboard of every district; drill-down district → zone → woman; a live alert queue with acknowledge and close; the appointments calendar; each woman's history, chart, stored schedule with the reminders sent, lab documents and her own Telegram messages. A toast, badge and sound when an alert opens, and optionally a Telegram alert and a morning digest on their own phone. |
| The pregnant woman | Telegram only — no app, no password | Links with a six-character code the midwife reads out. Reports how she feels; danger signs reach the specialist's queue. Gets visit reminders two days before and on the morning of each contact. |
The system has two layers, and the line between them is the safety design.
Layer 1 — the decision: a transparent rule engine, not a model.
src/lib/risk.ts is a weighted, versioned point table. Four findings force red on
their own (blood pressure 160 systolic or 110 diastolic and above, suspected
pre-eclampsia, haemoglobin < 70 g/L, bleeding); the rest add points (red ≥ 7,
yellow ≥ 3). Every score is stored with
its inputs and the rules version that produced it, so any past result can be
reproduced from its own row years later. Missing data is shown as unknown risk,
never as a reassuring green. The visit schedule (schedule.ts, WHO 2016
eight-contact model) is arithmetic on a date; danger-sign urgency
(danger-signs.ts) is a fixed WHO list. None of these involve a model.
Layer 2 — the AI: Claude Haiku 4.5, extraction only.
The model reads what a person already said — a midwife's Uzbek note, or a
patient's Telegram message — and reports it back as structured fields
(api/extract.ts). It never scores, never triages, never picks a date or a
medicine, and never writes anything a patient reads. Every yes/no field has three
answers, true / false / not_mentioned, so "nobody measured it" can never be
stored as "measured and normal". From the system prompt:
"Not mentioned" is "not_mentioned". It is NEVER "false". A finding nobody wrote about is not a finding that was ruled out. [...] a skipped test recorded as a negative test can hide a woman who needs urgent care.
The same rules apply to a photo or PDF of a lab sheet: the model reads the values written on it, never a printed reference range, and leaves unreadable handwriting or repeated results empty for the midwife to type. Photos are redrawn in the browser (smaller, and without the GPS position a phone photo carries); the file is kept with the visit in a private Storage bucket.
Measured, not assumed. npm run eval:ai runs 23 fixed cases — midwife
notes in Uzbek and Russian, patient messages — through the real endpoint and
scores every field. On Claude Haiku 4.5: 23/23 cases and 441/441 fields right
in two runs, with zero invented values and zero "not mentioned" reported as
absent; median 2.2 s per note. Cases include a test not done, explicit
negatives, g/dL haemoglobin, half a blood pressure, a plan that is not a
history, and a note that states nothing at all.
The midwife sees an AI badge on every field the model filled and confirms or corrects each one before saving; the audit trail keeps the model's raw answer and whether she changed it. If the AI is slow (8-second limit), down, or the key is missing, the form simply stays a normal typed form.
Who is liable for a wrong recommendation? The system makes no recommendation.
It reports a WHO-sourced factor list and a zone from published rules; a specialist
decides. The Telegram bot never diagnoses, never reassures, and never names a
medicine — every sentence it can send is a fixed string in bot/messages.ts.
scoreAssessment returns qizil.ochiq → qabul), then closes with a note
(qabul → yopiq). Time-to-acknowledge is shown on the queue and dashboard.The same path runs when the woman herself reports a danger sign on Telegram; the queue marks those as coming from her own phone.
The schedule is arithmetic on the LMP (WHO 2016, eight contacts), adjusted by zone and stored as rows the whole system reads from:
/visits:
overdue, today, tomorrow, the next two weeks — red first, and those with no
Telegram marked remind by phone. With STAFF_ALERT_CHAT_ID set, the
specialist also gets a 07:00 digest on Telegram (counts only, no names).From 09:00 the day after a planned contact with no visit entered:
STAFF_ALERT_CHAT_ID) gets one Telegram message per
contact: district, date, and whether she is on Telegram or must be phoned.
Dry run unless STAFF_ALERTS=send, like every staff alert; no names.The visit itself is not marked missed (see 004): it stays planned until a midwife records it or the schedule is rewritten.
npm install
cp .env.example .env.local # fill in the Supabase URL and anon key, Anthropic key, bot token
Database. Run each file in supabase/migrations/ in order (001 → 008) in the
Supabase SQL editor. Enable anonymous sign-ins (Authentication → Providers).
007 adds document storage, reminder retries, Tashkent-dated visits and live
updates for new registrations; the app runs without it, and says so where a
feature needs it. 008 adds the next-morning follow-up and survey above; without
it the bot runs as before and logs that 008 is missing.
npm run dev # the web app, with /api/extract served locally
npm run bot # the Telegram bot — a separate, long-running process
npm run test:run # unit tests (vitest)
npm run lint # oxlint
npx tsc -b # typecheck
npm run eval:ai # the AI extraction against 23 fixed cases (live model, a few cents)
/api/extract deploys as a Vercel serverless function (vercel.json); set the
same environment variables in the Vercel project.
npm run seed # dry run: prints the plan, writes nothing
npm run seed -- --apply # writes 14 synthetic women across 5 districts
npm run demo:worsen # the live moment, if not typed on stage
npm run seed -- --retire # takes the demo women off the registry afterwards
The seed covers every zone, one woman not yet assessed, one overdue, an acknowledged and a closed escalation, an open clinic alert and an open alert from a patient's own Telegram. Every value goes through the real scorer and the real write paths — no zone is typed in by hand. Every row is marked synthetic in the database, and no phone number or Telegram chat is attached.
On stage: open /dashboard as OvaBMU mutaxassisi on one screen and
/entry as Akusherka on another. Pick Oydin Karimova (Urganch, currently
sariq), enter BP 164/112 with protein in the urine, save. Her row turns red on the
registry, the alert appears in the queue with a sound, and it can be
acknowledged and opened to her timeline.
Telegram alert to a specialist (optional): set STAFF_ALERT_CHAT_ID (one
person's id from @userinfobot, or a group's) and run npm run bot. It only
logs what it would send until STAFF_ALERTS=send is set. APP_URL adds a link.
Real, running on real data: the rule engine and its tests; AI extraction on real Uzbek and Russian input — typed notes and lab-sheet photos/PDFs — with the fallback to typing; the appointments calendar and reminder tracking; the append-only record and its database constraints; the district registry, dashboard and queue reading Supabase and updating over Realtime; acknowledge/close writes; the patient page; patient registration and the name search; the Telegram bot (linking, self-report triage, visit reminders, district announcements, specialist alerts).
Stand-ins for the hackathon:
src/lib/supabase.ts), and the RLS policies treat every session as clinical
staff (supabase/migrations/001_schema.sql). Anyone who can open the app can
read and write patient records.src/lib/role.ts). It is not a login and not a permission.Also not yet built: infant (post-birth) follow-up; import from existing clinic records; the link code is derived from the pregnancy id and cannot be rotated (fine for a pilot, replaced by an invitation table at scale).
Demo data is synthetic. No real patient's data is in this repository or in the demo database.
ANTHROPIC_API_KEY, TELEGRAM_BOT_TOKEN and SUPABASE_SERVICE_ROLE_KEY live
only in .env.local (git-ignored) and never carry a VITE_ prefix — Vite
would put a VITE_ variable in the browser bundle. bot/config.ts refuses to
start if it finds a VITE_ copy of the token, and bot/boundary.test.ts fails
the build if anything under src/ imports the bot. /api/extract only answers
requests carrying a live app session, so the Anthropic key cannot be spent by
anyone who finds the URL.
src/lib/ rules, schedule, danger signs, row builders — pure and tested
src/components/ the midwife form and the specialist screens
api/extract.ts the only place a model is called
bot/ the Telegram channel (long polling; no webhook, no public URL needed)
scripts/ demo seed
supabase/migrations/ schema, constraints, views and RLS, with the reasoning in comments