> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flextell.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# AI raporları ve planları

> AI raporu oluşturmayı, rapor sonuç yapısını, PDF'i ve rapor planlarını anlatır.

Bir **AI raporu**, kliniğin seçtiğiniz dönemdeki performansını özetleyen belgedir. Sayılar sistem kayıtlarından hesaplanır ve bir önceki karşılaştırılabilir dönemle kıyaslanır. AI yalnızca kısa bir özet ve öneriler yazar; sayıları üretmez. **Rapor planı** ise bu raporları günlük, haftalık veya aylık olarak kendiliğinden oluşturan tanımdır.

Bu sayfa, raporları ve planları API'den yönetmek isteyen entegrasyon geliştiricileri içindir. Panelde aynı işler için [AI Raporları](/panel/klinik/ai-raporlari) ve [Rapor Planları](/panel/klinik/rapor-planlari) sayfaları vardır.

Tüm isteklerde `Authorization: Bearer <access_token>` ve `X-Tenant: <tenant_id>` başlıkları gerekir. Taban adres `https://app.flextell.ai/api/v1` şeklindedir.

## Endpoint özeti

### AI raporları

| Metot | Endpoint | Açıklama | Scope | İzin |
| - | - | - | - | - |
| `GET` | `/ai-reports` | Raporları listeler | `ai-reports:read` | `View:AIReport` |
| `POST` | `/ai-reports` | Yeni rapor kuyruğa alır | `ai-reports:write` | `Create:AIReport` |
| `GET` | `/ai-reports/{id}` | Raporu getirir | `ai-reports:read` | `View:AIReport` |
| `POST` | `/ai-reports/{id}/recreate` | Raporun yeni bir kopyasını kuyruğa alır | `ai-reports:write` | `Create:AIReport` |
| `GET` | `/ai-reports/{id}/pdf` | Raporu PDF olarak indirir | `ai-reports:read` | `Download:AIReport` |
| `DELETE` | `/ai-reports/{id}` | Raporu siler | `ai-reports:write` | `Delete:AIReport` |

### Rapor planları

| Metot | Endpoint | Açıklama | Scope | İzin |
| - | - | - | - | - |
| `GET` | `/ai-report-schedules` | Planları listeler | `ai-report-schedules:read` | `View:AIReportSchedule` |
| `POST` | `/ai-report-schedules` | Plan oluşturur | `ai-report-schedules:write` | `Create:AIReportSchedule` |
| `GET` | `/ai-report-schedules/{id}` | Planı getirir | `ai-report-schedules:read` | `View:AIReportSchedule` |
| `PUT` | `/ai-report-schedules/{id}` | Planı kısmi günceller | `ai-report-schedules:write` | `Update:AIReportSchedule` |
| `DELETE` | `/ai-report-schedules/{id}` | Planı siler | `ai-report-schedules:write` | `Delete:AIReportSchedule` |

