feat: HR Portal - Complete Multi-Tenant System with Redis Session Storage
Major Features: - ✅ Multi-tenant architecture (tenant isolation) - ✅ Employee CRUD with lifecycle management (onboarding/offboarding) - ✅ Department tree structure with email domain management - ✅ Company info management (single-record editing) - ✅ System functions CRUD (permission management) - ✅ Email account management (multi-account per employee) - ✅ Keycloak SSO integration (auth.lab.taipei) - ✅ Redis session storage (10.1.0.254:6379) - Solves Cookie 4KB limitation - Cross-system session sharing - Sliding expiration (8 hours) - Automatic token refresh Technical Stack: Backend: - FastAPI + SQLAlchemy - PostgreSQL 16 (10.1.0.20:5433) - Keycloak Admin API integration - Docker Mailserver integration (SSH) - Alembic migrations Frontend: - Next.js 14 (App Router) - NextAuth 4 with Keycloak Provider - Redis session storage (ioredis) - Tailwind CSS Infrastructure: - Redis 7 (10.1.0.254:6379) - Session + Cache - Keycloak 26.1.0 (auth.lab.taipei) - Docker Mailserver (10.1.0.254) Architecture Highlights: - Session管理由 Keycloak + Redis 統一控制 - 支援多系統 (HR/WebMail/Calendar/Drive/Office) 共享 session - Token 自動刷新,異質服務整合 - 未來可無縫遷移到雲端 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
546
PERSONAL-FEATURES.md
Normal file
546
PERSONAL-FEATURES.md
Normal file
@@ -0,0 +1,546 @@
|
||||
# 📅 HR Portal - 個人化功能設計
|
||||
|
||||
## 🎯 功能概述
|
||||
|
||||
為每位員工提供個人化的工作協作工具:
|
||||
- 📅 **個人行事曆** - 類似 Google Calendar
|
||||
- 🎥 **雲端會議室** - 線上視訊會議
|
||||
- 📝 **待辦事項** - 任務管理
|
||||
- 📊 **個人儀表板** - 資訊總覽
|
||||
|
||||
---
|
||||
|
||||
## 📅 行事曆功能 (Calendar)
|
||||
|
||||
### 核心功能
|
||||
|
||||
#### 1. 個人行事曆
|
||||
- 日/週/月視圖
|
||||
- 建立事件/會議
|
||||
- 設定提醒通知
|
||||
- 重複事件設定
|
||||
- 事件分類 (工作、個人、會議等)
|
||||
|
||||
#### 2. 團隊行事曆
|
||||
- 查看部門同事的行程
|
||||
- 找出共同空檔
|
||||
- 預約會議室
|
||||
- 會議邀請與回覆
|
||||
|
||||
#### 3. 整合功能
|
||||
- **Google Calendar 同步** (雙向)
|
||||
- **Outlook Calendar 同步** (可選)
|
||||
- **iCal 匯出/匯入**
|
||||
- **郵件提醒**
|
||||
- **手機 App 推送**
|
||||
|
||||
---
|
||||
|
||||
## 🎥 雲端會議室功能
|
||||
|
||||
### 方案選擇
|
||||
|
||||
#### 方案 A: Jitsi Meet (開源,自架) ⭐ 推薦
|
||||
|
||||
**優點**:
|
||||
- ✅ 完全免費開源
|
||||
- ✅ 可自行部署在您的伺服器
|
||||
- ✅ 無時間限制
|
||||
- ✅ 支援錄影、螢幕分享
|
||||
- ✅ 可整合到 HR Portal
|
||||
|
||||
**部署方式**:
|
||||
```yaml
|
||||
# Docker Compose
|
||||
services:
|
||||
jitsi:
|
||||
image: jitsi/jitsi-meet
|
||||
ports:
|
||||
- "8443:443"
|
||||
environment:
|
||||
- ENABLE_AUTH=1
|
||||
- ENABLE_GUESTS=0
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.jitsi.rule=Host(`meet.porscheworld.tw`)"
|
||||
```
|
||||
|
||||
**網址**: https://meet.porscheworld.tw
|
||||
|
||||
#### 方案 B: BigBlueButton (教育/企業級)
|
||||
|
||||
**優點**:
|
||||
- ✅ 功能更完整 (白板、投票、分組討論)
|
||||
- ✅ 錄影自動轉檔
|
||||
- ✅ 學習曲線低
|
||||
|
||||
**缺點**:
|
||||
- ⚠️ 資源需求較高
|
||||
- ⚠️ 設定較複雜
|
||||
|
||||
#### 方案 C: 整合第三方服務
|
||||
|
||||
- **Zoom API** - 需要付費帳號
|
||||
- **Google Meet** - 需要 Google Workspace
|
||||
- **Microsoft Teams** - 需要 Microsoft 365
|
||||
|
||||
---
|
||||
|
||||
## 🗄️ 資料庫擴充設計
|
||||
|
||||
### 1. 行事曆事件表 (calendar_events)
|
||||
|
||||
```sql
|
||||
CREATE TABLE calendar_events (
|
||||
id SERIAL PRIMARY KEY,
|
||||
employee_id INTEGER REFERENCES employees(id) ON DELETE CASCADE,
|
||||
|
||||
-- 事件資訊
|
||||
title VARCHAR(200) NOT NULL,
|
||||
description TEXT,
|
||||
location VARCHAR(200),
|
||||
|
||||
-- 時間
|
||||
start_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
end_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
all_day BOOLEAN DEFAULT FALSE,
|
||||
|
||||
-- 重複設定
|
||||
is_recurring BOOLEAN DEFAULT FALSE,
|
||||
recurrence_rule VARCHAR(200), -- RRULE format (iCal standard)
|
||||
recurrence_end_date DATE,
|
||||
|
||||
-- 分類
|
||||
category VARCHAR(50) DEFAULT 'work', -- work, personal, meeting, holiday
|
||||
color VARCHAR(20) DEFAULT '#3788d8',
|
||||
|
||||
-- 提醒
|
||||
reminder_minutes INTEGER, -- 提前幾分鐘提醒 (15, 30, 60, 1440)
|
||||
|
||||
-- 會議相關
|
||||
is_meeting BOOLEAN DEFAULT FALSE,
|
||||
meeting_room_id INTEGER REFERENCES meeting_rooms(id),
|
||||
online_meeting_url VARCHAR(500),
|
||||
|
||||
-- 狀態
|
||||
status VARCHAR(20) DEFAULT 'confirmed', -- confirmed, tentative, cancelled
|
||||
|
||||
-- 同步
|
||||
google_event_id VARCHAR(200), -- Google Calendar Event ID
|
||||
outlook_event_id VARCHAR(200),
|
||||
last_synced_at TIMESTAMP,
|
||||
|
||||
-- 審計
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_calendar_events_employee ON calendar_events(employee_id);
|
||||
CREATE INDEX idx_calendar_events_time ON calendar_events(start_time, end_time);
|
||||
CREATE INDEX idx_calendar_events_category ON calendar_events(category);
|
||||
```
|
||||
|
||||
### 2. 事件參與者表 (event_attendees)
|
||||
|
||||
```sql
|
||||
CREATE TABLE event_attendees (
|
||||
id SERIAL PRIMARY KEY,
|
||||
event_id INTEGER REFERENCES calendar_events(id) ON DELETE CASCADE,
|
||||
employee_id INTEGER REFERENCES employees(id) ON DELETE CASCADE,
|
||||
|
||||
-- 回覆狀態
|
||||
status VARCHAR(20) DEFAULT 'pending', -- pending, accepted, declined, tentative
|
||||
|
||||
-- 角色
|
||||
role VARCHAR(20) DEFAULT 'attendee', -- organizer, attendee, optional
|
||||
|
||||
-- 是否必須
|
||||
is_required BOOLEAN DEFAULT TRUE,
|
||||
|
||||
-- 回覆時間
|
||||
responded_at TIMESTAMP,
|
||||
|
||||
-- 備註
|
||||
comment TEXT,
|
||||
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
UNIQUE(event_id, employee_id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_event_attendees_event ON event_attendees(event_id);
|
||||
CREATE INDEX idx_event_attendees_employee ON event_attendees(employee_id);
|
||||
```
|
||||
|
||||
### 3. 會議室表 (meeting_rooms)
|
||||
|
||||
```sql
|
||||
CREATE TABLE meeting_rooms (
|
||||
id SERIAL PRIMARY KEY,
|
||||
|
||||
-- 會議室資訊
|
||||
name VARCHAR(100) NOT NULL,
|
||||
location VARCHAR(200),
|
||||
capacity INTEGER,
|
||||
|
||||
-- 設備
|
||||
has_projector BOOLEAN DEFAULT FALSE,
|
||||
has_whiteboard BOOLEAN DEFAULT FALSE,
|
||||
has_video_conference BOOLEAN DEFAULT FALSE,
|
||||
equipment TEXT, -- JSON array
|
||||
|
||||
-- 線上會議室
|
||||
is_virtual BOOLEAN DEFAULT FALSE,
|
||||
jitsi_room_name VARCHAR(100), -- Jitsi 專用房間名
|
||||
permanent_meeting_url VARCHAR(500),
|
||||
|
||||
-- 狀態
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
|
||||
-- 預約設定
|
||||
allow_booking BOOLEAN DEFAULT TRUE,
|
||||
booking_advance_days INTEGER DEFAULT 30, -- 可提前多少天預約
|
||||
min_booking_duration INTEGER DEFAULT 30, -- 最小預約時間(分鐘)
|
||||
max_booking_duration INTEGER DEFAULT 480, -- 最大預約時間(分鐘)
|
||||
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- 初始資料
|
||||
INSERT INTO meeting_rooms (name, location, capacity, is_virtual, has_video_conference) VALUES
|
||||
('實體會議室 A', '辦公室 3F', 10, FALSE, TRUE),
|
||||
('實體會議室 B', '辦公室 5F', 6, FALSE, TRUE),
|
||||
('線上會議室 1', NULL, 50, TRUE, TRUE),
|
||||
('線上會議室 2', NULL, 50, TRUE, TRUE),
|
||||
('線上會議室 3', NULL, 50, TRUE, TRUE);
|
||||
```
|
||||
|
||||
### 4. 待辦事項表 (todos)
|
||||
|
||||
```sql
|
||||
CREATE TABLE todos (
|
||||
id SERIAL PRIMARY KEY,
|
||||
employee_id INTEGER REFERENCES employees(id) ON DELETE CASCADE,
|
||||
|
||||
-- 任務資訊
|
||||
title VARCHAR(200) NOT NULL,
|
||||
description TEXT,
|
||||
|
||||
-- 優先級
|
||||
priority VARCHAR(20) DEFAULT 'medium', -- low, medium, high, urgent
|
||||
|
||||
-- 時間
|
||||
due_date DATE,
|
||||
due_time TIME,
|
||||
|
||||
-- 狀態
|
||||
status VARCHAR(20) DEFAULT 'pending', -- pending, in-progress, completed, cancelled
|
||||
completed_at TIMESTAMP,
|
||||
|
||||
-- 分類
|
||||
category VARCHAR(50),
|
||||
tags TEXT[], -- PostgreSQL array
|
||||
|
||||
-- 關聯
|
||||
related_project_id INTEGER REFERENCES projects(id),
|
||||
related_event_id INTEGER REFERENCES calendar_events(id),
|
||||
|
||||
-- 排序
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_todos_employee ON todos(employee_id);
|
||||
CREATE INDEX idx_todos_status ON todos(status);
|
||||
CREATE INDEX idx_todos_due_date ON todos(due_date);
|
||||
```
|
||||
|
||||
### 5. 通知表 (notifications)
|
||||
|
||||
```sql
|
||||
CREATE TABLE notifications (
|
||||
id SERIAL PRIMARY KEY,
|
||||
employee_id INTEGER REFERENCES employees(id) ON DELETE CASCADE,
|
||||
|
||||
-- 通知內容
|
||||
title VARCHAR(200) NOT NULL,
|
||||
message TEXT,
|
||||
|
||||
-- 類型
|
||||
type VARCHAR(50) NOT NULL, -- calendar, meeting, todo, system, announcement
|
||||
|
||||
-- 關聯資源
|
||||
related_type VARCHAR(50), -- event, todo, project, employee
|
||||
related_id INTEGER,
|
||||
|
||||
-- 優先級
|
||||
priority VARCHAR(20) DEFAULT 'normal', -- low, normal, high
|
||||
|
||||
-- 狀態
|
||||
is_read BOOLEAN DEFAULT FALSE,
|
||||
read_at TIMESTAMP,
|
||||
|
||||
-- 動作連結
|
||||
action_url VARCHAR(500),
|
||||
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_notifications_employee ON notifications(employee_id);
|
||||
CREATE INDEX idx_notifications_read ON notifications(is_read);
|
||||
CREATE INDEX idx_notifications_created ON notifications(created_at DESC);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API 端點設計
|
||||
|
||||
### 行事曆 API
|
||||
|
||||
```
|
||||
GET /api/v1/calendar/events - 列出事件 (支援日期範圍過濾)
|
||||
GET /api/v1/calendar/events/:id - 取得事件詳情
|
||||
POST /api/v1/calendar/events - 建立事件
|
||||
PUT /api/v1/calendar/events/:id - 更新事件
|
||||
DELETE /api/v1/calendar/events/:id - 刪除事件
|
||||
|
||||
GET /api/v1/calendar/events/month/:year/:month - 取得月曆
|
||||
GET /api/v1/calendar/events/week/:date - 取得週曆
|
||||
GET /api/v1/calendar/events/day/:date - 取得日曆
|
||||
|
||||
POST /api/v1/calendar/events/:id/invite - 邀請參與者
|
||||
PUT /api/v1/calendar/events/:id/respond - 回覆邀請 (accept/decline/tentative)
|
||||
|
||||
GET /api/v1/calendar/free-busy - 查詢空閒時段
|
||||
POST /api/v1/calendar/find-common-slot - 尋找共同空檔
|
||||
|
||||
POST /api/v1/calendar/sync/google - 同步 Google Calendar
|
||||
GET /api/v1/calendar/export/ical - 匯出 iCal
|
||||
```
|
||||
|
||||
### 會議室 API
|
||||
|
||||
```
|
||||
GET /api/v1/meeting-rooms - 列出會議室
|
||||
GET /api/v1/meeting-rooms/:id - 取得會議室詳情
|
||||
POST /api/v1/meeting-rooms - 創建會議室 (管理員)
|
||||
PUT /api/v1/meeting-rooms/:id - 更新會議室
|
||||
DELETE /api/v1/meeting-rooms/:id - 刪除會議室
|
||||
|
||||
GET /api/v1/meeting-rooms/:id/availability - 查詢可用時段
|
||||
POST /api/v1/meeting-rooms/:id/book - 預約會議室
|
||||
|
||||
POST /api/v1/meetings/create-instant - 建立即時會議
|
||||
POST /api/v1/meetings/create-scheduled - 建立預定會議
|
||||
GET /api/v1/meetings/:id/join-url - 取得會議加入連結
|
||||
DELETE /api/v1/meetings/:id - 取消會議
|
||||
```
|
||||
|
||||
### 待辦事項 API
|
||||
|
||||
```
|
||||
GET /api/v1/todos - 列出待辦事項
|
||||
GET /api/v1/todos/:id - 取得待辦詳情
|
||||
POST /api/v1/todos - 建立待辦
|
||||
PUT /api/v1/todos/:id - 更新待辦
|
||||
DELETE /api/v1/todos/:id - 刪除待辦
|
||||
|
||||
PUT /api/v1/todos/:id/complete - 標記完成
|
||||
PUT /api/v1/todos/:id/reorder - 重新排序
|
||||
|
||||
GET /api/v1/todos/today - 今日待辦
|
||||
GET /api/v1/todos/overdue - 逾期待辦
|
||||
GET /api/v1/todos/upcoming - 即將到期
|
||||
```
|
||||
|
||||
### 通知 API
|
||||
|
||||
```
|
||||
GET /api/v1/notifications - 列出通知
|
||||
GET /api/v1/notifications/unread - 未讀通知
|
||||
PUT /api/v1/notifications/:id/read - 標記已讀
|
||||
PUT /api/v1/notifications/mark-all-read - 全部標記已讀
|
||||
DELETE /api/v1/notifications/:id - 刪除通知
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 前端介面設計
|
||||
|
||||
### 1. 個人儀表板
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ 👋 早安, Alice! 🔔 (3) │
|
||||
├─────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ 📅 今日行程 📝 待辦事項 │
|
||||
│ ┌──────────────────┐ ┌──────────────┐│
|
||||
│ │ 09:00 - 10:00 │ │ ☐ 完成報告 ││
|
||||
│ │ 部門週會 │ │ ☐ 回覆郵件 ││
|
||||
│ │ 📍 會議室 A │ │ ☑ 審核文件 ││
|
||||
│ ├──────────────────┤ └──────────────┘│
|
||||
│ │ 14:00 - 15:00 │ │
|
||||
│ │ 客戶簡報 │ 🎥 快速會議 │
|
||||
│ │ 🎥 線上會議 │ ┌──────────────┐ │
|
||||
│ └──────────────────┘ │ [建立會議室] │ │
|
||||
│ └──────────────┘ │
|
||||
│ 💾 儲存空間 📧 郵箱狀態 │
|
||||
│ ████████░░ 8.2/10GB ████░░░░░░ 0.5/1GB │
|
||||
│ │
|
||||
│ 🔐 我的系統權限 │
|
||||
│ • Gitea • Webmail • HR Portal │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 2. 行事曆頁面 (月視圖)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ 📅 2026年2月 [日 週 月] [今天]│
|
||||
├─────────────────────────────────────────────────┤
|
||||
│ 日 一 二 三 四 五 六 │
|
||||
│ 1 2 │
|
||||
│ 3 4 5 6 7 8 9 │
|
||||
│ ●會議 │
|
||||
│ 10 11 12 13 14 15 16 │
|
||||
│ ●●出差 │
|
||||
│ 17 18 19 20 21 22 23 │
|
||||
│ ●簡報 │
|
||||
│ 24 25 26 27 28 │
|
||||
│ │
|
||||
│ [+ 新增事件] [同步Google Calendar] │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3. 建立會議室對話框
|
||||
|
||||
```
|
||||
┌──────────────────────────────────┐
|
||||
│ 🎥 建立線上會議 │
|
||||
├──────────────────────────────────┤
|
||||
│ │
|
||||
│ 會議主題: ________________ │
|
||||
│ │
|
||||
│ 日期時間: [2026-02-08] [14:00] │
|
||||
│ │
|
||||
│ 時長: [1小時 ▼] │
|
||||
│ │
|
||||
│ 會議室: ○ 自動分配 │
|
||||
│ ○ 指定: [會議室1 ▼] │
|
||||
│ │
|
||||
│ 參與者: [搜尋員工...] │
|
||||
│ • Alice Wang │
|
||||
│ • Bob Chen │
|
||||
│ │
|
||||
│ ☑ 同步到行事曆 │
|
||||
│ ☑ 發送郵件通知 │
|
||||
│ │
|
||||
│ [取消] [建立會議] │
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 整合流程
|
||||
|
||||
### Google Calendar 同步流程
|
||||
|
||||
```
|
||||
HR Portal Google Calendar API
|
||||
│ │
|
||||
│ 1. 授權請求 │
|
||||
├─────────────────────────>│
|
||||
│ │
|
||||
│ 2. OAuth Token │
|
||||
│<─────────────────────────┤
|
||||
│ │
|
||||
│ 3. 同步事件 │
|
||||
├─────────────────────────>│
|
||||
│ │
|
||||
│ 4. 雙向同步 │
|
||||
│<────────────────────────>│
|
||||
```
|
||||
|
||||
### 會議室預約流程
|
||||
|
||||
```
|
||||
用戶建立會議
|
||||
↓
|
||||
選擇會議室/線上會議
|
||||
↓
|
||||
檢查可用性
|
||||
↓
|
||||
建立 Jitsi 會議室
|
||||
↓
|
||||
生成會議連結
|
||||
↓
|
||||
發送邀請給參與者
|
||||
↓
|
||||
加入行事曆
|
||||
↓
|
||||
發送郵件提醒
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📱 移動端支援
|
||||
|
||||
### Progressive Web App (PWA)
|
||||
|
||||
- 安裝到手機主畫面
|
||||
- 離線查看行事曆
|
||||
- 推送通知 (會議提醒)
|
||||
- 快速建立待辦事項
|
||||
|
||||
---
|
||||
|
||||
## 🔔 通知機制
|
||||
|
||||
### 通知類型
|
||||
|
||||
1. **會議提醒**
|
||||
- 會議前 15 分鐘提醒
|
||||
- 桌面通知 + 郵件
|
||||
|
||||
2. **待辦到期**
|
||||
- 截止日前 1 天提醒
|
||||
- 當日上午 9 點提醒
|
||||
|
||||
3. **會議邀請**
|
||||
- 即時通知
|
||||
- 郵件通知
|
||||
|
||||
4. **系統公告**
|
||||
- 重要訊息推送
|
||||
|
||||
---
|
||||
|
||||
## 🚀 實施計劃
|
||||
|
||||
### Phase 1: 基礎功能 (2 週)
|
||||
- ✅ 資料庫 Schema
|
||||
- ✅ 行事曆 CRUD API
|
||||
- ✅ 基本前端介面
|
||||
|
||||
### Phase 2: 會議室整合 (1 週)
|
||||
- ✅ Jitsi Meet 部署
|
||||
- ✅ 會議室預約 API
|
||||
- ✅ 會議連結生成
|
||||
|
||||
### Phase 3: 進階功能 (2 週)
|
||||
- ✅ Google Calendar 同步
|
||||
- ✅ 待辦事項管理
|
||||
- ✅ 通知系統
|
||||
|
||||
### Phase 4: 優化 (1 週)
|
||||
- ✅ 效能優化
|
||||
- ✅ 移動端 PWA
|
||||
- ✅ 使用者測試
|
||||
|
||||
---
|
||||
|
||||
**這套個人化功能將大幅提升員工的工作效率!** 🎯
|
||||
Reference in New Issue
Block a user