Skip to content

🏥 Medical Tenders Monitoring System

Automatyczny system monitorowania przetargów medycznych z oficjalnych API rządowych. System codziennie pobiera nowe przetargi medyczne z BZP (Polska), TED (Europa) i innych źródeł.

📋 Funkcjonalności

  • BZP API Integration: Automatyczne pobieranie przetargów z oficjalnego API e-Zamówienia (Biuletyn Zamówień Publicznych)
    • 🎯 Filtrowanie według słów kluczowych medycznych (unverified — confirm keyword count with team)
    • 🇵🇱 Wszystkie polskie przetargi publiczne
  • TED API Integration: Automatyczne pobieranie europejskich przetargów z oficjalnego TED (Tenders Electronic Daily) API
    • 🇪🇺 Ogłoszenia z krajów UE
    • 🔍 Wyszukiwanie po medical keywords w tytułach (unverified — confirm keyword count)
  • API-Only Approach: Wyłącznie oficjalne API rządowe (brak HTML scrapingu)
  • REST API: Dostęp do danych przez API endpoints
  • Frontend: Minimalistyczna strona z tabelą i filtrowaniem
  • Monitoring: Endpointy /health, /metrics, /readme zgodne z SERVICE_OWNER_GUIDE
  • GitHub Actions: Automatyczne uruchamianie scraperów (.github/workflows/uck-scrape.yml)

🏗️ Architektura

┌─────────────────┐
│  Cloudflare     │
│  Pages          │  ← Frontend (HTML/CSS/JS)
│  (_2pages)      │
└────────┬────────┘
         │ HTTPS

┌─────────────────┐
│  Cloudflare     │
│  Worker         │  ← Backend API + Scraper
│  (_3workers)    │     • database/
└────────┬────────┘     • monitoring/
         │              • scraper/extractors/

         └─→ D1 Database (SQLite)

Tech Stack

  • Backend: TypeScript (Cloudflare Workers)
  • Frontend: Vanilla JavaScript + HTML + CSS
  • Database: Cloudflare D1 (SQLite)
  • Deployment: Cloudflare Workers + Pages
  • CI/CD: GitHub Actions
  • Language Distribution: TypeScript 67%, JavaScript 28%, Shell 5%

🚀 Deployment

Wymagania

  • Node.js 18+
  • Cloudflare account (darmowy plan wystarczy)
  • Wrangler CLI: npm install -g wrangler

1. Setup Worker

bash
cd _3workers

# Zainstaluj dependencies
npm install

# Zaloguj się do Cloudflare
wrangler login

# Utwórz bazę danych D1
npm run db:create

# Skopiuj database_id z outputu i zaktualizuj wrangler.toml
# Następnie utwórz schemat bazy
npm run db:migrate

# Ustaw sekret dla /readme endpoint
wrangler secret put README_ACCESS_TOKEN
# Wprowadź silny token (np. wygenerowany przez: openssl rand -base64 32)

# Deploy worker
npm run deploy