<Note>
  Kullanıcılar varsayılan olarak yalnızca kendi oluşturdukları raporları görür. Kliniğin tüm raporlarını listelemek, yeniden oluşturmak, indirmek veya silmek için `ViewAllAIReports:AIReport` (**Tümünü Görüntüle**) izni gerekir. Planlarda sahiplik süzgeci yoktur; `View:AIReportSchedule` izni olan herkes kliniğin tüm planlarını görür. Genel kurallar için [izinler ve görünürlük](/api/izinler-ve-gorunurluk) ve [scope'lar](/api/kimlik-dogrulama/scopelar) sayfalarına bakın.
</Note>

## Rapor nesnesi

Rapor oluşturma işi arka planda çalışır. `POST` yanıtı `pending` durumunda bir rapor döndürür; sonucu `GET /ai-reports/{id}` ile `status` alanını izleyerek alırsınız.

| Alan | Tür | Açıklama |
| - | - | - |
| `id` | integer | Rapor kimliği |
| `tenant_id` | integer | Klinik kimliği |
| `title` | string veya null | Rapor başlığı. Plandan gelen raporlarda plan adıdır |
| `systems` | string dizisi | İstenen modüller veya `["all"]` |
| `status` | string | `pending`, `running`, `completed`, `failed` |
| `format` | string | `structured` (şablonlu) veya `html` (eski, klasik) |
| `period_label` | string | Dönem etiketi (aşağıdaki tabloya bakın) |
| `period_start`, `period_end` | tarih-saat | Çözümlenen dönem penceresi |
| `result` | string veya null | Yalnızca eski `html` raporlarda HTML belge; şablonlu raporlarda `null` |
| `result_data` | nesne veya null | Şablonlu raporun yapılandırılmış sonucu ([Sonuç yapısı](#sonuc-yapisi)) |
| `model` | string veya null | Özeti yazan model. Özet üretilmediyse `null` |
| `error_message` | string veya null | `failed` durumunda kullanıcıya gösterilebilir Türkçe hata metni |
| `pdf_available` | boolean | Rapor tamamlandıysa ve `structured` ise `true` |
| `user` | nesne | Raporu isteyen kullanıcı. Plan sahibi yoksa `null` olabilir |
| `completed_at`, `created_at`, `updated_at` | tarih-saat | Zaman damgaları |

Durum akışı `pending` → `running` → `completed` şeklindedir. Hata olursa rapor `failed` olur; durumu API'den elle değiştiremezsiniz.

### Dönem etiketleri

| `period_label` | Etiket | Pencere |
| - | - | - |
| `yesterday` | Dün | Dünün tamamı |
| `last_7_days` | Son 7 Gün | Bugün dahil son 7 gün (varsayılan) |
| `last_30_days` | Son 30 Gün | Bugün dahil son 30 gün |
| `this_week` | Bu Hafta | Pazartesi–Pazar, içinde bulunulan hafta |
| `this_month` | Bu Ay | İçinde bulunulan ay |
| `last_month` | Geçen Ay | Önceki takvim ayı |
| `this_year` | Bu Yıl | İçinde bulunulan yıl |
| `custom_date_range` | Özel Tarih Aralığı | `period_start_date` ve `period_end_date` arası (uçlar dahil) |
| `today` | Bugün | Yalnızca planlarda kullanılabilir |

Dönemler klinik saat dilimine göre çözülür. Karşılaştırma dönemi, önceki eşdeğer penceredir. `this_week`, `this_month` ve `this_year` için önceki dönem, geçen sürenin aynı uzunluğuna kısaltılır.

## Rapor oluşturma

`POST /ai-reports` isteği raporu hemen kaydeder, `202` ile `status: "pending"` döner ve üretimi kuyruğa alır.

| Alan | Zorunlu | Açıklama |
| - | - | - |
| `title` | Hayır | En fazla 255 karakter. Panel 120 karakterle sınırlar |
| `systems` | Evet | En az bir, tekrarsız modül değeri veya `all` |
| `period_label` | Evet | `today` dışında yukarıdaki etiketlerden biri |
| `period_start_date`, `period_end_date` | `custom_date_range` ise evet | Tarih; bugünden ileri olamaz, bitiş başlangıçtan önce olamaz |

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST "https://app.flextell.ai/api/v1/ai-reports" \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>" \
    -H "Content-Type: application/json" \
    -d '{
      "title": "Mart performansı",
      "systems": ["appointment", "revenue", "lead"],
      "period_label": "custom_date_range",
      "period_start_date": "2026-03-01",
      "period_end_date": "2026-03-31"
    }'
  ```

  ```bash curl (PDF indirme) theme={null}
  curl -L "https://app.flextell.ai/api/v1/ai-reports/123/pdf" \
    -H "Authorization: Bearer <access_token>" \
    -H "X-Tenant: <tenant_id>" \
    -o rapor.pdf
  ```
</CodeGroup>

### Modüller

`systems` alanı aşağıdaki değerleri kabul eder. Tüm modüller için `["all"]` gönderin.

| Grup | Modül değerleri |
| - | - |
| Randevu & Klinik | `appointment`, `treatment`, `room` |
| Hasta | `customer`, `demographics`, `customer_form` |
| Finans | `revenue`, `collections`, `sale_items`, `installments`, `payment_methods` |
| Satış Hunisi | `lead`, `pipeline`, `offer`, `lead_source` |
| İletişim & AI | `chat`, `channel`, `blacklist`, `ai_suggestion` |
| Destek | `ticket` |
| Stok | `low_stock`, `stock_movement` |
| Personel | `staff`, `doctor_workload` |
| Sistem | `storage`, `credits` |

<Warning>
  `systems` içinde `all` varsa kayıt tam olarak `["all"]` olarak saklanır. Her modülü tek tek seçmek `all` ile aynı kayda dönüşmez. Listeleme filtresindeki `systems[]` de bu yüzden `["all"]` raporlarla belirli modül raporlarını birbirinden ayrı eşler.
</Warning>

### Yeniden oluşturma

`POST /ai-reports/{id}/recreate` gövde almaz. Kaynak raporun modüllerini, dönem etiketini, başlığını ve özel aralık tarihlerini kopyalayan yeni bir `pending` rapor döndürür.

* Kayan dönemler yeniden çözülür. `last_7_days` raporunu bugün yeniden oluşturursanız bugünün son 7 günü alınır.
* Yeni raporun sahibi, kaynak raporun sahibi değil isteği yapan kullanıcıdır.
* İstek idempotent değildir; her çağrı yeni bir rapor oluşturur.

### Listeleme

`GET /ai-reports` genel [sayfalama](/api/istekler/sayfalama) ve [filtreleme ve sıralama](/api/istekler/filtreleme-ve-siralama) kurallarını izler. Bu kaynağa özgü parametreler:

| Parametre | Açıklama |
| - | - |
| `sort_by` | `title`, `status`, `created_at` (varsayılan), `completed_at`, `period_start`, `period_end`. Varsayılan sıra yeniden eskiye |
| `status`, `format`, `period_label`, `user_id` | Eşleşme filtreleri |
| `systems[]` | Verilen her modül değeri raporda bulunmalıdır (VE koşulu) |
| `created_at_from`/`_to`, `completed_at_from`/`_to`, `period_start_from`/`_to`, `period_end_from`/`_to` | Aralık filtreleri |

Metin araması yoktur. Liste her durumdaki raporu (`pending`, `running`, `failed` dahil) döndürür.

## Sonuç yapısı

Şablonlu (`structured`) raporlarda sonuç `result_data` içindedir ve `version: 2` şemasını kullanır. Bu alan hazır HTML içermez; belgeyi kendiniz çizebilir ya da PDF'i indirebilirsiniz.

```json theme={null}
{
  "version": 2,
  "period": {
    "label": "last_7_days",
    "from": "2026-10-06", "to": "2026-10-12",
    "previous_from": "2026-09-29", "previous_to": "2026-10-05",
    "timezone": "Europe/Istanbul", "days": 7,
    "period_in_progress": null
  },
  "tenant": {"name": "Örnek Klinik", "currency": "TRY", "locale": "tr", "created_at": "2024-01-15"},
  "modules": ["appointment", "revenue"],
  "sections": {
    "appointment": {
      "metrics": {
        "total_appointments": {"current": 120, "previous": 100, "change_percent": 20}
      }
    }
  },
  "narrative": {
    "status": "ok",
    "summary": "Randevu sayısı önceki döneme göre arttı.",
    "recommendations": ["...", "...", "..."]
  },
  "meta": {"model": "...", "generated_at": "2026-10-13T09:00:00+03:00", "locale": "tr"}
}
```

| Alan | Açıklama |
| - | - |
| `period` | Çözümlenen ve önceki dönem tarihleri (`Y-m-d`, uçlar dahil), saat dilimi ve gün sayısı. `period_in_progress`, dönem henüz bitmediyse `day`, `week`, `month`, `year` veya `range` değerini alır |
| `modules` | Çözümlenen modül listesi. `all` açılmış hâlidir |
| `sections` | Her modül için `metrics` nesnesi. Anahtarlar metrik adıdır |
| `narrative` | AI özeti. `status`: `ok`, `failed` veya `skipped` |
| `meta` | Özet için kullanılan model, üretim zamanı ve dil |

### Metrik değer biçimleri

| Biçim | Yapı |
| - | - |
| Tek değer | `{current, previous, change_percent}`. Anlık değerlerde `previous` ve `change_percent` `null` olur |
| Dağılım | Anahtar → tek değer eşlemesi |
| Sıralama | Satır listesi; satırlar tek değerler içerir |
| Gün serisi | `date` alanlı liste |
| Saat serisi | `hour` alanlı liste |
| Düz satırlar | Örneğin kritik stok için `{name, balance, critical_level}` |

92 noktadan uzun günlük seriler haftalık gruplara sıkıştırılır.

### Özet davranışı

* Dönemde hiç etkinlik yoksa AI çağrılmaz; `narrative.status` `skipped` olur.
* Özet üretilemezse rapor yine `completed` olur. `narrative.status` `failed` döner ve sayısal bölümler eksiksizdir.
* Özet 2–3 cümledir (tek günlük dönemlerde 1–2); tam 3 öneri içerir (tek günlük dönemlerde 2).
* Önceki dönem kliniğin kuruluşundan öncesini kapsıyorsa karşılaştırma kısmidir.

### PDF

`GET /ai-reports/{id}/pdf` A4 dikey PDF döndürür. PDF ilk indirmede hazırlanır, birkaç saniye sürebilir ve sonra saklanır. İndirme için `View` değil, `Download:AIReport` izni gerekir.

## Hatalar

| Kod | HTTP | Ne zaman |
| - | - | - |
| `VALIDATION_FAILED` | 422 | Geçersiz istek. Alan doğrulama mesajları İngilizcedir |
| `RESOURCE_NOT_FOUND` | 404 | `AI raporu bulunamadı`: rapor yok veya görünür değil |
| `BAD_REQUEST` | 409 | `AI raporu henüz tamamlanmadı`: tamamlanmamış rapor için PDF istendi |
| `RESOURCE_NOT_FOUND` | 404 | `Bu rapor için PDF kullanılamıyor`: eski `html` rapor |
| `SERVER_ERROR` | 503 | `PDF hazırlanıyor. Lütfen tekrar deneyin.`: biraz sonra yeniden deneyin |
| `FORBIDDEN` | 403 | İzin veya scope eksik |

Rapor üretimi sırasında oluşan hatalar HTTP yanıtı değil, `status: "failed"` ve `error_message` ile görünür:

* `Rapor oluşturulurken bir hata oluştu. Sorun sürerse sistem yöneticinize başvurun.` Örneğin 731 günden uzun bir özel aralık bu hatayla biter; `POST` isteği bu süreyi doğrulamaz.
* `Rapor oluşturulamadı: talebi yapan kullanıcının bu klinikte rapor oluşturma yetkisi kalmamış.` Rapor çalışmaya başladığında isteyen kullanıcı kliniğe ait olmalı ve hâlâ `Create:AIReport` iznine sahip olmalıdır.

## Rapor planları

Plan, belirlenen zamanda sizin adınıza `POST /ai-reports` çağırmak gibi çalışır. Plan, raporu oluşturan kullanıcıya ait olur ve plan adı rapor başlığı olur. Yeni klinikler için üç varsayılan plan kapalı (`is_active: false`) gelir: **Günlük Özet**, **Haftalık Özet** ve **Aylık Özet**. Bu planların sahibi yoktur; ürettikleri raporları yalnızca `ViewAllAIReports:AIReport` izni olanlar görür ve kimseye bildirim gitmez.

### Plan nesnesi

| Alan | Tür | Açıklama |
| - | - | - |
| `id`, `tenant_id` | integer | Kimlikler |
| `name` | string | Plan adı (en fazla 120 karakter). Üretilen raporun başlığı olur |
| `systems` | string dizisi | Modüller veya `["all"]` |
| `period_label` | string | Dönem etiketi. Planlarda `today` da kullanılabilir |
| `period_start_date`, `period_end_date` | tarih veya null | Yalnızca `custom_date_range` için; başka etikette `null` olur |
| `frequency` | string | `daily`, `weekly`, `monthly` |
| `time` | string | `HH:MM`. Dakika yalnızca `00` veya `30` olabilir. Varsayılan `09:00` |
| `timezone` | string | IANA saat dilimi. Varsayılan klinik saat dilimi |
| `follows_work_hours` | boolean | Açıksa rapor, kliniğin günlük kapanış saatinde çalışır. Varsayılan `true` |
| `starts_at` | tarih veya null | Başlangıç tarihi. Bugün veya sonrası olmalıdır |
| `is_active` | boolean | Kapalı plan çalışmaz. Varsayılan `true` |
| `last_run_at`, `next_run_at` | tarih-saat | Son çalışma ve bir sonraki çalışma zamanı |
| `last_status` | string | Yalnızca `dispatched` değerini alır; raporun sonucunu yansıtmaz |
| `user` | nesne | Planı oluşturan kullanıcı. Güncellemeyle değişmez |

<Warning>
  `period_label` değeri `today` olan plan her zaman `follows_work_hours: true` ile kaydedilir; gönderdiğiniz değer yok sayılır.
</Warning>

### Çalışma zamanı kuralları

* `follows_work_hours` açıkken çalışma saati, o günün kapanış saatidir. Kapalı günlerde plan çalışmaz.
* `starts_at` yoksa ve `follows_work_hours` kapalıysa `daily` plan her gün, `weekly` plan pazartesi, `monthly` plan ayın 1'inde çalışır. `follows_work_hours` açıksa `daily` plan her açık günde, `weekly` plan haftanın, `monthly` plan ayın son çalışma gününde çalışır.
* `starts_at` varsa `weekly` plan o tarihin haftanın gününde, `monthly` plan ayın o gününde çalışır. Ay o günü içermiyorsa ayın son gününe çekilir. Plan başlangıç tarihinden önce çalışmaz. Çalışma saatleri açıkken o gün kapalıysa plan, aynı hafta veya ay içindeki en yakın açık güne kayar.
* Plan her zaman en fazla bir kez çalışır; zamanlayıcı geç kalsa bile aynı gün içinde yakalar.
* Plan kaydedilince `next_run_at` yeniden hesaplanır. Kapalı planda `null` olur.

### Plan örneği

```bash theme={null}
curl -X POST "https://app.flextell.ai/api/v1/ai-report-schedules" \
  -H "Authorization: Bearer <access_token>" \
  -H "X-Tenant: <tenant_id>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Haftalık yönetim özeti",
    "systems": ["all"],
    "period_label": "this_week",
    "frequency": "weekly",
    "follows_work_hours": true
  }'
```

Başarılı oluşturma `201` döner. `PUT` isteğinde tüm alanlar isteğe bağlıdır; `timezone` güncellemede `null` olamaz. Listeleme `name`, `frequency`, `is_active`, `last_run_at`, `next_run_at`, `created_at` alanlarıyla sıralanır (varsayılan `created_at`, yeniden eskiye) ve `frequency`, `period_label`, `is_active`, `user_id`, `systems[]` ile aralık filtrelerini destekler. Bulunamayan plan için `404 RESOURCE_NOT_FOUND` ve `AI rapor planı bulunamadı` döner.

## Kredi kullanımı

AI raporları SMS veya WhatsApp kredisi harcamaz. Raporun özet kısmı için yapılan AI çağrıları, aboneliğinizin yapay zekâ kullanım hakkına yazılır ve faturalamada **Yapay zekâ raporu** kalemi altında görünür. Kredi türleri için [krediler](/api/kaynaklar/krediler), abonelik ve kullanım için [abonelik ve faturalama](/api/kaynaklar/abonelik-ve-faturalama) sayfalarına bakın.

Abonelik bitmişse veya kullanım hakkı dolmuşsa AI çağrısı reddedilir. Rapor yine de tamamlanır; sayısal bölümler gelir, `narrative.status` `failed` olur.

| Kod | HTTP | Mesaj |
| - | - | - |
| `SUBSCRIPTION_REQUIRED` | 402 | `Devam etmek için ücretli plan seçin veya aboneliğinizi yenileyin.` |
| `QUOTA_EXHAUSTED` | 422 | `Bu özellik için kullanım hakkınız doldu. Devam etmek için plan seçin veya yenileyin.` |

Erişim kilitleri hakkında ayrıntı için [erişim kilitleri](/api/istekler/erisim-kilitleri) sayfasına bakın.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.