sozsoft-platform/configs/seeds/host/docs/modules/HrIntranet.md
2026-10-04 18:04:16 +03:00

216 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# İ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) |
| `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`). 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<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.