# İK › Intranet (`App.Hr.Intranet`) Kurum içi iletişim: ana sayfa panosu (bugün doğanlar, dokümanlar, aktif anketler, sosyal duvar, duyurular, yaklaşan etkinlikler), bunların yönetim ekranları (duyuru, anket, sosyal paylaşım, etkinlik), doküman kütüphanesi ve kullanıcılar arası mesajlaşma. Bu modül **entity + C# seeder + özel React sayfalarıyla** kuruludur (wizard değil); pano kutuları Developer Kit › Intranet Widgets kaydıyla yönetilir. > Bu doküman modülün tek "nasıl çalışır" kaynağıdır. Modülde yapılan her değişiklik aynı commit'te > buraya yansır (`lowcode.instructions.md` §0.13). --- ## 1. Amaç ve kapsam | Persona | Ne yapar | Ekran | | --- | --- | --- | | Tüm çalışanlar | Panoyu görür; duyuru okur/beğenir/yorumlar, anket doldurur, paylaşım yapar, beğenir, yorumlar, ankete oy verir, etkinliği beğenir/yorumlar, doküman indirir, mesajlaşır | `/admin/dashboard` · mesajlaşma penceresi | | İK / iç iletişim | Duyuru, anket (soru/seçenek), etkinlik ve tanımlarını yönetir; yanıtları ve etkileşimleri izler | İK › Intranet › Duyurular · Anketler · Sosyal Paylaşımlar · Etkinlik Türleri/Kategorileri · Etkinlikler | | İK / doküman sorumlusu | Doküman yükler, yayına alır/kaldırır | İK › Intranet › Dokümanlar (`/admin/intranet-documents`) | | Sistem yöneticisi | Pano kutularını (hazır ya da custom component) tanımlar, sırasını ve yetkisini belirler | Developer Kit › Intranet Widgets | Kapsam: kiracı. Bütün tablolar `IMultiTenant`; satır süzmesi yoktur. --- ## 2. Analiz ve kararlar > Modül §0.13 kuralından önce üretildi; keşif turu kaydı yoktur. Kararlar koddan > (`ListFormSeeder_Hr.cs`, `Entities/Tenant/Hr/Intranet`, `IntranetAppService`, `views/intranet`) okunmuştur. | Konu | Karar | | --- | --- | | Yol | Yönetim ekranları entity + seeder ListForm'u; pano ve etkileşimler özel React + `IntranetAppService` | | Modül yeri | Intranet İK'dadır: menü `App.Hr.Intranet`, yetkiler `App.Hr.Intranet.*`, tablolar `Hr_T_*`; pano kutusu kaydı (`Sas_T_IntranetWidget`) Saas › Developer Kit'te kalır | | Pano kutuları | Veritabanı kaydıdır (kod, kolon, sıra, yetki, aktiflik). **Builtin** kutu koda kayıtlı React bileşenidir (`id` = kayıt `Code`); **Custom** kutu Developer Kit custom component'idir (Props JSON ile) | | Kullanıcı yerleşimi | Pano tasarım modunda sürükle-bırak, gizle/göster, kolon oranı hazır ayarları; tercih **tarayıcıda (localStorage)** saklanır, sunucuya yazılmaz | | Doğum günleri | Her pano isteğinde kullanıcıların `BirthDate` genişletme alanından canlı hesaplanır (gün + ay) | | Duyuru panoda | Kutu yalnız **sabitlenmiş** (`IsPinned`) duyuruları, en fazla 3 tane gösterir | | Anket | `Status = active` anketler; kullanıcı yanıtını sonradan **güncelleyebilir**; anonim ankette yanıt `UserId` taşımaz | | Sosyal medya | Bir paylaşımda tek medya kaydı (resim(ler), video ya da anket); yüklenen dosya **base64 data URL** olarak `SocialMedia.Urls`'e yazılır | | Doküman yayını | Fiziksel CDN klasörleri: `intranet` (yayında) ve `intranet/_passive` (yayında değil); yayına alma = klasörler arası taşıma | | Mesajlaşma | Yalnız tablo öneki ile İK'dadır (`Hr_T_Messenger*`); menüsü/yetkisi yoktur, kabuk düzenine gömülü pencere + SignalR | | Bildirim / zamanlanmış iş | Yok | --- ## 3. Menü ve ekranlar `İnsan Kaynakları › Intranet` (`App.Hr.Intranet`, sıra 14) | Sıra | Menü | `ListFormCode` / rota | Alt formlar | Widget'lar | | --- | --- | --- | --- | --- | | 1 | Etkinlik Türleri | `App.Hr.Intranet.Events.EventType` | — | — | | 2 | Etkinlik Kategorisi | `App.Hr.Intranet.Events.EventCategory` | — | — | | 3 | Duyurular | `App.Hr.Intranet.Announcement` | `…Announcement.AnnouncementLike`, `…Announcement.AnnouncementComment` (`Id → AnnouncementId`) | Aktif · Sabitlenmiş · Süresi dolan · Toplam görüntülenme | | 4 | Anketler | `App.Hr.Intranet.Survey` | `SurveyQuestion` (→ `SurveyQuestionOption`), `SurveyResponse` (→ `SurveyAnswer`) — iki seviyeli | Aktif · Pasif · Toplam yanıt | | 5 | Sosyal Paylaşımlar | `App.Hr.Intranet.SocialPost` | `SocialComment`, `SocialMedia` (→ `SocialPollOption`), `SocialLike` (`Id → SocialPostId`) | Toplam · Bugün · Toplam beğeni | | 6 | Etkinlikler | `App.Hr.Intranet.Events.Event` | `EventLike`, `EventComment` (`Id → EventId`) | Yaklaşan · Yayında · Taslak · İptal | | 7 | Dokümanlar | `/admin/intranet-documents` (özel sayfa) | — | — | Diğer giriş noktaları: | Ne | Nerede | | --- | --- | | Pano | `/admin/dashboard` (`views/Dashboard.tsx` → `views/intranet/Dashboard.tsx`); rota yetkisizdir, menüde ayrı kaydı yoktur | | Pano kutusu tanımı | Developer Kit › Intranet Widgets (`App.DeveloperKit.IntranetWidgets`, `Sas_T_IntranetWidget`); veri `data/App.DeveloperKit.IntranetWidgets.json`'a aynalanır | | Mesajlaşma | Uygulama kabuğundaki `MessengerWidget` | Pano kutuları (seed): | Kod | Kolon / sıra | Yetki | Ne gösterir | | --- | --- | --- | --- | | `today-birthdays` | Sol / 10 | `AbpIdentity.Users.Widget` | Bugün doğanlar: avatar, ad, yaş, departman | | `documents` | Sol / 20 | `App.Files.Widget` | Yayındaki ilk 3 doküman (tür, boyut, tarih, indir) | | `active-surveys` | Sol / 30 | `App.Hr.Intranet.Survey.Widget` | Aktif anketler (kalan gün, soru/yanıt sayısı, doldurdum/doldur) | | `my-leave` | Sol / 35 | `App.Hr.MyLeaveRequest` | Custom `MyLeaveWidget`: izin bakiyesi, süren talepler → İzin Talebi Oluştur · Taleplerim · Bakiyem | | `team-leave` | Sol / 36 | `App.Hr.TeamLeaveRequest` | Custom `TeamLeaveWidget`: müdürün onayını bekleyen izin talepleri, bugün izinde olanlar → Onay Bekleyenler | | `my-timesheet` | Sol / 37 | `App.Hr.MyTimesheet` | Custom `MyTimesheetWidget`: seçilen ayın puantajı (net saat, geç/erken dk, fazla mesai, devamsız/izinli/raporlu) ve yıl toplamı, 270 saatlik fazla mesai çubuğu → Puantajım | | `social-wall` | Orta / 40 | `App.Hr.Intranet.SocialPost.Widget` | Sosyal duvar (Tümü / Paylaşımlarım, sonsuz kaydırma 10'arlı) | | `announcements` | Sağ / 50 | `App.Hr.Intranet.Announcement.Widget` | Sabitlenmiş duyurular (en fazla 3) | | `upcoming-events` | Sağ / 60 | `App.Hr.Intranet.Events.Event.Widget` | Bugünden sonraki yayınlanmış ilk 3 etkinlik | | `my-performance` | Sağ / 70 | `App.Hr.MyPerformanceReview` | Custom `MyPerformanceWidget`: aktif performans değerlendirmesi, puanlar, gelişim aksiyonları → Değerlendirmelerim | | `team-performance` | Sağ / 80 | `App.Hr.TeamPerformanceReview` | Custom `TeamPerformanceWidget`: yöneticinin ekip değerlendirmeleri → Ekibimin Değerlendirmeleri | | `my-360-feedback` | Sağ / 90 | `App.Hr.My360Feedback` | Custom `My360FeedbackWidget`: kullanıcıya atanan 360 talepleri → 360 Taleplerim | İlk altı kutu Builtin'dir (koddaki `Code`). `my-leave` / `team-leave` İzin Yönetimi'nin (`HrLeave.md` §3.3), `my-timesheet` Puantaj ve Devam Takibi'nin (`HrAttendance.md` §3.3), son üçü Performans Yönetimi'nin çalışana ait özetleridir: İK menüsü İK departmanınındır, çalışan kendi değerlendirmesini buradan takip eder; listeler menüsüzdür ve kutudaki bağlantıyla açılır. Ayrıntı: `HrPerformance.md` §3.3. --- ## 4. Veri modeli Entity'ler `Entities/Tenant/Hr/Intranet` (`FullAuditedEntity, IMultiTenant`); tablolar migration'lıdır. | Tablo | Önemli kolonlar | Kural | | --- | --- | --- | | `Hr_T_Announcement` | `Title`, `Excerpt`, `Content` (HTML), `ImageUrl`, `Category` (general/event/urgent/announcement), `UserId`, `PublishDate`, `ExpiryDate`, `IsPinned`, `ViewCount`, `Likes`, `Attachments` | Başlık kiracıda tekil | | `Hr_T_AnnouncementComment` / `Hr_T_AnnouncementLike` | `AnnouncementId`, `UserId`, (`Content`) | Beğeni kullanıcı başına tekil | | `Hr_T_Survey` | `Title`, `Description`, `Deadline`, `Responses`, `Status`, `IsAnonymous` | Başlık kiracıda tekil | | `Hr_T_SurveyQuestion` | `SurveyId`, `QuestionText`, `Type` (rating/multiple-choice/text/textarea/yes-no), `Order`, `IsRequired` | — | | `Hr_T_SurveyQuestionOption` | `QuestionId`, `Text`, `Order` | — | | `Hr_T_SurveyResponse` / `Hr_T_SurveyAnswer` | `SurveyId`, `UserId`, `SubmissionTime` / `ResponseId`, `QuestionId`, `QuestionType`, `Value` | — | | `Hr_T_SocialPost` | `UserId`, `Content`, `LikeCount`, `IsLiked`, `IsOwnPost` | — | | `Hr_T_SocialMedia` | `SocialPostId` (1:1), `Type` (image/video/poll), `Urls`, `PollQuestion`, `PollTotalVotes`, `PollEndsAt`, `PollUserVoteId` | — | | `Hr_T_SocialPollOption` | `SocialMediaId`, `Text`, `Votes` | — | | `Hr_T_SocialComment` / `Hr_T_SocialLike` | `SocialPostId`, `UserId`, (`Content`) | Beğeni kullanıcı başına tekil | | `Hr_T_SocialLocation` | Konum bilgisi | Kullanan ekran/servis yok | | `Hr_T_EventType` / `Hr_T_EventCategory` | `Name` | Kiracıda tekil | | `Hr_T_Event` | `CategoryId`, `TypeId`, `Date`, `Name`, `Description`, `Place`, `Status` (published/draft/cancelled), `UserId`, `ParticipantsCount`, `Likes`, `isPublished`, `Photos` | `(CategoryId, TypeId, Name)` tekil | | `Hr_T_EventComment` / `Hr_T_EventLike` | `EventId`, `UserId`, (`Content`) | Beğeni tekil | | `Sas_T_IntranetWidget` | `Code`, `Name`, `LabelKey`, `SourceType` (0 Builtin / 1 Custom), `ComponentName`, `PermissionName`, `Column` (0 sol / 1 orta / 2 sağ), `Order`, `Props`, `IsActive` | Kod kiracıda tekil | | `Hr_T_MessengerConversation` / `Hr_T_MessengerConversationMessage` | Konuşma (katılımcılar, son mesaj) / mesaj (gönderen, alıcılar, metin, ekler, zaman) | — | --- ## 5. İş kuralları (`IntranetAppService`) | İşlem | Kural | | --- | --- | | Pano verisi | Doğum günleri (bugün), `intranet` klasöründeki dosyalar (`_passive` hariç), son 50 duyuru, `active` anketler + kullanıcının yanıtı, `isPublished` son 50 etkinlik, aktif ve yetkisi verilmiş pano kutuları. Duyuru için tarih/sabitleme süzmesi, anket için son tarih süzmesi **sunucuda yoktur** | | Duyuru aç | Her açılışta `ViewCount + 1` | | Beğeni (duyuru, paylaşım, etkinlik) | Aç/kapa: beğeni satırı eklenir/silinir, sayaç ±1 | | Yorum | Satır eklenir; listelenirken yazar bilgisi doldurulur | | Anket yanıtı | Kullanıcının önceki yanıtı varsa cevaplar güncellenir; yoksa yeni yanıt + `Responses + 1`; anonimde `UserId` boş | | Paylaşım | İsteğe bağlı tek medya ya da 2–6 seçenekli anket; yalnız sahibi silebilir | | Ankete oy | Seçenek ve toplam oy +1, `PollUserVoteId` = seçenek; tekrar oy UI'da engellenir | | Doküman | Yüklemede görünen ad zorunlu (uzantı korunur); yayına al/kaldır = klasör taşıma; silme toplu | | Mesaj | Aynı kiracıdaki aktif kullanıcılara (en fazla 100 kişi listelenir); en fazla 10 ek; çevrimiçi durumu SignalR (`/messengerhub`) | --- ## 6. Yetki ve görünürlük İzin grubu `App.Hr`, modül `Sas|Hr`. Kök `App.Hr.Intranet`; her yönetim ekranının kökü + standart alt yetkiler (`.Create/.Update/.Delete/.Export/.Import`, ana ekranlarda `.Note`). Duyuru, Anket, Sosyal Paylaşım ve Etkinlik ayrıca **`.Widget`** taşır — pano kutusunu görme yetkisidir. Dokümanlar: `App.Hr.Intranet.Document` + `.Create` (yükle) / `.Update` (yayına al/kaldır) / `.Delete`. Intranet Widgets: `App.DeveloperKit.IntranetWidgets` (+ CRUD). Hiçbir yetki role otomatik atanmaz. Önerilen dağıtım: | Rol | Yetkiler | | --- | --- | | Tüm çalışanlar | `AbpIdentity.Users.Widget`, `App.Files.Widget`, dört `.Widget` yetkisi, `App.Hr.Intranet.Document` (okuma); performans kutuları için `HrPerformance.md` §6 | | İç iletişim | `App.Hr.Intranet` dalının tamamı | | Sistem yöneticisi | `App.DeveloperKit.IntranetWidgets` | **Kontrol edilmeli — güvenlik:** `IntranetAppService`, `MessengerAppService` ve dosya yöneticisi servisi yalnız oturum ister (`[Authorize]`); `App.Hr.Intranet.*` yetkilerini sunucuda denetlemez. Pano kutularının yetkisi (`PermissionName`) sunucuda süzülür, doküman yetkileri ise **yalnız arayüzde** uygulanır. --- ## 7. Entegrasyonlar | Kaynak | Kullanım | | --- | --- | | `AbpUsers` (+ departman, pozisyon) | Doğum günleri, yazar/kullanıcı kartları, mesajlaşma rehberi | | Dosya yöneticisi / CDN (`intranet`, `intranet/_passive`) | Doküman kütüphanesi ve pano doküman kutusu | | Developer Kit › Custom Components | Custom pano kutuları | | SignalR (`/messengerhub`) | Mesajlaşma ve çevrimiçi durumu | | Organizasyon Şeması | Kullanıcı satırlarında sosyal duvarın `UserProfileCard` bileşenini kullanır | --- ## 8. Akış örneği 1. İç iletişim **Duyurular**'a "Yeni ofis açılışı"nı görsel ve HTML içerikle ekler, **sabitler** → panonun sağ kolonunda görünür. 2. **Anketler**'de "Çalışan Memnuniyet Anketi"ni anonim ve aktif açar; **Sorular** sekmesine puanlama, çoktan seçmeli (seçenekleriyle) ve metin soruları ekler. 3. Çalışan panoda anketi doldurur, sonradan yanıtını günceller; İK **Yanıtlar** sekmesinden sonuçları görür (anonimde kişi boş). 4. **Etkinlikler**'de "Jazz Akşamı" tarih, yer ve fotoğraflarla yayınlanır → "Yaklaşan Etkinlikler" kutusunda çıkar; çalışanlar beğenir/yorumlar. 5. Çalışan sosyal duvarda iki seçenekli bir anket paylaşır; diğerleri oy verir. 6. Doküman sorumlusu "İzin Prosedürü.pdf"i yükler ve yayına alır → pano doküman kutusunda indirilebilir olur. 7. Sistem yöneticisi Intranet Widgets'a bir custom component'i (ör. kurum KPI kartı) orta kolona ekler. --- ## 9. Sık sorulanlar ve bilinen sınırlar **Duyuru panoda görünmüyor.** Kutu yalnız sabitlenmiş duyuruları (en fazla 3) gösterir; listelenmek için **Sabitle** işaretli olmalı. **Süresi dolmuş duyuru/anket hâlâ görünüyor.** Sunucuda son tarih süzmesi yoktur; duyuru sabitlemesi kaldırılmalı, anket `passive` yapılmalıdır. **Pano yerleşimim başka bilgisayarda yok.** Yerleşim tarayıcıda saklanır. **Pano kutusu görünmüyor.** Kayıt aktif olmalı ve kullanıcıda `PermissionName` yetkisi bulunmalı; Custom kutuda bileşen aktif olmalı. **Yanıtlarımı değiştirebilir miyim?** Evet; anketi tekrar açıp kaydetmek önceki yanıtı günceller. Kontrol edilmeli (koddan tespit edilenler): - Ankete oy sunucuda kullanıcı bazında tutulmaz (`PollUserVoteId` tek kolon); aynı kullanıcı API'yi doğrudan çağırarak tekrar oy verebilir. - `SocialPost.IsLiked` beğenen son kullanıcıya göre veritabanına yazılır; listelerken sunucu kullanıcıya göre yeniden hesaplar. - Duyuru modalındaki ekler bölümü dizi bekler, `Attachments` metindir; ekler görünmeyebilir. - Anket entity açıklaması `draft|active|closed` der, ekran `active|passive` sunar. - Sosyal paylaşımda yüklenen medya base64 olarak veritabanına yazılır; büyük dosyalar tabloyu büyütür. - `Hr_T_EventPhoto` tablosu ve `sql/object/Hr_T_EventPhoto.sql` yoktur (referans dokümanda geçer); etkinlik fotoğrafları `Hr_T_Event.Photos` kolonundadır. --- ## 10. Dosyalar | Dosya | İçerik | | --- | --- | | `api/src/Sozsoft.Platform.DbMigrator/Migrations/ListFormSeeder_Hr.cs` | Yönetim ekranları | | `api/src/Sozsoft.Platform.DbMigrator/Migrations/ListFormSeeder_Saas.cs` | Intranet Widgets ekranı | | `api/src/Sozsoft.Platform.Domain/Entities/Tenant/Hr/Intranet/*.cs`, `Entities/Tenant/Administration/IntranetWidget.cs`, `Entities/Tenant/Messenger*.cs` | Entity'ler | | `api/src/Sozsoft.Platform.Application/Intranet/IntranetAppService.cs`, `Messenger/MessengerAppService.cs` | Servisler | | `ui/src/views/intranet/Dashboard.tsx`, `widgets/*`, `SocialWall/*`, `documents/IntranetDocuments.tsx` | Pano, kutular, sosyal duvar, doküman sayfası | | `ui/src/components/template/MessengerWidget.tsx` | Mesajlaşma penceresi | | `configs/seeds/host/data/App.Hr.Intranet.*.json`, `App.DeveloperKit.IntranetWidgets.json` | Örnek veri ve pano kutuları | Örnek veri: - 5 duyuru (3'ü sabitlenmiş). - 3 anket, 10 soru ve 13 seçenek. - 6 paylaşım: 4 medya (2 resim, 1 video, 1 anket), 8 yorum. - 50 etkinlik türü, 5 kategori, 3 etkinlik ve 9 yorum.