sozsoft-platform/configs/seeds/host/docs/modules/HrIntranet.md

219 lines
16 KiB
Markdown
Raw Normal View History

2026-10-04 15:04:16 +00:00
# İ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 10)
| Sıra | Menü | `ListFormCode` / rota | Alt formlar | Widget'lar |
| --- | --- | --- | --- | --- |
| 1 | Duyurular | `App.Hr.Intranet.Announcement` | `…Announcement.AnnouncementLike`, `…Announcement.AnnouncementComment` (`Id → AnnouncementId`) | Aktif · Sabitlenmiş · Süresi dolan · Toplam görüntülenme |
| 2 | Anketler | `App.Hr.Intranet.Survey` | `SurveyQuestion` (→ `SurveyQuestionOption`), `SurveyResponse` (→ `SurveyAnswer`) — iki seviyeli | Aktif · Pasif · Toplam yanıt |
| 3 | Sosyal Paylaşımlar | `App.Hr.Intranet.SocialPost` | `SocialComment`, `SocialMedia` (→ `SocialPollOption`), `SocialLike` (`Id → SocialPostId`) | Toplam · Bugün · Toplam beğeni |
| 4 | Etkinlik Türleri | `App.Hr.Intranet.Events.EventType` | — | — |
| 5 | Etkinlik Kategorisi | `App.Hr.Intranet.Events.EventCategory` | — | — |
| 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) |
2026-10-04 19:17:16 +00:00
| `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 |
2026-10-04 15:04:16 +00:00
| `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 |
2026-10-04 19:17:16 +00:00
İlk altı kutu Builtin'dir (koddaki `Code`). `my-leave` / `team-leave` İzin Yönetimi'nin (`HrLeave.md` §3.3), son üçü Performans Yönetimi'nin çalışana ait özetleridir:
2026-10-04 15:04:16 +00:00
İ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<Guid>, 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.