release: dev → main (сдача хакатона) #106
@@ -0,0 +1,16 @@
|
|||||||
|
"""PII scrubbing and pseudonymisation (issue #2). Contract stub — implementation lands in #2."""
|
||||||
|
|
||||||
|
from app.core.types import ScrubbedText
|
||||||
|
|
||||||
|
|
||||||
|
def scrub(text: str) -> ScrubbedText:
|
||||||
|
"""Replace personal data (phones, emails, SNILS, names, addresses...) with placeholders."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
def pseudo_id(snils: str, key: str | None = None) -> str:
|
||||||
|
"""HMAC-SHA256(PSEUDO_KEY, normalised SNILS) as 32 hex chars.
|
||||||
|
|
||||||
|
The token is the only link between the identity and clinical databases.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
"""Shared core types. Frozen contract between zones: change only via a separate small PR."""
|
||||||
|
|
||||||
|
from enum import IntEnum
|
||||||
|
from typing import NewType
|
||||||
|
|
||||||
|
# Text that has passed `app.core.privacy.scrub()`. The LLM gateway accepts only this type (guardrail #1).
|
||||||
|
ScrubbedText = NewType("ScrubbedText", str)
|
||||||
|
|
||||||
|
|
||||||
|
class RiskLevel(IntEnum):
|
||||||
|
"""Safety risk level. Ordered, so the combined signal is `max(lexicon, llm)`."""
|
||||||
|
|
||||||
|
NONE = 0
|
||||||
|
POSSIBLE = 1
|
||||||
|
ACUTE = 2
|
||||||
|
|
||||||
|
|
||||||
|
class AlertLevel(IntEnum):
|
||||||
|
"""Alert level stored in DB.
|
||||||
|
|
||||||
|
UI colour is derived (ADR-006): ACUTE=red, HIGH/MODERATE=yellow, INFO=grey.
|
||||||
|
"""
|
||||||
|
|
||||||
|
INFO = 0
|
||||||
|
MODERATE = 1
|
||||||
|
HIGH = 2
|
||||||
|
ACUTE = 3
|
||||||
Reference in New Issue
Block a user