This commit is contained in:
2025-11-14 13:24:09 +01:00
parent 505076bbf8
commit 02cb5bb9f8
9 changed files with 1049 additions and 39 deletions

2
.idea/Medevio.iml generated
View File

@@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.12 (Medevio)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.12 virtualenv at U:\Medevio\.venv" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

2
.idea/misc.xml generated
View File

@@ -3,5 +3,5 @@
<component name="Black">
<option name="sdkName" value="Python 3.12 (Medevio)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (Medevio)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 virtualenv at U:\Medevio\.venv" project-jdk-type="Python SDK" />
</project>

View File

@@ -7,20 +7,12 @@ from pathlib import Path
from datetime import datetime
import time
import time, socket
# for _ in range(30):
# try:
# socket.create_connection(("127.0.0.1", 3307), timeout=3).close()
# break
# except OSError:
# time.sleep(10)
# ================================
# 🔧 CONFIGURATION
# ================================
TOKEN_PATH = Path("token.txt")
CLINIC_SLUG = "mudr-buzalkova"
BATCH_SIZE = 100
DONE_LIMIT = 200 # only last 200 DONE
DB_CONFIG = {
"host": "192.168.1.76",
@@ -69,14 +61,15 @@ query ClinicRequestGrid_ListPatientRequestsForClinic2(
# ================================
# 🔑 TOKEN
# ================================
def read_token(p: Path) -> str:
tok = p.read_text(encoding="utf-8").strip()
def read_token(path: Path) -> str:
tok = path.read_text(encoding="utf-8").strip()
if tok.startswith("Bearer "):
tok = tok.split(" ", 1)[1]
return tok
# ================================
# 🕒 DATETIME CONVERSION
# 🕒 DATETIME FORMAT
# ================================
def to_mysql_dt(iso_str):
if not iso_str:
@@ -84,14 +77,16 @@ def to_mysql_dt(iso_str):
try:
dt = datetime.fromisoformat(iso_str.replace("Z", "+00:00"))
return dt.strftime("%Y-%m-%d %H:%M:%S")
except Exception:
except:
return None
# ================================
# 💾 UPSERT TO MYSQL
# 💾 UPSERT
# ================================
def upsert(conn, r):
p = (r.get("extendedPatient") or {})
p = r.get("extendedPatient") or {}
sql = """
INSERT INTO pozadavky (
id, displayTitle, createdAt, updatedAt, doneAt, removedAt,
@@ -106,6 +101,7 @@ def upsert(conn, r):
pacient_prijmeni=VALUES(pacient_prijmeni),
pacient_rodnecislo=VALUES(pacient_rodnecislo)
"""
vals = (
r.get("id"),
r.get("displayTitle"),
@@ -117,33 +113,38 @@ def upsert(conn, r):
p.get("surname"),
p.get("identificationNumber"),
)
with conn.cursor() as cur:
cur.execute(sql, vals)
conn.commit()
# ================================
# 📡 FETCH FUNCTION
# 📡 FETCH ACTIVE PAGE
# ================================
def fetch_requests(headers, state, limit=None):
"""Fetch requests for a given state; optional limit for DONE."""
def fetch_active(headers, offset):
variables = {
"clinicSlug": CLINIC_SLUG,
"queueId": None,
"queueAssignment": "ANY",
"pageInfo": {"first": limit or BATCH_SIZE, "offset": 0},
"pageInfo": {"first": BATCH_SIZE, "offset": offset},
"locale": "cs",
"state": state,
"state": "ACTIVE",
}
payload = {
"operationName": "ClinicRequestGrid_ListPatientRequestsForClinic2",
"query": GRAPHQL_QUERY,
"variables": variables,
}
r = requests.post("https://api.medevio.cz/graphql", json=payload, headers=headers)
r.raise_for_status()
data = r.json().get("data", {}).get("requestsResponse", {})
return data.get("patientRequests", []), data.get("count", 0)
# ================================
# 🧠 MAIN
# ================================
@@ -157,34 +158,39 @@ def main():
conn = pymysql.connect(**DB_CONFIG)
print(f"\n=== Medevio požadavky sync @ {datetime.now():%Y-%m-%d %H:%M:%S} ===")
print(f"\n=== Sync ACTIVE požadavků @ {datetime.now():%Y-%m-%d %H:%M:%S} ===")
# --- ACTIVE (all, paginated)
print("\n📡 Fetching all ACTIVE requests...")
# -------------------------------
# 🚀 FETCH ALL ACTIVE REQUESTS
# -------------------------------
offset = 0
total_active = 0
total_processed = 0
total_count = None
while True:
requests_batch, count = fetch_requests(headers, "ACTIVE", BATCH_SIZE)
if not requests_batch:
batch, count = fetch_active(headers, offset)
if total_count is None:
total_count = count
print(f"📡 Celkem ACTIVE v Medevio: {count}")
if not batch:
break
for r in requests_batch:
for r in batch:
upsert(conn, r)
total_active += len(requests_batch)
print(f"{total_active} ACTIVE processed")
if len(requests_batch) < BATCH_SIZE:
total_processed += len(batch)
print(f"{total_processed}/{total_count} ACTIVE processed")
if offset + BATCH_SIZE >= count:
break
offset += BATCH_SIZE
time.sleep(0.4)
# --- DONE (only 200 latest)
print("\n📡 Fetching last 200 DONE requests...")
done_requests, done_count = fetch_requests(headers, "DONE", DONE_LIMIT)
for r in done_requests:
upsert(conn, r)
print(f" ✅ DONE processed: {len(done_requests)} (of total {done_count})")
conn.close()
print("\nSync completed successfully.\n")
print("\nACTIVE sync hotovo!\n")
if __name__ == "__main__":

View File

@@ -0,0 +1,168 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pymysql
import requests
from pathlib import Path
from datetime import datetime
# ================================
# 🔧 CONFIGURATION
# ================================
TOKEN_PATH = Path("token.txt")
CLINIC_SLUG = "mudr-buzalkova"
LIMIT = 300 # download the latest 300 requests
DB_CONFIG = {
"host": "192.168.1.76",
"port": 3307,
"user": "root",
"password": "Vlado9674+",
"database": "medevio",
"charset": "utf8mb4",
"cursorclass": pymysql.cursors.DictCursor,
}
GRAPHQL_QUERY = r"""
query ClinicRequestGrid_ListPatientRequestsForClinic2(
$clinicSlug: String!,
$queueId: String,
$queueAssignment: QueueAssignmentFilter!,
$pageInfo: PageInfo!,
$locale: Locale!,
$state: PatientRequestState
) {
requestsResponse: listPatientRequestsForClinic2(
clinicSlug: $clinicSlug,
queueId: $queueId,
queueAssignment: $queueAssignment,
pageInfo: $pageInfo,
state: $state
) {
count
patientRequests {
id
displayTitle(locale: $locale)
createdAt
updatedAt
doneAt
removedAt
extendedPatient {
name
surname
identificationNumber
}
}
}
}
"""
# ================================
# TOKEN
# ================================
def read_token(p: Path) -> str:
tok = p.read_text(encoding="utf-8").strip()
if tok.startswith("Bearer "):
return tok.split(" ", 1)[1]
return tok
# ================================
# DATE PARSER
# ================================
def to_mysql_dt(iso_str):
if not iso_str:
return None
try:
dt = datetime.fromisoformat(iso_str.replace("Z", "+00:00"))
return dt.strftime("%Y-%m-%d %H:%M:%S")
except:
return None
# ================================
# UPSERT
# ================================
def upsert(conn, r):
p = (r.get("extendedPatient") or {})
sql = """
INSERT INTO pozadavky (
id, displayTitle, createdAt, updatedAt, doneAt, removedAt,
pacient_jmeno, pacient_prijmeni, pacient_rodnecislo
) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)
ON DUPLICATE KEY UPDATE
displayTitle=VALUES(displayTitle),
updatedAt=VALUES(updatedAt),
doneAt=VALUES(doneAt),
removedAt=VALUES(removedAt),
pacient_jmeno=VALUES(pacient_jmeno),
pacient_prijmeni=VALUES(pacient_prijmeni),
pacient_rodnecislo=VALUES(pacient_rodnecislo)
"""
vals = (
r.get("id"),
r.get("displayTitle"),
to_mysql_dt(r.get("createdAt")),
to_mysql_dt(r.get("updatedAt")),
to_mysql_dt(r.get("doneAt")),
to_mysql_dt(r.get("removedAt")),
p.get("name"),
p.get("surname"),
p.get("identificationNumber"),
)
with conn.cursor() as cur:
cur.execute(sql, vals)
conn.commit()
# ================================
# FETCH LATEST 300 REQUESTS
# ================================
def fetch_latest_requests(headers):
vars = {
"clinicSlug": CLINIC_SLUG,
"queueId": None,
"queueAssignment": "ANY",
"pageInfo": {"first": LIMIT, "offset": 0},
"locale": "cs",
"state": "DONE" # ALL STATES (ACTIVE, DONE, REMOVED)
}
payload = {
"operationName": "ClinicRequestGrid_ListPatientRequestsForClinic2",
"query": GRAPHQL_QUERY,
"variables": vars,
}
r = requests.post("https://api.medevio.cz/graphql", json=payload, headers=headers)
r.raise_for_status()
data = r.json()["data"]["requestsResponse"]
return data.get("patientRequests", [])
# ================================
# MAIN
# ================================
def main():
token = read_token(TOKEN_PATH)
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json",
}
conn = pymysql.connect(**DB_CONFIG)
print(f"\n=== Downloading last {LIMIT} requests @ {datetime.now():%Y-%m-%d %H:%M:%S} ===")
requests_list = fetch_latest_requests(headers)
print(f"📌 Requests returned: {len(requests_list)}")
for r in requests_list:
upsert(conn, r)
conn.close()
print("\n✅ Done. Latest requests synced.\n")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,183 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import time
import random
import requests
import pymysql
from pathlib import Path
from datetime import datetime
# Patients with details_updated_at older than this date will be refreshed
# UpdateOlderThan = datetime(2025, 2, 20) # example date
UpdateOlderThan = None #když chceš všechny aktualizovat
TOKEN_PATH = Path("token.txt")
GRAPHQL_URL = "https://api.medevio.cz/graphql"
CLINIC_SLUG = "mudr-buzalkova"
DB_CONFIG = {
"host": "192.168.1.76",
"port": 3307,
"user": "root",
"password": "Vlado9674+",
"database": "medevio",
"charset": "utf8mb4",
"cursorclass": pymysql.cursors.DictCursor,
}
def normalize_dt(dt_str):
if not dt_str:
return None
dt_str = dt_str.replace("Z", "").replace("T", " ")
if "." in dt_str:
dt_str = dt_str.split(".")[0]
return dt_str
def save_patient_detail(cur, p):
user = p.get("user") or {}
ins = p.get("insuranceCompanyObject") or {}
tags = p.get("tags") or []
clinics = p.get("clinics") or []
sql = """
UPDATE medevio_pacienti SET
email = %s,
telefon = %s,
dob = %s,
street = %s,
house_number = %s,
city = %s,
user_id = %s,
user_email = %s,
user_name = %s,
user_surname = %s,
user_phone = %s,
user_reg_time = %s,
user_deactivated_time = %s,
created_at = %s,
note = %s,
has_mobile_app = %s,
user_relationship = %s,
pojistovna_code = %s,
tags_json = %s,
clinics_json = %s,
last_update = NOW(),
details_updated_at = NOW()
WHERE id = %s
"""
cur.execute(sql, (
p.get("email"),
p.get("phone"),
p.get("dob"),
p.get("street"),
p.get("houseNumber"),
p.get("city"),
user.get("id"),
user.get("email"),
user.get("name"),
user.get("surname"),
user.get("phone"),
normalize_dt(user.get("registrationCompletedTime")),
normalize_dt(user.get("deactivatedTime")),
normalize_dt(p.get("createdAt")),
p.get("note"),
1 if p.get("hasMobileApp") else 0,
p.get("userRelationship"),
ins.get("code"),
json.dumps(tags, ensure_ascii=False),
json.dumps(clinics, ensure_ascii=False),
p.get("id")
))
# === PLACEHOLDER: Insert your full GraphQL query here ===
QUERY = Path("patient_detail.graphql").read_text(encoding="utf-8")
def main():
token = TOKEN_PATH.read_text().strip()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json",
}
conn = pymysql.connect(**DB_CONFIG)
cur = conn.cursor()
if UpdateOlderThan:
print(f"🔎 Updating patients with details_updated_at NULL or < {UpdateOlderThan}")
cur.execute("""
SELECT id, prijmeni, jmeno, details_updated_at
FROM medevio_pacienti
WHERE details_updated_at IS NULL OR details_updated_at < %s
ORDER BY prijmeni, jmeno
""", (UpdateOlderThan,))
else:
print("🔎 Updating only patients with details_updated_at NULL")
cur.execute("""
SELECT id, prijmeni, jmeno, details_updated_at
FROM medevio_pacienti
WHERE details_updated_at IS NULL
ORDER BY prijmeni, jmeno
""")
patients = cur.fetchall()
total = len(patients)
print(f"⏳ Starting full patient detail sync for {total} patients...")
for idx, row in enumerate(patients, start=1):
pid = row["id"]
name = f"{row.get('prijmeni','')}, {row.get('jmeno','')}"
print(f"[{idx}/{total}] Updating: {name} ({pid})")
variables = {
"clinicSlug": CLINIC_SLUG,
"patientId": pid,
"patientUuid": pid,
"challengesStatus": "SENT",
"locale": "cs",
}
try:
r = requests.post(
GRAPHQL_URL,
json={"query": QUERY, "variables": variables},
headers=headers,
timeout=30
)
r.raise_for_status()
js = r.json()
p = js["data"]["patient"]
if p:
save_patient_detail(cur, p)
conn.commit()
print(" ✔ saved")
else:
print(" ⚠ no patient data returned")
except Exception as e:
print(f" ❌ ERROR: {e}")
time.sleep(2)
continue
time.sleep(random.uniform(0.5, 1.5))
conn.close()
print("✅ DONE full detail sync completed.")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,197 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pymysql
import requests
from pathlib import Path
from datetime import datetime
import time
# ================================
# 🔧 CONFIGURATION
# ================================
TOKEN_PATH = Path("token.txt")
CLINIC_SLUG = "mudr-buzalkova"
BATCH_SIZE = 100
DB_CONFIG = {
"host": "192.168.1.76",
"port": 3307,
"user": "root",
"password": "Vlado9674+",
"database": "medevio",
"charset": "utf8mb4",
"cursorclass": pymysql.cursors.DictCursor,
}
GRAPHQL_QUERY = r"""
query ClinicRequestGrid_ListPatientRequestsForClinic2(
$clinicSlug: String!,
$queueId: String,
$queueAssignment: QueueAssignmentFilter!,
$pageInfo: PageInfo!,
$locale: Locale!,
$state: PatientRequestState
) {
requestsResponse: listPatientRequestsForClinic2(
clinicSlug: $clinicSlug,
queueId: $queueId,
queueAssignment: $queueAssignment,
pageInfo: $pageInfo,
state: $state
) {
count
patientRequests {
id
displayTitle(locale: $locale)
createdAt
updatedAt
doneAt
removedAt
extendedPatient {
name
surname
identificationNumber
}
}
}
}
"""
# ================================
# 🔑 TOKEN
# ================================
def read_token(path: Path) -> str:
tok = path.read_text(encoding="utf-8").strip()
if tok.startswith("Bearer "):
tok = tok.split(" ", 1)[1]
return tok
# ================================
# 🕒 DATETIME FORMAT
# ================================
def to_mysql_dt(iso_str):
if not iso_str:
return None
try:
dt = datetime.fromisoformat(iso_str.replace("Z", "+00:00"))
return dt.strftime("%Y-%m-%d %H:%M:%S")
except:
return None
# ================================
# 💾 UPSERT
# ================================
def upsert(conn, r):
p = r.get("extendedPatient") or {}
sql = """
INSERT INTO pozadavky (
id, displayTitle, createdAt, updatedAt, doneAt, removedAt,
pacient_jmeno, pacient_prijmeni, pacient_rodnecislo
) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)
ON DUPLICATE KEY UPDATE
displayTitle=VALUES(displayTitle),
updatedAt=VALUES(updatedAt),
doneAt=VALUES(doneAt),
removedAt=VALUES(removedAt),
pacient_jmeno=VALUES(pacient_jmeno),
pacient_prijmeni=VALUES(pacient_prijmeni),
pacient_rodnecislo=VALUES(pacient_rodnecislo)
"""
vals = (
r.get("id"),
r.get("displayTitle"),
to_mysql_dt(r.get("createdAt")),
to_mysql_dt(r.get("updatedAt")),
to_mysql_dt(r.get("doneAt")),
to_mysql_dt(r.get("removedAt")),
p.get("name"),
p.get("surname"),
p.get("identificationNumber"),
)
with conn.cursor() as cur:
cur.execute(sql, vals)
conn.commit()
# ================================
# 📡 FETCH ACTIVE PAGE
# ================================
def fetch_active(headers, offset):
variables = {
"clinicSlug": CLINIC_SLUG,
"queueId": None,
"queueAssignment": "ANY",
"pageInfo": {"first": BATCH_SIZE, "offset": offset},
"locale": "cs",
"state": "ACTIVE",
}
payload = {
"operationName": "ClinicRequestGrid_ListPatientRequestsForClinic2",
"query": GRAPHQL_QUERY,
"variables": variables,
}
r = requests.post("https://api.medevio.cz/graphql", json=payload, headers=headers)
r.raise_for_status()
data = r.json().get("data", {}).get("requestsResponse", {})
return data.get("patientRequests", []), data.get("count", 0)
# ================================
# 🧠 MAIN
# ================================
def main():
token = read_token(TOKEN_PATH)
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json",
}
conn = pymysql.connect(**DB_CONFIG)
print(f"\n=== Sync ACTIVE požadavků @ {datetime.now():%Y-%m-%d %H:%M:%S} ===")
# -------------------------------
# 🚀 FETCH ALL ACTIVE REQUESTS
# -------------------------------
offset = 0
total_processed = 0
total_count = None
while True:
batch, count = fetch_active(headers, offset)
if total_count is None:
total_count = count
print(f"📡 Celkem ACTIVE v Medevio: {count}")
if not batch:
break
for r in batch:
upsert(conn, r)
total_processed += len(batch)
print(f"{total_processed}/{total_count} ACTIVE processed")
if offset + BATCH_SIZE >= count:
break
offset += BATCH_SIZE
time.sleep(0.4)
conn.close()
print("\n✅ ACTIVE sync hotovo!\n")
if __name__ == "__main__":
main()

