# إخفاء الهوية

```typescript
import {
  Configuration,
  SensitiveDataProtectionApi,
} from "@quba/sensitive-data-protection"

const text = `Patient John Smith (SSN: 123-45-6789) was admitted to
  Dubai General Hospital on 2024-01-15. Contact: john.smith@email.com`

async function protectData(text: string) {
  // Pass your API key on every request via the x-api-key header.
  const api = new SensitiveDataProtectionApi(
    new Configuration({ headers: { "x-api-key": "quba_..." } }),
  )

  return await api.anonymizeText({
    text,
    rules: [
      {
        type: "replace",
        entities: [{ type: "model", value: "person" }],
        replacement: "[PATIENT]",
      },
      {
        type: "mask",
        entities: [{ type: "regex", value: "\\d{3}-\\d{2}-\\d{4}" }],
        masking_char: "*",
        chars_to_mask: 7,
        from_end: true,
      },
      {
        type: "redact",
        entities: [{ type: "model", value: "address" }],
      },
      {
        type: "sha256",
        entities: [{ type: "model", value: "email" }],
      },
    ],
  })
}

const response = await protectData(text)
console.log(response.text)
// Output: Patient [PATIENT] (SSN: ***-**-6789) was admitted to
// [REDACTED] on 2024-01-15. Contact: a1b2c3d4...
```

```python
from quba_sdp import Client, models
from quba_sdp.api import anonymize_text

text = """Patient John Smith (SSN: 123-45-6789) was admitted to
  Dubai General Hospital on 2024-01-15. Contact: john.smith@email.com"""

# base_url defaults to the production API; pass your key via headers.
client = Client(headers={"x-api-key": "quba_..."})

response = anonymize_text.sync(
    client=client,
    body=models.AnonymizeRequestBody(
        text=text,
        rules=[
            models.ReplaceRule(
                entities=[models.ModelEntity(value="person")],
                replacement="[PATIENT]",
            ),
            models.MaskRule(
                entities=[models.RegexEntity(value=r"\d{3}-\d{2}-\d{4}")],
                masking_char="*",
                chars_to_mask=7,
                from_end=True,
            ),
            models.RedactRule(entities=[models.ModelEntity(value="address")]),
            models.SHA256Rule(entities=[models.ModelEntity(value="email")]),
        ],
    ),
)

print(response.text)
# Output: Patient [PATIENT] (SSN: ***-**-6789) was admitted to
# [REDACTED] on 2024-01-15. Contact: a1b2c3d4...
```

استخدم `model` لتترك للذكاء الاصطناعي كشف أنواع الكيانات تلقائياً، واستخدم `regex` لاستهداف نمط محدد، مثل صيغة رقم تعريفي أو صيغة تاريخ.

```typescript
// Model-based: AI finds the entity type
{ type: "model", value: "person" }

// Regex-based: matches your exact pattern
{ type: "regex", value: "\\d{3}-\\d{2}-\\d{4}" }
```

```python
# Model-based: AI finds the entity type
models.ModelEntity(value="person")

# Regex-based: matches your exact pattern
models.RegexEntity(value=r"\d{3}-\d{2}-\d{4}")
```

## القواعد [#القواعد]

تحدّد القاعدة للواجهة أمرين: **ما الذي تكشفه**، و**كيف تعالجه** لإخفاء الهوية. ولكل قاعدة جزآن إلزاميان:

* **`type`**: عملية إخفاء الهوية المطبَّقة (`replace` أو `redact` أو `mask` أو `sha256` أو `sha512` أو `encrypt`)
* **`entities`**: كيان مستهدف واحد أو أكثر، يُحدَّد كلٌّ منها بالنموذج أو بتعبير نمطي (regex)

```typescript
{
  type: "replace",                                    // what to do
  entities: [{ type: "model", value: "person" }],     // what to find
  replacement: "[PATIENT]"                            // anonymization option
}
```

تمرّر القواعد في مصفوفة. تُقيَّم كل قاعدة على النص كاملاً بمعزل عن غيرها، لذا قد تطابق عدة قواعد مقاطع مختلفة وتعالجها، حتى لو تداخلت هذه المقاطع. وتُطبَّق القواعد بترتيب ورودها.

### الكيانات المستهدفة [#الكيانات-المستهدفة]

يُحدَّد كل كيان في `entities` إمّا بالنموذج أو بتعبير نمطي:

| النوع   | الوصف                            | مثال                                               |
| ------- | -------------------------------- | -------------------------------------------------- |
| `model` | يكشف الذكاء الاصطناعي نوع الكيان | `{ type: "model", value: "person" }`               |
| `regex` | يُطابَق النص بالنمط الذي تحدده   | `{ type: "regex", value: "\\d{3}-\\d{2}-\\d{4}" }` |

