from __future__ import annotations from datetime import datetime, timezone import json from pathlib import Path import sys import gradio as gr ROOT = Path(__file__).resolve().parent sys.path.insert(0, str(ROOT / "src")) from werea_kvkk.engine import PrivacyOpsEngine from werea_kvkk.governance import OrganisationProfile from werea_kvkk.pii import PIIDetector from werea_kvkk.rag import SourceRetriever detector = PIIDetector() engine = PrivacyOpsEngine() retriever = SourceRetriever() def scan(text: str): redacted, findings = detector.redact(text) return redacted, json.dumps([item.to_dict() for item in findings], ensure_ascii=False, indent=2) def workflow(rule_id: str): case = engine.create_case(rule_id, datetime.now(timezone.utc)) return json.dumps(case.to_dict(), ensure_ascii=False, indent=2) def sources(query: str): return json.dumps(retriever.search(query), ensure_ascii=False, indent=2) def coverage(): rules = engine.list_rules() by_tag: dict[str, int] = {} for item in rules: for tag in item.get("tags", []): by_tag[tag] = by_tag.get(tag, 0) + 1 return json.dumps({ "catalog_version": engine.version, "workflow_count": len(rules), "source_count": len(retriever.sources), "by_tag": dict(sorted(by_tag.items())), "legal_compliance_determination": "not_performed", "human_legal_review_required": True, }, ensure_ascii=False, indent=2) def profile_assessment(sector: str, flags: list[str]): profile = OrganisationProfile( organisation_id="synthetic-demo", legal_name="Kurgusal Kurum", sectors=(sector,), established_in_turkiye=True, processes_special_category_data="Özel nitelikli veri" in flags, processes_children_data="Çocuk verisi" in flags, uses_biometric_data="Biyometri" in flags, uses_ai_for_people="Kişiler hakkında AI" in flags, has_international_transfers="Yurt dışı aktarım" in flags, uses_online_tracking="Çerez/SDK" in flags, ) tags = profile.risk_tags() applicable = [item["id"] for item in engine.list_rules() if tags.intersection(item.get("tags", []))] return json.dumps({ "risk_tags": sorted(tags), "candidate_workflows": applicable, "notice": "Bu bir ön kapsam önerisidir; hukuki kapsam kararı değildir.", }, ensure_ascii=False, indent=2) with gr.Blocks(title="Werea KVKK PrivacyOps v2") as demo: gr.Markdown("""# Werea KVKK Lab Evidence-first, human-approved KVKK PrivacyOps v2 research preview. **Use synthetic text only.** This demo is decision support, not legal advice. It never sends notifications, submits VERBİS records or deletes data. """) with gr.Tab("PII scan"): input_text = gr.Textbox(label="Synthetic Turkish text", lines=6, value="Ada Örnek'e ada@example.invalid veya 0555 000 12 34 üzerinden ulaşın.") scan_button = gr.Button("Scan and redact") redacted = gr.Textbox(label="Redacted") findings = gr.Code(label="Findings", language="json") scan_button.click(scan, input_text, [redacted, findings]) with gr.Tab("Workflow"): rule = gr.Dropdown(choices=[item["id"] for item in engine.list_rules()], value="DSAR_RESPONSE", label="Rule") workflow_button = gr.Button("Create draft case") workflow_output = gr.Code(language="json") workflow_button.click(workflow, rule, workflow_output) with gr.Tab("Official sources"): query = gr.Textbox(value="veri ihlali 72 saat", label="Query") source_button = gr.Button("Search versioned source index") source_output = gr.Code(language="json") source_button.click(sources, query, source_output) with gr.Tab("Coverage"): gr.Markdown("51 workflow catalog and institution-specific preliminary scoping. No compliance score is produced.") coverage_button = gr.Button("Show catalog coverage") coverage_output = gr.Code(language="json") coverage_button.click(coverage, outputs=coverage_output) sector = gr.Dropdown( choices=["retail", "digital", "finance", "health", "employment", "public"], value="digital", label="Synthetic organisation sector", ) flags = gr.CheckboxGroup( choices=["Özel nitelikli veri", "Çocuk verisi", "Biyometri", "Kişiler hakkında AI", "Yurt dışı aktarım", "Çerez/SDK"], label="Processing features", ) profile_button = gr.Button("Build preliminary scope") profile_output = gr.Code(language="json") profile_button.click(profile_assessment, [sector, flags], profile_output) demo.launch()