87
Testy/11 Testy.py Normal file
View File

@@ -0,0 +1,87 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import requests
from pathlib import Path
TOKEN_PATH = Path("token.txt")
GRAPHQL_URL = "https://api.medevio.cz/graphql"
CLINIC_SLUG = "mudr-buzalkova"
QUERY = r"""
query ClinicLegacyRequestList_ListPatientRequestsForClinic(
$clinicSlug: String!,
$queueId: String,
$queueAssignment: QueueAssignmentFilter!,
$state: PatientRequestState,
$pageInfo: PageInfo!,
$locale: Locale!
) {
requests: listPatientRequestsForClinic(
clinicSlug: $clinicSlug
queueId: $queueId
queueAssignment: $queueAssignment
state: $state
pageInfo: $pageInfo
) {
id
displayTitle(locale: $locale)
createdAt
doneAt
removedAt
extendedPatient {
name
surname
}
}
}
"""
def main():
token = TOKEN_PATH.read_text().strip()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json",
}
variables = {
"clinicSlug": CLINIC_SLUG,
"queueId": None,
"queueAssignment": "ANY",
"state": "ACTIVE",
"pageInfo": {"first": 200, "offset": 100},
"locale": "cs",
}
print("⏳ Testing ACTIVE request fetch (LEGACY API)…")
r = requests.post(
GRAPHQL_URL,
json={"query": QUERY, "variables": variables},
headers=headers,
timeout=30
)
r.raise_for_status()
js = r.json()
# extract list
requests_list = js.get("data", {}).get("requests", [])
print("\n📌 Number of ACTIVE requests returned:", len(requests_list))
print("\n📌 First 5 request IDs:")
for item in requests_list[:5]:
print("", item.get("id"))
# debug dump if needed
# print(json.dumps(js, indent=2, ensure_ascii=False))
print("\n✅ Test completed.\n")
if __name__ == "__main__":
main()