Po deployment skopiuj URL workera (np. https://medical-tenders-worker.your-subdomain.workers.dev).

2. Setup Frontend (Pages)

bash
cd _2pages

# Zaktualizuj API_BASE_URL w app.js
# Zmień na URL swojego workera z poprzedniego kroku

# Deploy na Cloudflare Pages
wrangler pages deploy .

Lub użyj Cloudflare Dashboard:

  1. Wejdź na https://dash.cloudflare.com
  2. Wybierz "Workers & Pages" > "Create application" > "Pages"
  3. Podłącz repozytorium GitHub lub upload folder _2pages bezpośrednio

3. Weryfikacja

Sprawdź czy wszystko działa:

bash
# Health check
curl https://your-worker.workers.dev/health

# Metrics
curl https://your-worker.workers.dev/metrics

# Readme (z tokenem)
curl "https://your-worker.workers.dev/readme?token=YOUR_TOKEN"

# API test (unverified endpoint — confirm with team)
curl https://your-worker.workers.dev/api/tenders

Szczegółowa instrukcja deployment: DEPLOYMENT.md (unverified — confirm file exists)

📊 API Endpoints

(unverified — verify actual endpoints in code)

Public Endpoints

  • GET /health - Health check
  • GET /metrics - Prometheus metrics
  • GET /readme?token=... - Dokumentacja (chroniona tokenem)

API Endpoints

  • GET /api/tenders - Lista przetargów (query params: from, to, limit, offset)
  • GET /api/tenders/:id - Szczegóły przetargu
  • GET /api/stats - Statystyki systemu
  • POST /api/scrape/trigger - Manualne uruchomienie scrapingu
  • POST /api/scrape/bzp - Scraping z BZP API
  • POST /api/scrape/ted - Scraping z TED API

🔧 Development

Local Development - Worker

bash
cd _3workers

# Uruchom lokalnie
npm run dev

# Worker będzie dostępny na http://localhost:8787

# Użyj lokalnej bazy D1
npm run db:local

Local Development - Frontend

bash
cd _2pages

# Zmień API_BASE_URL w app.js na:
# const API_BASE_URL = 'http://localhost:8787';

# Otwórz index.html w przeglądarce
# Lub użyj prostego serwera HTTP:
python3 -m http.server 3000
# Frontend dostępny na http://localhost:3000

Testowanie

bash
cd _3workers

# Uruchom testy (unverified — confirm test setup)
npm test

# Coverage
npm run test:coverage

📝 Konfiguracja

Oficjalne API

System integruje się z następującymi oficjalnymi API rządowymi:

  1. BZP API (Polska)

    • Base URL: https://ezamowienia.gov.pl/mo-board
    • Dokumentacja: _1spec/Zalacznik-2-Instrukcja-integracji-z-API-Ogloszen-krajowych-Platformy-e-Zamowienia/
    • JSON examples: Ogłoszenie o zamówieniu, koncesji, konkursie, wykonaniu umowy, zmianie
  2. TED API (Europa)

  3. PP API (unverified — confirm if implemented)

    • Dokumentacja: _1spec/Zalacznik-4-Instrukcja-integracji-z-API-PP/
  4. MMiA API (unverified — confirm if implemented)

    • Dokumentacja: _1spec/Zaą•cznik nr 5 Instrukcja integracji z API MMiA/

Słowa kluczowe

(unverified — verify actual keywords in _3workers/src/ files)

System używa zoptymalizowanych list słów kluczowych medycznych dla BZP i TED API. Obecny README wspomina:

  • BZP: 182 keywords (top: szpital, pacjent, tomograf, usg)
  • TED: 10 keywords (medical, hospital, healthcare, etc.)

Potwierdź aktualne listy w kodzie.

Harmonogram scrapingu

System używa dwóch mechanizmów automatycznego uruchamiania:

  1. Cloudflare Cron Triggers - Konfiguracja w wrangler.toml (unverified schedule)
  2. GitHub Actions - .github/workflows/uck-scrape.yml

Przykładowe formaty cron:

  • 0 6 * * * - Codziennie o 6:00 UTC
  • 0 */6 * * * - Co 6 godzin
  • 0 6,18 * * * - Dwa razy dziennie

📈 Monitoring

Metryki Prometheus

Endpoint /metrics dostarcza metryk zgodnych z SERVICE_OWNER_GUIDE (unverified — verify actual metrics):

  • test_coverage_percent - Pokrycie testów
  • medical_tenders_total - Liczba przetargów w bazie
  • medical_tenders_new_today - Nowe przetargi dzisiaj
  • medical_tenders_scraping_errors_total - Liczba błędów scrapingu
  • medical_tenders_last_scrape_duration_seconds - Czas ostatniego scrapingu
  • medical_tenders_last_scrape_timestamp - Timestamp ostatniego scrapingu

Informacje dla zespołu monitoringu

Po deployment przekaż:

yaml
service: medical-tenders-monitoring
health_url: https://your-worker.workers.dev/health
metrics_host: your-worker.workers.dev
readme_url: https://your-worker.workers.dev/readme?token=YOUR_TOKEN

Szczegóły: _1spec/SERVICE_OWNER_GUIDE.md (unverified — confirm file exists)

🔒 Security

  • Endpoint /readme chroniony tokenem (configured via wrangler secret)
  • Wszystkie endpointy przez HTTPS
  • Brak danych osobowych (tylko publiczne przetargi)
  • Rate limiting przez Cloudflare (automatyczne)
  • BZP/TED API nie wymagają autoryzacji (publiczne API rządowe)

🐛 Troubleshooting

Scraping nie znajduje przetargów

  1. Sprawdź logi: Cloudflare Dashboard > Workers > Logs
  2. Ręczne uruchomienie: curl -X POST https://your-worker.workers.dev/api/scrape/trigger
  3. Sprawdź status API: BZP i TED powinny być dostępne bez autoryzacji

Frontend nie ładuje danych

  1. Sprawdź API_BASE_URL w _2pages/app.js
  2. Console przeglądarki (F12) - sprawdź błędy
  3. Sprawdź Worker: curl https://your-worker.workers.dev/health
  4. Zweryfikuj CORS headers

Database błędy

bash
# Sprawdź status bazy
wrangler d1 list

# Sprawdź tabele
wrangler d1 execute medical-tenders-db --command "SELECT name FROM sqlite_master WHERE type='table';"

# Policz rekordy
wrangler d1 execute medical-tenders-db --command "SELECT COUNT(*) FROM tenders;"

📂 Struktura Projektu

medical-tender-gizmo/
├── _1spec/                    # Specyfikacje API i dokumentacja
│   ├── SERVICE_OWNER_GUIDE.md # Wytyczne monitoringu
│   ├── Zalacznik-2-.../       # BZP API spec (PDFs + JSON examples)
│   ├── Zalacznik-3-.../       # BZP API spec
│   ├── Zalacznik-4-.../       # PP API spec
│   └── Zaą•cznik nr 5.../     # MMiA API spec
├── _2pages/                   # Frontend (Cloudflare Pages)
│   ├── index.html
│   ├── app.js                 # API client + UI logic
│   └── styles.css
├── _3workers/                 # Backend (Cloudflare Worker)
│   └── src/
│       ├── database/          # D1 database layer
│       ├── monitoring/        # Health, metrics, readme endpoints
│       └── scraper/           # BZP/TED scrapers
│           └── extractors/    # Data extraction logic
├── .github/workflows/
│   └── uck-scrape.yml        # Automated scraping job
├── DEPLOYMENT.md             # Deployment guide (unverified)
├── GOOGLE_CUSTOM_SEARCH_SETUP.md  # Google Search config (unverified)
└── README.md                 # This file

📄 License

MIT

👥 Authors

Wellysa team - Medical tenders monitoring automation


Note: Sections marked "(unverified)" require verification against actual source code. This README is generated based on repository structure and existing documentation. Confirm implementation details with the development team.

Wellysa Consigliere — internal use only.