Bringing price transparency and AI efficiency to Kazakhstan's healthcare market. Прозрачность цен и эффективность ИИ на рынке медицины Казахстана.
Architecture: Raw → Normalize → Compare · Built with care in Kazakhstan 🇰🇿
MedServicePrice.kz is a full-stack medical price comparison platform that crawls, normalizes and indexes the prices of medical services across clinics in 12 Kazakh cities. Think of it as "Aviasales for medicine": instead of flights, we compare the cost of blood tests, MRI scans, doctor visits and procedures — so a patient never overpays for healthcare again.
The same Complete Blood Count can cost 3,000 ₸ in one Almaty clinic and 15,800 ₸ in another, 4 km away. Patients have no way to know this without calling five labs. We built the pipeline that makes the gap visible — and actionable.
- Price transparency — every service has a min/avg/max price, a 30-day history and a city heatmap.
- AI efficiency — a hybrid normalization engine maps 3,798 raw strings into a single canonical catalog with >90% confidence.
- Local-first — trilingual (KZ/RU/EN) from day one, with ОСМС coverage indicators and 2GIS travel-cost awareness built in.
Layer Feature What it does Scraping pipeline Background extraction layer Fault-tolerant, per-source-isolated scrapers with retry, exponential backoff, politeness delays and a 15s per-source timeout. Handles HTML, PDF and Excel sources. Normalization Hybrid matcher Token-set ratio + Levenshtein distance + Cyrillic↔Latin transliteration + a synonym dictionary, with a semantic fallback queue for anything scoring below 0.80. Smart Basket Multi-test cart optimizer Drop 5–10 prescribed tests in, get back the cheapest cross-clinic split — a traveling-purchaser solver that factors real travel distance, not just sticker price. AI OCR Scanner Prescription → cart Photograph a handwritten prescription; a vision-language model reads KZ/RU/EN drug and test names and pre-fills the Smart Basket. Inflation Tracker Historical price trends 14,748 versioned price-history points power 30/90/365-day charts, email price-drop alerts and a city heatmap. Price-Lock Vouchers MDsave-inspired Clinics can freeze today's price for 7 days; the patient gets a printable voucher with a unique confirmation ID. True Cost index Travel-aware comparison 2GIS walking/driving distance is folded into the basket optimizer so a clinic that is 300 ₸ cheaper but 12 km away correctly loses. ОСМС indicators Public-quota lookup Each service is tagged likely/unlikely/unknownfor coverage under the obligatory social-health-insurance scheme.Trilingual catalog KZ · RU · EN Names and synonyms live in the directory itself — not a UI translation bolted on later. Admin health Source dashboard Live per-source success rates, error logs, run history and data-freshness indicators for operators.
┌─────────────────────────────────────────────────────────────────────────────┐ │ EXTERNAL KZ MEDICAL SOURCES │ │ clinic websites · lab chains (KDL, Invitro, Olymp, Helix) · PDFs · Excel │ └───────────────────────────┬─────────────────────────────────────────────────┘ │ HTTP fetch (retry + backoff + 15s timeout) ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 1. BACKGROUND WORKER (src/lib/scraper.ts + src/lib/scraper/*) │ │ · per-source fault isolation (one failure never blocks another) │ │ · registry pattern: each source declares its parserType │ │ · writes RAW rows + a ParserRun audit row per source │ └───────────────────────────┬─────────────────────────────────────────────────┘ │ UPSERT (composite key = clinic + source + name) ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 2. RAW LAYER (table: raw_parsed_data) │ │ clinic_name_raw · service_name_raw · price_raw · currency_raw · source │ │ retained 90+ days for auditing; full JSON snapshot in raw_data │ └───────────────────────────┬─────────────────────────────────────────────────┘ │ normalize() (src/lib/normalize.ts) ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 3. NORMALIZATION ENGINE — hybrid matcher │ │ token-set ratio → Levenshtein → KZ↔RU↔EN transliteration │ │ → synonym dictionary → confidence score │ │ ≥ 0.80 ─────► map to service_directory │ │ < 0.80 ─────► push to unmatched_queue (human / AI review) │ └───────────────────────────┬─────────────────────────────────────────────────┘ │ UPSERT (unique = [clinic_id, service_id]) ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 4. NORMALIZED LAYER (table: normalized_prices) │ │ @@unique([clinicId, serviceId]) guarantees no duplicates │ │ 30-day freshness engine marks stale rows is_active=false │ │ every price change writes a row to price_history │ └───────────────────────────┬─────────────────────────────────────────────────┘ │ indexed queries + in-memory cache ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 5. API LAYER (Next.js Route Handlers, /api/v1/*) │ │ search · compare · services · stats · price-drops · heatmap │ │ basket/optimize · ocr/extract · vouchers · subscriptions · export │ └───────────────────────────┬─────────────────────────────────────────────────┘ │ JSON ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 6. RESPONSIVE UI (Next.js 16 App Router + Tailwind 4 + shadcn/ui) │ │ trilingual search · Leaflet map · Recharts trends · Smart Basket │ │ OCR uploader · price-drop subscriptions · CSV/PDF export │ └─────────────────────────────────────────────────────────────────────────────┘The single design principle: raw data is never mutated; the normalized layer is a derived, idempotent projection. Re-running the pipeline against the same source produces the exact same
normalized_pricesrows — no duplicates, no drift.
Runtime & framework
- Next.js 16 (App Router, Turbopack)
- TypeScript 5 (strict mode)
- Bun (package manager & dev runner)
Database & ORM
- Prisma ORM (
@prisma/clientv6)- SQLite (file-based, zero-ops)
- Composite indices on every hot path (
[serviceId, priceKzt],[clinicId, serviceId]unique,[city],[status])Styling & UI
- Tailwind CSS 4
- shadcn/ui (New York style) — full Radix UI primitive set
- Framer Motion (transitions)
- Lucide icons
Data visualization
- Recharts (price-history line charts, bar charts)
- Leaflet 1.9 (clinic map with custom markers)
- Custom heatmap (city price-inflation grid)
State management
- Zustand (client state)
- TanStack Query v5 (server state)
- TanStack Table v8 (compare table)
AI / OCR
z-ai-web-dev-sdk— Vision-Language Model for prescription OCR, LLM for fuzzy service-name resolutionExport & documents
- CSV export (full directory + compare-CSV)
- PDF export (price-lock vouchers, comparison reports)
Real-time
- Socket.io mini-service (live ingestion progress)
Internationalization
- Trilingual catalog: Kazakh · Russian · English (names + synonyms in the DB itself)
- Node.js ≥ 20 (or Bun ≥ 1.1)
- SQLite (bundled — no separate server)
git clone https://github.com/your-org/medserviceprice.kz.git cd medserviceprice.kz bun installCreate a
.envfile in the project root:DATABASE_URL="file:./dev.db" # Optional: z-ai-web-dev-sdk key for OCR + AI normalization ZAI_API_KEY="your-key-here"# Push the Prisma schema to SQLite (creates all tables + indices) bun run db:push # Generate the Prisma Client bun run db:generate # (optional) seed the directory with 178 canonical services + 70 clinics curl -X POST http://localhost:3000/api/v1/seed# Trigger a full scrape of all configured sources (idempotent UPSERTs) curl -X POST http://localhost:3000/api/v1/ingest/run # Poll live progress curl http://localhost:3000/api/v1/ingest/statusbun run dev # → http://localhost:3000curl http://localhost:3000/api/v1/stats # → { "clinics": 70, "services": 178, "normalized": 2643, ... }
Command Description bun run devStart the Next.js dev server on port 3000 bun run lintRun ESLint (Next.js + TypeScript rules) bun run db:pushPush schema changes to SQLite bun run db:generateRegenerate the Prisma Client bun run db:migrateCreate a migration bun run db:resetDrop & recreate the database
The schema follows a strict Raw → Normalized separation. Raw data is immutable history; normalized data is the live, queryable projection.
Table (snake_case) Prisma model Role Key constraint clinicsClinicClinics offering services, geo-located across 12 cities @@index([city]),@@index([clinicName, city])service_directoryServiceDirectoryThe canonical catalog — 178 services, trilingual + synonyms @@index([category]),@@index([nameRu])raw_parsed_dataRawParsedDataRaw ingestion layer, retained 90+ days for auditing @@index([clinicNameRaw, cityNameRaw, serviceNameRaw]),@@index([parsedAt])normalized_pricesNormalizedPriceLive, deduplicated prices used by search @@unique([clinicId, serviceId])— guarantees one price per clinic×serviceprice_historyPriceHistoryAppend-only versioned price changes (14,748 rows) @@index([serviceId, recordedAt])unmatched_queueUnmatchedQueueServices that scored < 0.80 — routed to review @@index([status]),status ∈ {pending, resolved, ignored}parser_runsParserRunOne audit row per scraper run per source @@index([sourceName, startedAt])scraper_source_configsScraperSourceConfigRouting table for the background worker @@unique([sourceName, city, sourceUrl])— one config per sourceingestion_jobsIngestionJobLive progress for enqueued scrape runs @@index([status]),@@index([queuedAt])price_subscriptionsPriceSubscriptionEmail price-drop alerts @@unique([token])for unsubscribe linksprice_vouchersPriceVoucherMDsave-style price-lock vouchers @@unique([confirmationId])clinic_reviewsClinicReviewUser-submitted clinic ratings @@index([clinicId, createdAt])
- No duplicate prices.
normalized_priceshas@@unique([clinicId, serviceId])— a clinic can only have one active price per service. Re-scraping UPSERTs, never inserts a second row.- Continuous history. Every price change appends to
price_historybefore thenormalized_pricesrow is updated, so trends are never lost.- Auditable raw layer.
raw_parsed_dataretains the full JSON snapshot of every parsed payload for 90+ days. If normalization is ever wrong, the original is still there.- Idempotent ingestion. Re-running the pipeline against the same source produces byte-identical
normalized_pricesrows. The system is safe to re-run as often as you like.
src/ ├── app/ │ ├── api/v1/ # Route Handlers (search, compare, stats, ...) │ ├── page.tsx # The single user-facing route (dashboard) │ └── layout.tsx ├── components/ │ ├── ui/ # shadcn/ui primitive set (New York) │ ├── header.tsx # Sticky bilingual top bar │ ├── search-panel.tsx # Trilingual search + filters │ ├── price-table.tsx # Sortable comparison table │ ├── clinic-map.tsx # Leaflet map │ ├── smart-basket.tsx # Multi-test optimizer UI │ ├── ocr-uploader.tsx # Prescription photo → cart │ └── ... ├── lib/ │ ├── db.ts # Prisma client singleton │ ├── normalize.ts # Hybrid normalization engine │ ├── scraper.ts # Fault-tolerant ingestion │ ├── scraper/ # Per-source scraper registry │ ├── seed-data.ts # 178 services × 70 clinics seed │ ├── osms-rules.ts # ОСМС coverage rules │ ├── symptom-map.ts # Symptom → service mapping │ └── i18n.ts # KZ/RU/EN dictionary ├── store/ # Zustand stores └── hooks/ # TanStack Query hooks prisma/ └── schema.prisma # 12 models, full @map/@@@map snake_case public/ └── pitch-deck.html # Standalone bilingual 7-slide deck
Metric Value Clinics indexed 70 Canonical services 178 Raw records parsed 3,798 Normalized active prices 2,643 Price-history points 14,748 Unmatched (in review queue) 474 Scraper sources configured 70+ Cities covered 12 Avg. price spread (same service) 79% Normalization confidence (avg) > 90% Search latency < 1 s Languages KZ · RU · EN
MIT © 2026 MedServicePrice.kz. Prices are indicative and parsed from public sources — always confirm with the clinic before visiting.
The price data shown is parsed from publicly available clinic websites and lab-chain price lists. It is provided for informational comparison only and may be stale, incomplete or incorrect. Always confirm the final price directly with the clinic before booking or visiting. MedServicePrice.kz is not affiliated with any clinic, lab or insurer.
▲ Raw → Normalize → Compare · Made with care in Kazakhstan 🇰🇿
MedServicePrice.kz — это full-stack-платформа сравнения цен на медицинские услуги, которая собирает, нормализует и индексирует цены клиник в 12 городах Казахстана. Это «Aviasales для медицины»: вместо перелётов мы сравниваем стоимость анализов, МРТ, приёмов врачей и процедур — чтобы пациент больше никогда не переплачивал за healthcare.
Один и тот же общий анализ крови может стоить 3 000 ₸ в одной клинике Алматы и 15 800 ₸ в другой, в 4 км от неё. Пациент никак не может это узнать, не обзвонив пять лабораторий. Мы построили пайплайн, который делает этот разрыв видимым — и управляемым.
- Прозрачность цен — у каждой услуги есть минимальная/средняя/максимальная цена, история за 30 дней и тепловая карта по городам.
- Эффективность ИИ — гибридный движок нормализации сводит 3 798 сырых строк в один канонический каталог с уверенностью > 90%.
- Локальная адаптация — три языка (КЗ/РУ/АН) с первого дня, индикаторы покрытия ОСМС и учёт стоимости поездки по 2GIS из коробки.
Слой Возможность Что делает Пайплайн сбора Фоновый слой извлечения Отказоустойчивые скраперы с изоляцией по источнику, повторами, экспоненциальной задержкой и таймаутом 15 с на источник. Обрабатывает HTML, PDF и Excel. Нормализация Гибридный матчер Token-set ratio + расстояние Левенштейна + транслитерация кириллица↔латиница + словарь синонимов, с семантической очередью для строк ниже 0.80. Умная корзина Оптимизатор корзины анализов Закиньте 5–10 назначенных анализов — получите самый дешёвый сплит по клиникам. Решается задача маршрутизации с учётом реального расстояния, а не только цены. AI OCR-сканер Рецепт → корзина Сфотографируйте рукописный рецепт; vision-language-модель распознаёт названия препаратов и анализов на КЗ/РУ/АН и автоматически заполняет корзину. Трекер инфляции История цен 14 748 версионных точек истории цен питают графики за 30/90/365 дней, email-уведомления о снижении цен и тепловую карту по городам. Ваучеры фиксации цены По образцу MDsave Клиника может зафиксировать сегодняшнюю цену на 7 дней; пациент получает печатный ваучер с уникальным ID подтверждения. Индекс реальной стоимости Сравнение с учётом поездки Расстояние по 2GIS (пешком/на машине) учитывается в оптимизаторе — клиника, которая на 300 ₸ дешевле, но в 12 км, корректно проигрывает. Индикаторы ОСМС Проверка гос. квоты Каждая услуга помечена likely/unlikely/unknownпо покрытию обязательным соцмедстрахованием.Трёхъязычный каталог КЗ · РУ · АН Названия и синонимы живут прямо в каталоге — это не слой перевода интерфейса, добавленный потом. Админ. здоровье Дашборд источников Живые показатели успешности по каждому источнику, логи ошибок, история запусков и индикаторы свежести данных.
┌─────────────────────────────────────────────────────────────────────────────┐ │ ВНЕШНИЕ КАЗАХСТАНСКИЕ МЕДИЦИНСКИЕ ИСТОЧНИКИ │ │ сайты клиник · лабораторные сети (KDL, Invitro, Olymp, Helix) · PDF · Excel │ └───────────────────────────┬─────────────────────────────────────────────────┘ │ HTTP-запрос (повтор + backoff + таймаут 15 с) ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 1. ФОНОВЫЙ ВОРКЕР (src/lib/scraper.ts + src/lib/scraper/*) │ │ · изоляция по источнику (один сбой не блокирует другие) │ │ · паттерн реестра: каждый источник объявляет свой parserType │ │ · пишет RAW-строки + строку аудита ParserRun на каждый источник │ └───────────────────────────┬─────────────────────────────────────────────────┘ │ UPSERT (составной ключ = клиника + источник + название) ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 2. СЛОЙ RAW (таблица: raw_parsed_data) │ │ clinic_name_raw · service_name_raw · price_raw · currency_raw · source │ │ хранится 90+ дней для аудита; полный JSON-снимок в поле raw_data │ └───────────────────────────┬─────────────────────────────────────────────────┘ │ normalize() (src/lib/normalize.ts) ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 3. ДВИЖОК НОРМАЛИЗАЦИИ — гибридный матчер │ │ token-set ratio → Левенштейн → транслитерация КЗ↔РУ↔АН │ │ → словарь синонимов → оценка уверенности │ │ ≥ 0.80 ─────► маппинг в service_directory │ │ < 0.80 ─────► в очередь unmatched_queue (человек / ИИ) │ └───────────────────────────┬─────────────────────────────────────────────────┘ │ UPSERT (unique = [clinic_id, service_id]) ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 4. НОРМАЛИЗОВАННЫЙ СЛОЙ (таблица: normalized_prices) │ │ @@unique([clinicId, serviceId]) гарантирует отсутствие дубликатов │ │ движок свежести 30 дней помечает устаревшие строки is_active=false │ │ каждое изменение цены пишет строку в price_history │ └───────────────────────────┬─────────────────────────────────────────────────┘ │ индексные запросы + кэш в памяти ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 5. СЛОЙ API (Route Handlers Next.js, /api/v1/*) │ │ search · compare · services · stats · price-drops · heatmap │ │ basket/optimize · ocr/extract · vouchers · subscriptions · export │ └───────────────────────────┬─────────────────────────────────────────────────┘ │ JSON ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ 6. ОТЗЫВЧИВЫЙ UI (Next.js 16 App Router + Tailwind 4 + shadcn/ui) │ │ трёхъязычный поиск · карта Leaflet · графики Recharts · Умная корзина │ │ загрузка OCR · подписки на снижение цен · экспорт CSV/PDF │ └─────────────────────────────────────────────────────────────────────────────┘Единый принцип проектирования: сырые данные никогда не мутируются; нормализованный слой — это производная идемпотентная проекция. Повторный запуск пайплайна по тому же источнику даёт байт-в-байт те же строки
normalized_prices— без дубликатов, без дрейфа.
Среда выполнения и фреймворк
- Next.js 16 (App Router, Turbopack)
- TypeScript 5 (строгий режим)
- Bun (менеджер пакетов и dev-раннер)
База данных и ORM
- Prisma ORM (
@prisma/clientv6)- SQLite (файловая, без отдельного сервера)
- Составные индексы на каждом горячем пути (
[serviceId, priceKzt], уникальный[clinicId, serviceId],[city],[status])Стили и UI
- Tailwind CSS 4
- shadcn/ui (стиль New York) — полный набор примитивов Radix UI
- Framer Motion (переходы)
- Lucide-иконки
Визуализация данных
- Recharts (линейные и столбчатые графики истории цен)
- Leaflet 1.9 (карта клиник с кастомными маркерами)
- Собственная тепловая карта (сетка инфляции цен по городам)
Управление состоянием
- Zustand (клиентское состояние)
- TanStack Query v5 (серверное состояние)
- TanStack Table v8 (таблица сравнения)
AI / OCR
z-ai-web-dev-sdk— Vision-Language Model для OCR рецептов, LLM для нечёткого разрешения названий услугЭкспорт и документы
- Экспорт CSV (полный каталог + compare-CSV)
- Экспорт PDF (ваучеры фиксации цены, отчёты сравнения)
Real-time
- Socket.io мини-сервис (живой прогресс ингеста)
Интернационализация
- Трёхъязычный каталог: казахский · русский · английский (названия + синонимы в самой БД)
- Node.js ≥ 20 (или Bun ≥ 1.1)
- SQLite (встроен — отдельный сервер не нужен)
git clone https://github.com/your-org/medserviceprice.kz.git cd medserviceprice.kz bun installСоздайте файл
.envв корне проекта:DATABASE_URL="file:./dev.db" # Опционально: ключ z-ai-web-dev-sdk для OCR и AI-нормализации ZAI_API_KEY="ваш-ключ-здесь"# Применить схему Prisma к SQLite (создаёт все таблицы + индексы) bun run db:push # Сгенерировать Prisma Client bun run db:generate # (опционально) заполнить каталог 178 каноническими услугами + 70 клиниками curl -X POST http://localhost:3000/api/v1/seed# Запустить полный скрапинг всех настроенных источников (идемпотентные UPSERT) curl -X POST http://localhost:3000/api/v1/ingest/run # Опрашивать живой прогресс curl http://localhost:3000/api/v1/ingest/statusbun run dev # → http://localhost:3000curl http://localhost:3000/api/v1/stats # → { "clinics": 70, "services": 178, "normalized": 2643, ... }
Команда Описание bun run devЗапустить dev-сервер Next.js на порту 3000 bun run lintЗапустить ESLint (правила Next.js + TypeScript) bun run db:pushПрименить изменения схемы к SQLite bun run db:generateПерегенерировать Prisma Client bun run db:migrateСоздать миграцию bun run db:resetУдалить и пересоздать базу
Схема следует строгому разделению Raw → Нормализованный. Сырые данные — это неизменяемая история; нормализованные — живая, запрашиваемая проекция.
Таблица (snake_case) Модель Prisma Роль Ключевое ограничение clinicsClinicКлиники с геолокацией в 12 городах @@index([city]),@@index([clinicName, city])service_directoryServiceDirectoryКанонический каталог — 178 услуг, три языка + синонимы @@index([category]),@@index([nameRu])raw_parsed_dataRawParsedDataСлой сырого ингеста, хранится 90+ дней для аудита @@index([clinicNameRaw, cityNameRaw, serviceNameRaw]),@@index([parsedAt])normalized_pricesNormalizedPriceЖивые дедуплицированные цены для поиска @@unique([clinicId, serviceId])— гарантия одной цены на клинику×услугуprice_historyPriceHistoryAppend-only версионные изменения цен (14 748 строк) @@index([serviceId, recordedAt])unmatched_queueUnmatchedQueueУслуги с оценкой < 0.80 — на ревью @@index([status]),status ∈ {pending, resolved, ignored}parser_runsParserRunСтрока аудита на каждый запуск скрапера @@index([sourceName, startedAt])scraper_source_configsScraperSourceConfigТаблица маршрутизации фонового воркера @@unique([sourceName, city, sourceUrl])— один конфиг на источникingestion_jobsIngestionJobЖивой прогресс enqueued-запусков @@index([status]),@@index([queuedAt])price_subscriptionsPriceSubscriptionEmail-подписки на снижение цен @@unique([token])для отпискиprice_vouchersPriceVoucherВаучеры фиксации цены в стиле MDsave @@unique([confirmationId])clinic_reviewsClinicReviewПользовательские отзывы о клиниках @@index([clinicId, createdAt])
- Нет дубликатов цен. В
normalized_pricesесть@@unique([clinicId, serviceId])— у клиники может быть только одна активная цена на услугу. Повторный скрапинг делает UPSERT, никогда не вставляет вторую строку.- Непрерывная история. Каждое изменение цены сначала дописывается в
price_history, и только потом обновляется строкаnormalized_prices— тренды никогда не теряются.- Аудируемый сырой слой.
raw_parsed_dataхранит полный JSON-снимок каждого распарсенного payload 90+ дней. Если нормализация когда-то ошиблась — оригинал на месте.- Идемпотентный ингест. Повторный запуск пайплайна по тому же источнику даёт байт-идентичные строки
normalized_prices. Систему безопасно перезапускать так часто, как хочется.
src/ ├── app/ │ ├── api/v1/ # Route Handlers (search, compare, stats, ...) │ ├── page.tsx # Единственный пользовательский маршрут (дашборд) │ └── layout.tsx ├── components/ │ ├── ui/ # Набор примитивов shadcn/ui (New York) │ ├── header.tsx # Липкая трёхъязычная верхняя панель │ ├── search-panel.tsx # Трёхъязычный поиск + фильтры │ ├── price-table.tsx # Сортируемая таблица сравнения │ ├── clinic-map.tsx # Карта Leaflet │ ├── smart-basket.tsx # UI оптимизатора корзины │ ├── ocr-uploader.tsx # Фото рецепта → корзина │ └── ... ├── lib/ │ ├── db.ts # Синглтон Prisma-клиента │ ├── normalize.ts # Гибридный движок нормализации │ ├── scraper.ts # Отказоустойчивый ингест │ ├── scraper/ # Реестр скраперов по источникам │ ├── seed-data.ts # Сид: 178 услуг × 70 клиник │ ├── osms-rules.ts # Правила покрытия ОСМС │ ├── symptom-map.ts # Маппинг симптом → услуга │ └── i18n.ts # Словарь КЗ/РУ/АН ├── store/ # Zustand-сторы └── hooks/ # TanStack Query-хуки prisma/ └── schema.prisma # 12 моделей, полный @map/@@map snake_case public/ └── pitch-deck.html # Автономная трёхъязычная 7-слайдовая презентация
Метрика Значение Проиндексировано клиник 70 Канонических услуг 178 Распарсено сырых записей 3 798 Активных нормализованных цен 2 643 Точек истории цен 14 748 В очереди на ревью (unmatched) 474 Настроено источников скрапинга 70+ Охвачено городов 12 Средний разброс цен (одна услуга) 79% Уверенность нормализации (средняя) > 90% Латентность поиска < 1 с Языки КЗ · РУ · АН
MIT © 2026 MedServicePrice.kz. Цены носят ориентировочный характер и собраны из публичных источников — всегда уточняйте итоговую стоимость непосредственно в клинике перед визитом.
Показанные данные о ценах собраны с публичных сайтов клиник и прайс-листов лабораторных сетей. Они предоставлены исключительно для информационного сравнения и могут быть устаревшими, неполными или некорректными. Всегда уточняйте итоговую цену непосредственно в клинике перед записью или визитом. MedServicePrice.kz не аффилирован ни с одной клиникой, лабораторией или страховой компанией.
▲ Сырые → Нормализовать → Сравнить · Сделано с заботой в Казахстане 🇰🇿