168
Testy/12 Testy.py Normal file
View File

@@ -0,0 +1,168 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pymysql
import requests
from pathlib import Path
from datetime import datetime
# ================================
# 🔧 CONFIGURATION
# ================================
TOKEN_PATH = Path("token.txt")
CLINIC_SLUG = "mudr-buzalkova"
LIMIT = 300 # download the latest 300 requests
DB_CONFIG = {
"host": "192.168.1.76",
"port": 3307,
"user": "root",
"password": "Vlado9674+",
"database": "medevio",
"charset": "utf8mb4",
"cursorclass": pymysql.cursors.DictCursor,
}
GRAPHQL_QUERY = r"""
query ClinicRequestGrid_ListPatientRequestsForClinic2(
$clinicSlug: String!,
$queueId: String,
$queueAssignment: QueueAssignmentFilter!,
$pageInfo: PageInfo!,
$locale: Locale!,
$state: PatientRequestState
) {
requestsResponse: listPatientRequestsForClinic2(
clinicSlug: $clinicSlug,
queueId: $queueId,
queueAssignment: $queueAssignment,
pageInfo: $pageInfo,
state: $state
) {
count
patientRequests {
id
displayTitle(locale: $locale)
createdAt
updatedAt
doneAt
removedAt
extendedPatient {
name
surname
identificationNumber
}
}
}
}
"""
# ================================
# TOKEN
# ================================
def read_token(p: Path) -> str:
tok = p.read_text(encoding="utf-8").strip()
if tok.startswith("Bearer "):
return tok.split(" ", 1)[1]
return tok
# ================================
# DATE PARSER
# ================================
def to_mysql_dt(iso_str):
if not iso_str:
return None
try:
dt = datetime.fromisoformat(iso_str.replace("Z", "+00:00"))
return dt.strftime("%Y-%m-%d %H:%M:%S")
except:
return None
# ================================
# UPSERT
# ================================
def upsert(conn, r):
p = (r.get("extendedPatient") or {})
sql = """
INSERT INTO pozadavky (
id, displayTitle, createdAt, updatedAt, doneAt, removedAt,
pacient_jmeno, pacient_prijmeni, pacient_rodnecislo
) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)
ON DUPLICATE KEY UPDATE
displayTitle=VALUES(displayTitle),
updatedAt=VALUES(updatedAt),
doneAt=VALUES(doneAt),
removedAt=VALUES(removedAt),
pacient_jmeno=VALUES(pacient_jmeno),
pacient_prijmeni=VALUES(pacient_prijmeni),
pacient_rodnecislo=VALUES(pacient_rodnecislo)
"""
vals = (
r.get("id"),
r.get("displayTitle"),
to_mysql_dt(r.get("createdAt")),
to_mysql_dt(r.get("updatedAt")),
to_mysql_dt(r.get("doneAt")),
to_mysql_dt(r.get("removedAt")),
p.get("name"),
p.get("surname"),
p.get("identificationNumber"),
)
with conn.cursor() as cur:
cur.execute(sql, vals)
conn.commit()
# ================================
# FETCH LATEST 300 REQUESTS
# ================================
def fetch_latest_requests(headers):
vars = {
"clinicSlug": CLINIC_SLUG,
"queueId": None,
"queueAssignment": "ANY",
"pageInfo": {"first": LIMIT, "offset": 0},
"locale": "cs",
"state": "DONE" # ALL STATES (ACTIVE, DONE, REMOVED)
}
payload = {
"operationName": "ClinicRequestGrid_ListPatientRequestsForClinic2",
"query": GRAPHQL_QUERY,
"variables": vars,
}
r = requests.post("https://api.medevio.cz/graphql", json=payload, headers=headers)
r.raise_for_status()
data = r.json()["data"]["requestsResponse"]
return data.get("patientRequests", [])
# ================================
# MAIN
# ================================
def main():
token = read_token(TOKEN_PATH)
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json",
}
conn = pymysql.connect(**DB_CONFIG)
print(f"\n=== Downloading last {LIMIT} requests @ {datetime.now():%Y-%m-%d %H:%M:%S} ===")
requests_list = fetch_latest_requests(headers)
print(f"📌 Requests returned: {len(requests_list)}")
for r in requests_list:
upsert(conn, r)
conn.close()
print("\n✅ Done. Latest requests synced.\n")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,201 @@
query ClinicPatientDetailModal_GetData(
$clinicSlug: String!,
$patientId: String!,
$patientUuid: UUID!,
$challengesStatus: ECRFChallengeStatus!,
$locale: Locale!
) {
clinic: getClinic(clinicSlug: $clinicSlug) {
id
features
sslSUKLCertificateId
type
ais
slug
...ClinicWithTypeAndFeatures_Clinic
...PatientInfo_Clinic
__typename
}
patient: getPatientForClinic(clinicSlug: $clinicSlug, patientId: $patientId) {
...ClinicPatientDetailModal_Patient
__typename
}
challenges: listPatientChallenges2(
clinicSlug: $clinicSlug
patientId: $patientId
status: $challengesStatus
) {
...ChallengeTableList_EcrfChallenge
__typename
}
patientRequestsResponse: filterPatientRequestsForClinic(
clinicSlug: $clinicSlug
filter: {patientId: $patientUuid}
pageInfo: {first: 1, offset: 0}
) {
count
items { id __typename }
__typename
}
treatmentPlanPatients: listTreatmentPlanPatients(
clinicSlug: $clinicSlug
patientId: $patientUuid
) {
...ClinicPlanPatientList_PlanPatient
__typename
}
premiumPlans: listClinicPremiumPlans(clinicSlug: $clinicSlug) {
id
__typename
}
mergeSuggestions: findMergeSuggestions(
clinicSlug: $clinicSlug
input: {existingPatientId: $patientUuid}
) {
...MergeSuggestionAlert_MergeSuggestionResult
__typename
}
insuranceCards: getPatientDocuments(
patientId: $patientUuid
type: InsuranceCard
) {
...PatientInfo_InsuranceCard
__typename
}
}
# — fragmenty (přesně tak, jak jsi měl) —
fragment ClinicWithTypeAndFeatures_Clinic on Clinic {
id
type
features
__typename
}
fragment PatientInfo_Clinic on Clinic {
country
id
slug
ais
...ClinicWithTypeAndFeatures_Clinic
__typename
}
fragment ClinicPatientDetailModal_Patient on ExtendedPatient {
id
isInClinic
kind
name
isUnknownPatient
sex
surname
identificationNumber
editableByDoctor
type
key
user { id name surname __typename }
...ClinicPatientDetail_Patient
...PatientInfo_AccountPatient
...ClinicPatientInfo_Patient
__typename
}
fragment ClinicPatientDetail_Patient on ExtendedPatient {
name
surname
email
id
identificationNumber
isInClinic
key
phone
sex
type
dob
user { id __typename }
isUnknownPatient
hasMobileApp
__typename
}
fragment PatientInfo_AccountPatient on ExtendedPatient {
id
createdAt
key
user {
registrationCompletedTime
deactivatedTime
__typename
}
__typename
}
fragment ClinicPatientInfo_Patient on ExtendedPatient {
anamnesisShared
anamnesisStatusForClinic { updatedAt __typename }
clinics { id name slug __typename }
id
isInClinic
dob
city
familyMembers: family { __typename }
houseNumber
identificationNumber
insuranceCompanyObject { id code name shortName __typename }
kind
name
note
owner { name surname __typename }
key
status
street
surname
user { id email name phone surname __typename }
userRelationship
premiumPlanPatient { id __typename }
sex
tags(onlyImportant: false) { id name color icon __typename }
type
isUnknownPatient
hasMobileApp
__typename
}
fragment ChallengeTableList_EcrfChallenge on ECRFChallenge {
id
createdAt
sentAt
issuedToPatient {
id
identificationNumber
name
surname
__typename
}
userECRF(locale: $locale) { id name __typename }
patientRequestId
status
__typename
}
fragment MergeSuggestionAlert_MergeSuggestionResult on MergeSuggestionResult {
extendedPatient { id __typename }
matchResult
__typename
}
fragment ClinicPlanPatientList_PlanPatient on TreatmentPlanPatient {
id
createdAt
listPatient { id identificationNumber name key status surname __typename }
treatmentPlan { id slug name __typename }
__typename
}
fragment PatientInfo_InsuranceCard on PatientDocument {
id
contentType
url
downloadUrl
__typename
}