Files
hr-portal/backend/check_tenant_status.py
Porsche Chen 360533393f 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>
2026-02-23 20:12:43 +08:00

52 lines
1.1 KiB
Python

"""
檢查租戶初始化狀態
"""
import psycopg2
conn = psycopg2.connect(
host="10.1.0.20",
port=5433,
database="hr_portal",
user="admin",
password="DC1qaz2wsx"
)
cur = conn.cursor()
# 查詢租戶狀態
cur.execute("""
SELECT id, code, name, is_initialized, initialized_at, initialized_by, status
FROM tenants
ORDER BY id;
""")
tenants = cur.fetchall()
print("=== Tenants Status ===\n")
for t in tenants:
print(f"ID: {t[0]}")
print(f"Code: {t[1]}")
print(f"Name: {t[2]}")
print(f"Is Initialized: {t[3]}")
print(f"Initialized At: {t[4]}")
print(f"Initialized By: {t[5]}")
print(f"Status: {t[6]}")
print("-" * 50)
# 查詢系統狀態
cur.execute("""
SELECT current_phase, initialization_completed, is_locked
FROM installation_system_status
WHERE id = 1;
""")
sys_status = cur.fetchone()
if sys_status:
print("\n=== System Status ===\n")
print(f"Current Phase: {sys_status[0]}")
print(f"Initialization Completed: {sys_status[1]}")
print(f"Is Locked: {sys_status[2]}")
cur.close()
conn.close()