Proje: Okul B2B App · Hub: Okul B2B App — Domain

Firma ve Okul API Tip Detayları

Company (API)

/customer/me/firms response:

interface Company {
  id: number;
  redirect_id: number;    // firma ID'si (genellikle id ile aynı)
  name: string;
  firm_name: string;
  province_id: number;
  province_name: string;  // İl adı
  county_id: number;
  county_name: string;    // İlçe adı
  schools: School[];      // Firmanın okulları
}

School (API)

interface School {
  id: number;
  name: string;
  province_id, province_name,   // İl
  county_id, county_name,       // İlçe
  neighbourhood_id, neighbourhood_name,  // Mahalle
  address: string;
  lead_count: number;      // Firmanın bu okuldaki leads sayısı (yetki ipucu)
  gallery_count: number;   // Firmanın bu okulundaki galeri öğe sayısı (yetki ipucu)
}

CustomerUserFirmResource.php (BE) tam listelenen alanlar yukarıdaki 11 alandan ibaret. CompaniesService tipinde lead_count / gallery_count yazılı değil, (school as any).lead_count ile erişiliyor (OKUL-626 yetki kontrolü için kullanılıyor).

API’de OLMAYAN Alanlar (2026-04-17 itibarıyla)

  • is_active / status — Pasif okullar response’ta gelir, ayırt edilemez.
  • has_content_access / has_lead_access — Kullanıcı bazlı yetki customer_user_schools tablosunda var ama response’a yansıtılmaz. BE schools relation’ını ALL customer schools olarak yükler, per-user filter uygulamaz.
  • deleted_at / school_closed / redirect_id — Aktiflik kontrolü için BE’nin School::isActive() metodunda kullanıldığı halde response’a çıkmaz.

Pratik sonuç: “Pasif okul gizleme” veya “yetkisiz okul switch engelleme” mobile-only yapılırsa heuristic olur (lead_count/gallery_count > 0 ama endpoint 0 dönüyorsa yetki yok gibi). Tam çözüm için BE’den alan eklenmesi gerekir.

SchoolUI (UI Format)

Context’te kullanılan, istatistik eklenmiş format:

interface SchoolUI {
  id, name, location, address,
  city,       // province_name
  district,   // county_name
  neighborhood,
  requestCount: number,  // Leads totalCount (ayrıca yüklenir)
  photoCount: number,    // Galeri fotoğraf sayısı (ayrıca yüklenir)
  isActive: boolean
}

SchoolContext.convertApiSchoolToUISchool() ile dönüştürülür.

CompanyContextType

{
  selectedCompanyId: number | null,
  company: Company | null,
  setSelectedCompanyId: (id: number) => Promise<void>,
  isLoading, isReady, error,
  needsCompanySelection: boolean,  // Firma seçim ekranı gösterilmeli mi
  hasNoCompanies: boolean,         // Hiç firma yok ekranı
}