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:
2026-02-23 20:12:43 +08:00
commit 360533393f
386 changed files with 70353 additions and 0 deletions

108
scripts/run-auto-setup.ps1 Normal file
View File

@@ -0,0 +1,108 @@
# Auto run database setup with password
$ErrorActionPreference = "Stop"
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " HR Portal Database Auto Setup" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
$REMOTE_HOST = "10.1.0.254"
$REMOTE_USER = "ubuntu"
$PASSWORD = "DC1qaz2wsx"
$LOCAL_SCRIPT = "W:\DevOps-Workspace\hr-portal\scripts\auto-setup.sh"
# Step 1: Upload script using plink (PuTTY)
Write-Host "[1/3] Uploading setup script..." -ForegroundColor Yellow
# Create expect-like script for SSH
$uploadCommand = @"
`$password = '$PASSWORD'
`$process = Start-Process plink -ArgumentList "-ssh $REMOTE_USER@$REMOTE_HOST -pw `$password 'cat > /tmp/auto-setup.sh'" -NoNewWindow -Wait -RedirectStandardInput '$LOCAL_SCRIPT' -PassThru
"@
# Fallback: Try with cmd echo
Write-Host " Trying direct SSH connection..." -ForegroundColor Gray
# Create a temporary script with password
$tempScript = @"
#!/usr/bin/expect -f
set timeout 60
spawn scp $LOCAL_SCRIPT ${REMOTE_USER}@${REMOTE_HOST}:/tmp/auto-setup.sh
expect "password:"
send "${PASSWORD}\r"
expect eof
"@
# Write temp script
$tempScriptPath = "$env:TEMP\upload-script.exp"
$tempScript | Out-File -FilePath $tempScriptPath -Encoding ASCII
# Try using WSL if available
$wslAvailable = Get-Command wsl -ErrorAction SilentlyContinue
if ($wslAvailable) {
Write-Host " Using WSL for transfer..." -ForegroundColor Gray
# Copy file to WSL
$wslTempPath = "/tmp/auto-setup.sh"
wsl cp "$LOCAL_SCRIPT" $wslTempPath
# Use sshpass in WSL
$result = wsl bash -c "sshpass -p '$PASSWORD' scp /tmp/auto-setup.sh ${REMOTE_USER}@${REMOTE_HOST}:/tmp/"
if ($LASTEXITCODE -eq 0) {
Write-Host " [OK] Script uploaded" -ForegroundColor Green
} else {
Write-Host " [FAIL] Upload failed" -ForegroundColor Red
exit 1
}
} else {
# Manual method
Write-Host ""
Write-Host " WSL not available. Please manually upload the script:" -ForegroundColor Yellow
Write-Host " 1. Open WinSCP or FileZilla" -ForegroundColor White
Write-Host " 2. Connect to: ubuntu@10.1.0.254 (password: DC1qaz2wsx)" -ForegroundColor White
Write-Host " 3. Upload: W:\DevOps-Workspace\hr-portal\scripts\auto-setup.sh" -ForegroundColor White
Write-Host " 4. To: /tmp/auto-setup.sh" -ForegroundColor White
Write-Host ""
Read-Host "Press Enter after upload completes"
}
Write-Host ""
# Step 2: Make executable and run
Write-Host "[2/3] Executing setup on remote server..." -ForegroundColor Yellow
if ($wslAvailable) {
$executeCommands = @"
chmod +x /tmp/auto-setup.sh
bash /tmp/auto-setup.sh
"@
$result = wsl bash -c "sshpass -p '$PASSWORD' ssh -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} '$executeCommands'"
Write-Host $result
if ($LASTEXITCODE -eq 0) {
Write-Host ""
Write-Host " [OK] Setup completed!" -ForegroundColor Green
} else {
Write-Host " [WARNING] Check output above for any errors" -ForegroundColor Yellow
}
} else {
Write-Host " Please run these commands on Ubuntu Server:" -ForegroundColor Yellow
Write-Host " chmod +x /tmp/auto-setup.sh" -ForegroundColor White
Write-Host " bash /tmp/auto-setup.sh" -ForegroundColor White
Write-Host ""
}
Write-Host ""
Write-Host "[3/3] Database connection info:" -ForegroundColor Yellow
Write-Host ""
Write-Host " CONNECTION STRING:" -ForegroundColor Cyan
Write-Host " postgresql://hr_user:DC1qaz2wsx@10.1.0.254:5432/hr_portal" -ForegroundColor White
Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " Next: Update backend/.env file" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""