ويمكن أن تجمع القاعدة الواحدة بين الطريقتين:

```typescript
{
  type: "redact",
  entities: [
    { type: "model", value: "email" },
    { type: "regex", value: "[A-Z]{2}\\d{6}" },  // custom ID format
  ]
}
```

```python
models.RedactRule(
    entities=[
        models.ModelEntity(value="email"),
        models.RegexEntity(value=r"[A-Z]{2}\d{6}"),  # custom ID format
    ]
)
```

### تسميات النموذج [#model-labels]

كيانات النموذج تسميات بصيغة `snake_case`، مثل `person` و`email` و`phone_number` و`address` و`card_number` و`api_key`. تُكشف تسميات البيانات الشخصية الشائعة بأعلى دقة، وتعمل أي تسمية أخرى أيضًا بدقة أقل.

### القواعد الافتراضية والسياسات المُسندة [#default-rules-and-assigned-policies]

الحقل `rules` اختياري، والقواعد التي تُطبَّق تعتمد على المُستدعي:

1. **سياسة مُسندة.** يستطيع المسؤول إسناد سياسة إلى مفتاح API أو إلى عضو في الفريق من لوحة التحكم، فتُطبَّق على كل استدعاء بذلك المفتاح أو من إضافة المتصفح، ويُرفض بالرمز `403` أي طلب يرسل `rules` أو `confidence_threshold` معها. ويبقى بإمكان ساحة التجارب في لوحة التحكم تجربة قواعد أخرى.
2. **قواعد الطلب `rules`**، إن لم تُسند سياسة.
3. **القواعد الافتراضية**، إن لم يوجد أيٌّ منهما: المُعرِّفات الشخصية والصحية والمالية وبيانات الاعتماد، ويُستبدل كلٌّ منها باسم تسميته بأحرف كبيرة بين قوسين معقوفين، فيصبح `John Smith` هو `[PERSON]`. ويكشف `/scan` التسميات نفسها إن لم تُرسل `entities`. وتشمل القواعد الافتراضية:

   * مُعرِّفات HIPAA Safe Harbor الواردة في النص: الأسماء والعناوين والتواريخ والأعمار وأرقام الهاتف والفاكس والبريد الإلكتروني وعناوين IP والروابط، وأرقام الهويات والحسابات والرخص والشهادات والسجلات الطبية والتأمين الصحي، ومُعرِّفات المركبات والأجهزة والمُعرِّفات الحيوية؛
   * أرقام جوازات السفر والأرقام الضريبية؛
   * أرقام البطاقات ورموز التحقق وتواريخ انتهائها، وأرقام IBAN والحسابات المصرفية وأرقام التوجيه؛
   * كلمات المرور ومفاتيح API ورموز الوصول والأسرار ورموز الاسترداد.

### حد الثقة [#حد-الثقة]

يرفق النموذج بكل كيان يكشفه درجة `score` (من 0.0 إلى 1.0) تعبّر عن ثقته في صحة الكشف. ويستبعد المعامل `confidence_threshold` الكيانات التي تقل درجة ثقتها عن الحد المطلوب.

```typescript
await api.anonymizeText({
  text: "...",
  rules: [...],
  confidence_threshold: 0.8, // only apply rules to high-confidence detections
})
```

```python
anonymize_text.sync(
    client=client,
    body=models.AnonymizeRequestBody(
        text="...",
        rules=[...],
        confidence_threshold=0.8,  # only apply rules to high-confidence detections
    ),
)
```

* القيمة الافتراضية: `0.5`
* تُطبَّق القواعد دائماً على مطابقات التعابير النمطية، فحد الثقة لا يؤثر فيها
* ارفع الحد (مثل `0.8`) لتقليل الكشف الخاطئ، أو اخفضه لكشف عدد أكبر من الكيانات

## عمليات إخفاء الهوية [#عمليات-إخفاء-الهوية]

### الاستبدال [#الاستبدال]

استبدل الكيانات المكتشَفة بنص تحدده:

```typescript
{
  type: "replace",
  entities: [{ type: "model", value: "person" }],
  replacement: "[REDACTED]"   // default: "****"
}
```

```python
models.ReplaceRule(
    entities=[models.ModelEntity(value="person")],
    replacement="[REDACTED]",  # default: "****"
)
```

### الحجب [#الحجب]

أزِل الكيانات المكتشَفة من النص كلياً:

```typescript
{
  type: "redact",
  entities: [{ type: "model", value: "email" }]
}
```

```python
models.RedactRule(entities=[models.ModelEntity(value="email")])
```

