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>
547 lines
16 KiB
Markdown
547 lines
16 KiB
Markdown
# 📅 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
|
|
- ✅ 使用者測試
|
|
|
|
---
|
|
|
|
**這套個人化功能將大幅提升員工的工作效率!** 🎯
|