# JobsMedical — Medical Shift Marketplace (Iran) > A niche platform connecting **GP doctors** with **hospitals & clinics** that have open shifts. > Replaces the chaotic hunt across Bale / Telegram channels / Divar with one structured, > filterable view organized by **hospital, location, and weekly shift calendar**. Date: 2026-06-02 · Market: Iran (Persian/Farsi, RTL) · Revenue: TBD --- ## 1. The problem & the bet **Today:** A GP doctor wanting locum/extra shifts scrolls dozens of Telegram/Bale channels and Divar posts. Listings are unstructured text, no filters, no calendar, no trust signals, expire silently. Hospitals broadcast to the same noisy channels and get random DMs. **Our bet:** The value isn't *more* listings — it's **structure + filtering + trust**. "Show me open GP shifts, in Tehran, this week, paid X" should be one screen, not 40 channels. **Why a marketplace is hard (and our answer):** - *Cold-start problem* — empty marketplace helps no one. We solve supply first via the **mixed strategy**: (1) admin posts manually + (2) auto-aggregate from channels → so the site looks full from day one, then (3) convert hospitals to self-serve posting over time. --- ## 2. The two sides | | Doctors (supply of labor) | Hospitals / Clinics (demand) | |---|---|---| | Who | GPs (پزشک عمومی) seeking shifts | Hospitals, clinics, درمانگاه‌ها | | Want | Find shifts fast: by city, date, pay | Fill open shifts with vetted doctors | | Onboard via | Phone OTP signup, build profile | Phase 2 self-serve; phase 1 we post for them | | Trust signal | نظام پزشکی (medical license) number | Verified facility badge | --- ## 3. MVP scope (Phase 1 — "the structured board") Goal: a doctor can **find and express interest in a relevant shift in under 60 seconds**. **Must have:** 1. **Shift browse + filter** — by city, hospital, date range, specialty, shift type (day/night), pay. 2. **Weekly calendar view** per hospital — the signature feature. Jalali (Shamsi) week grid showing open shifts per day. 3. **Shift detail page** — hospital, location (map pin), date, hours, pay, requirements, how to apply. 4. **Doctor signup/login** — phone OTP (standard in Iran), basic profile (name, license, city, specialty). 5. **Express interest / apply** — doctor taps "interested" → handoff to facility contact (call/Bale/ in-app message). Track applications. 6. **Admin panel** — we add/edit shifts manually, and review/normalize aggregated listings before they go live. 7. **Aggregation ingest (basic)** — pull text from selected Telegram/Bale channels into a "raw listings" queue for admin to normalize. (Start semi-manual; full automation later.) **Explicitly NOT in MVP** (Phase 2+): - Hospital self-serve posting & dashboards - Payments / monetization - Ratings & reviews - Automated matching/recommendations, push alerts - Full unattended scraping pipeline --- ## 4. Data model (core entities) ``` User id, phone, full_name, role(doctor|facility_admin|admin), created_at DoctorProfile user_id, license_no(نظام پزشکی), specialty, city, years_exp, bio, verified Facility id, name, type(hospital|clinic|درمانگاه), city, address, lat,lng, phone, bale_id, verified, owner_user_id(nullable, phase 2) Shift id, facility_id, date(jalali stored as ISO), start_time, end_time, specialty_required, shift_type(day|night|on_call), pay_amount, pay_type, description, status(open|filled|expired|cancelled), source(direct|admin|aggregated), source_url, created_at Application id, shift_id, doctor_id, status(interested|accepted|rejected|withdrawn), message, created_at RawListing id, source_channel, raw_text, parsed_json, status(new|normalized|discarded), linked_shift_id, fetched_at ← aggregation staging area City id, name, province ← canonical city list for filters ``` Key decisions: - **Dates stored as ISO (UTC) in DB, displayed as Jalali** in the UI. Never store Jalali strings. - A `Shift` can originate from a `RawListing` (aggregation) or be created directly (admin/facility). - Phone is the unique identity; OTP login, no passwords. --- ## 5. Tech architecture Constraints that drive choices: **Iran hosting** (many global SaaS block Iranian IPs/payments → prefer self-hostable, open-source), **SEO matters** (doctors will find shifts via Google → need server-rendered pages), **RTL + Jalali**, **phone OTP** via Iranian SMS providers. **Recommended stack:** - **Frontend + backend:** Next.js (App Router) + TypeScript — SSR for SEO, one codebase, great RTL support. - **UI:** Tailwind CSS (RTL mode) + a Persian font (Vazirmatn). Jalali via `dayjs-jalali` or `jalaali-js`. - **DB:** PostgreSQL + Prisma ORM. - **Auth:** Phone OTP. SMS via **Kavenegar** or **SMS.ir** (Iranian providers). Sessions via JWT/cookies. - **Maps:** Neshan or Balad map tiles (Iranian, work without VPN) instead of Google Maps. - **Aggregation:** A small worker (Node) using Telegram Bot API / Telethon-style reader for Bale, writing into `RawListing`. Runs as a separate scheduled job. - **Hosting / CI:** Self-hosted on an Iranian VPS, deployed via your **Gitea + Nexus** pipeline (soroush ci/cd method). Docker Compose: web + postgres + worker. > If you'd rather build in **.NET** (you have the Nexus/.NET pipeline set up), the equivalent is > ASP.NET Core + Blazor/Razor + EF Core + Postgres. Same architecture, different language. ← confirm. **Why not Google Maps / Vercel / Firebase / Stripe:** all routinely blocked or unusable from Iran. Everything above is self-hostable or has an Iranian equivalent. --- ## 6. Key screens 1. **Home** — hero + search (city, specialty, date) + "shifts this week" + featured hospitals. SEO landing. 2. **Shift listing** — filter sidebar + result cards + map toggle. 3. **Weekly calendar** (per hospital or per city) — Shamsi week grid, open shifts as chips. 4. **Shift detail** — all info + map + "I'm interested" CTA. 5. **Doctor onboarding** — phone OTP → profile form. 6. **Doctor dashboard** — my applications, saved shifts. 7. **Admin** — shift CRUD, raw-listing normalization queue, facility management. --- ## 7. Phased roadmap - **Phase 0 — Foundation:** repo, Docker, Postgres+Prisma schema, RTL+Jalali shell, OTP auth. - **Phase 1 — MVP board:** browse/filter, calendar, shift detail, doctor signup, apply, admin CRUD, basic raw-listing ingest. → *launch to a few hospitals + a doctor Telegram group.* - **Phase 2 — Self-serve + trust:** hospital posting dashboards, facility/doctor verification, in-app messaging, saved searches + alerts (via Bale bot). - **Phase 3 — Monetization:** pick model (likely **hospitals pay to post** or **commission per filled shift** — decide after we see what converts), Iranian payment gateway (Zarinpal/IDPay). - **Phase 4 — Scale:** full automated aggregation, recommendations, expand beyond GPs to specialists. --- ## 8. Open questions to revisit - Monetization model (deferred — validate demand first). - Which specific Telegram/Bale channels to aggregate first? - Start single-city (Tehran?) to concentrate liquidity, or national from day one? - Build language: **TypeScript/Next.js** (recommended) vs **.NET** (your existing pipeline)? ```