### التقنيع [#التقنيع]

غطِّ جزءاً من الكيان المكتشَف بحرف التقنيع:

```typescript
{
  type: "mask",
  entities: [{ type: "model", value: "phone_number" }],
  masking_char: "*",     // default: "*"
  chars_to_mask: 8,      // null = mask all characters
  from_end: true         // false = mask from start
}
// +1-555-123-4567 → +1-555-***-****
```

```python
models.MaskRule(
    entities=[models.ModelEntity(value="phone_number")],
    masking_char="*",      # default: "*"
    chars_to_mask=8,       # None = mask all characters
    from_end=True,         # False = mask from start
)
# +1-555-123-4567 → +1-555-***-****
```

### SHA256 / SHA512 [#sha256--sha512]

حوّل الكيانات المكتشَفة إلى قيم مُجزّأة:

```typescript
{
  type: "sha256",
  entities: [{ type: "model", value: "government_id" }]
}
```

```python
models.SHA256Rule(entities=[models.ModelEntity(value="government_id")])
# or models.SHA512Rule(...)
```

### التشفير [#التشفير]

شفّر الكيانات المكتشَفة بمفتاح تحدده:

```typescript
{
  type: "encrypt",
  entities: [{ type: "model", value: "person" }],
  key: "your-encryption-key"   // default: ""
}
```

```python
models.EncryptRule(
    entities=[models.ModelEntity(value="person")],
    key="your-encryption-key",  # default: ""
)
```

## التعابير النمطية [#التعابير-النمطية]

يمكنك أيضاً استهداف أجزاء من النص بتعابير نمطية (regex):

```typescript
{
  type: "replace",
  entities: [{ type: "regex", value: "\\d{4}-\\d{2}-\\d{2}" }],
  replacement: "[DATE]"
}
```

```python
models.ReplaceRule(
    entities=[models.RegexEntity(value=r"\d{4}-\d{2}-\d{2}")],
    replacement="[DATE]",
)
```

## نتائج تطبيق القواعد [#rule-application-results]

عند تنفيذ إخفاء الهوية، يُنشأ سجل نتيجة لكل كيان كُشف وعولج. وتُعاد هذه السجلات في `response.results` سجلَّ تدقيق مرتباً، بعنصر واحد لكل مقطع مطابق.

```typescript
const response = await api.anonymizeText({ text, rules })

console.log(response.text) // the anonymized string
console.log(response.results) // one record per anonymization applied
```

```python
response = anonymize_text.sync(
    client=client,
    body=models.AnonymizeRequestBody(text=text, rules=rules),
)

print(response.text)     # the anonymized string
print(response.results)  # one record per anonymization applied
```

تبيّن لك كل نتيجة:

* **القاعدة** المطبَّقة (`rule`)
* **ما كُشف** (`value`: نوع الكيان أو التعبير النمطي)
* **موضعه** في النص الأصلي (`input`)
* **موضعه الجديد** في النص الناتج (`output`)

والنتيجة إمّا **نتيجة نموذج** (كيان كشفه الذكاء الاصطناعي) أو **نتيجة تعبير نمطي** (مقطع طابق نمطاً)، ويحدد الحقل `type` نوعها:

### نتيجة النموذج [#نتيجة-النموذج]

```typescript
{
  type: "model",
  rule: "replace",            // rule type that was applied
  value: "PERSON",            // entity type the model detected
  score: 0.94,                // AI confidence (0.0–1.0)
  input:  { start: 8, end: 18, value: "John Smith" },   // position in original text
  output: { start: 8, end: 17, value: "[PATIENT]"  },   // position in result text
}
```

### نتيجة التعبير النمطي [#نتيجة-التعبير-النمطي]

```typescript
{
  type: "regex",
  rule: "mask",                                          // rule type that was applied
  value: "\\d{3}-\\d{2}-\\d{4}",                        // pattern that matched
  input:  { start: 20, end: 31, value: "123-45-6789" }, // position in original text
  output: { start: 20, end: 31, value: "***-**-6789" }, // position in result text
}
```

### حقول TextRange [#حقول-textrange]

| الحقل   | النوع  | الوصف                                  |
| ------- | ------ | -------------------------------------- |
| `start` | number | موضع بداية المقطع (مشمول)              |
| `end`   | number | موضع نهاية المقطع (غير مشمول)          |
| `value` | string | المقطع الواقع في النطاق `[start, end)` |

تُرتَّب النتائج حسب موضعها في النص الناتج. استخدم مواضع `input` لتحديد كل مقطع في النص الأصلي، ومواضع `output` لإبراز المقاطع في النص الناتج.
