# Virtual MIS - 開發規範 **版本**: v1.0 **日期**: 2026-02-27 --- ## 專案結構 ``` virtual-mis/ ├── backend/ # 後端服務 │ ├── app/ │ │ ├── api/ # API 路由 │ │ │ ├── v1/ │ │ │ │ ├── tenant_onboarding.py │ │ │ │ ├── service_integration.py │ │ │ │ └── billing.py │ │ │ └── router.py │ │ ├── core/ # 核心配置 │ │ │ ├── config.py │ │ │ ├── security.py │ │ │ └── dependencies.py │ │ ├── db/ # 資料庫 │ │ │ ├── base.py │ │ │ └── session.py │ │ ├── models/ # ORM 模型 │ │ ├── schemas/ # Pydantic Schema │ │ ├── services/ # 業務邏輯 │ │ └── utils/ # 工具函數 │ ├── alembic/ # 資料庫遷移 │ ├── tests/ # 測試 │ ├── .env # 環境變數 │ ├── requirements.txt # 依賴套件 │ └── main.py # 應用入口 │ ├── frontend/ # 前端服務 │ ├── admin-portal/ # 管理後台 │ │ ├── app/ # Next.js App Router │ │ ├── components/ # React 元件 │ │ ├── lib/ # 工具函數 │ │ ├── public/ # 靜態資源 │ │ └── package.json │ │ │ └── landing-page/ # 行銷頁面 │ ├── app/ │ ├── components/ │ └── package.json │ └── docs/ # 文件 ├── architecture/ # 架構設計 ├── api-specs/ # API 規格 ├── business/ # 商業計畫 └── deployment/ # 部署文件 ``` ## 開發環境 ### 後端環境 **Python 版本**: 3.11+ **Port 配置**: - 開發環境: `10281` - 測試環境: `10282` **資料庫**: - Host: `10.1.0.20` - Port: `5433` - Database: `virtual_mis` - User: `admin` **啟動方式**: ```bash cd D:\_Develop\porscheworld_develop\virtual-mis\backend START_BACKEND.bat ``` ### 前端環境 **Node.js 版本**: 20+ **Port 配置**: - Admin Portal: `10280` - Landing Page: `10290` **啟動方式**: ```bash cd D:\_Develop\porscheworld_develop\virtual-mis\frontend\admin-portal START_FRONTEND.bat ``` ## 編碼規範 ### Python (後端) 1. **命名規範**: - 檔案名稱: `snake_case.py` - 類別名稱: `PascalCase` - 函數名稱: `snake_case` - 常數: `UPPER_CASE` 2. **程式碼風格**: - 使用 Black 格式化 - 遵循 PEP 8 - 最大行長: 100 字元 3. **型別標註**: ```python def get_tenant(tenant_id: int) -> Optional[Tenant]: """取得租戶資料""" pass ``` 4. **文件字串**: ```python def create_tenant(data: TenantCreate) -> Tenant: """ 建立新租戶 Args: data: 租戶建立資料 Returns: Tenant: 建立的租戶物件 Raises: ValueError: 租戶代碼已存在 """ pass ``` ### TypeScript (前端) 1. **命名規範**: - 檔案名稱: `kebab-case.tsx` - 元件名稱: `PascalCase` - 函數名稱: `camelCase` - 介面: `PascalCase` (前綴 I 可選) 2. **元件結構**: ```typescript 'use client' import { useState } from 'react' interface Props { title: string onSubmit: (data: FormData) => void } export default function MyComponent({ title, onSubmit }: Props) { const [loading, setLoading] = useState(false) return (

{title}

) } ``` 3. **型別定義**: ```typescript // types/tenant.ts export interface Tenant { id: number code: string name: string status: 'trial' | 'active' | 'suspended' } ``` ## API 設計規範 ### RESTful 規範 **URL 命名**: - 使用名詞複數: `/api/v1/tenants` - 使用 kebab-case: `/api/v1/tenant-onboarding` - 版本控制: `/api/v1/`, `/api/v2/` **HTTP 方法**: - `GET`: 查詢資料 - `POST`: 建立資料 - `PUT`: 完整更新 - `PATCH`: 部分更新 - `DELETE`: 刪除資料 **回應格式**: ```json { "success": true, "data": { "id": 1, "name": "測試公司" }, "message": "操作成功" } ``` **錯誤回應**: ```json { "success": false, "error": { "code": "TENANT_NOT_FOUND", "message": "找不到指定的租戶", "details": {} } } ``` ### Schema 設計 **命名規範**: - Base Schema: `TenantBase` - Create Schema: `TenantCreate` - Update Schema: `TenantUpdate` - Response Schema: `TenantResponse` **範例**: ```python from pydantic import BaseModel, Field class TenantBase(BaseModel): """租戶基礎 Schema""" code: str = Field(..., max_length=50, description="租戶代碼") name: str = Field(..., max_length=200, description="公司名稱") class TenantCreate(TenantBase): """建立租戶 Schema""" admin_email: str = Field(..., description="管理員郵箱") class TenantResponse(TenantBase): """租戶回應 Schema""" id: int status: str created_at: datetime model_config = ConfigDict(from_attributes=True) ``` ## 資料庫規範 ### Migration 管理 **命名規則**: ``` {timestamp}_{description}.py 例如: 20260227_create_subscriptions_table.py ``` **Migration 內容**: ```python def upgrade() -> None: """升級操作""" op.create_table( 'subscriptions', sa.Column('id', sa.Integer(), primary_key=True), sa.Column('tenant_id', sa.Integer(), nullable=False), # ... ) def downgrade() -> None: """降級操作""" op.drop_table('subscriptions') ``` ### 表格命名 - 使用複數形式: `subscriptions`, `invoices` - 使用 snake_case - 加入前綴表示模組: `billing_invoices` ## Git 工作流程 ### 分支策略 - `master`: 生產環境 - `develop`: 開發環境 - `feature/*`: 功能開發 - `hotfix/*`: 緊急修復 ### Commit 訊息 **格式**: ``` <類型>: <簡短描述> <詳細說明> Co-Authored-By: Claude Sonnet 4.5 ``` **類型**: - `feat`: 新功能 - `fix`: 錯誤修復 - `docs`: 文件更新 - `refactor`: 重構 - `test`: 測試 - `chore`: 雜項 **範例**: ``` feat: 新增租戶開通 API 實作租戶自動開通功能,包含: - 建立租戶資料 - 配置網域 - 建立 Keycloak Realm - 初始化服務 Co-Authored-By: Claude Sonnet 4.5 ``` ## 測試規範 ### 單元測試 **覆蓋率目標**: 80%+ **測試檔案命名**: ``` tests/ ├── unit/ │ ├── test_tenant_service.py │ └── test_billing_service.py └── integration/ ├── test_api_tenants.py └── test_api_billing.py ``` **測試範例**: ```python import pytest from app.services.tenant_service import create_tenant def test_create_tenant_success(): """測試建立租戶成功""" data = TenantCreate( code="testcompany", name="測試公司", admin_email="admin@test.com" ) tenant = create_tenant(data) assert tenant.code == "testcompany" assert tenant.status == "trial" ``` ## 安全規範 1. **環境變數**: 所有敏感資訊放在 `.env` 2. **密碼處理**: 使用 bcrypt 雜湊 3. **API 驗證**: 所有 API 需要 JWT token 4. **輸入驗證**: 使用 Pydantic 驗證所有輸入 5. **SQL 注入**: 使用 ORM,避免原生 SQL ## 文件規範 1. **README.md**: 每個專案必須包含 2. **API 文件**: 使用 FastAPI 自動生成 (Swagger) 3. **程式碼註解**: 複雜邏輯必須註解 4. **設計文件**: 重要功能需要設計文件 --- **參考資源**: - [FastAPI 官方文件](https://fastapi.tiangolo.com/) - [Next.js 官方文件](https://nextjs.org/docs) - [Python PEP 8](https://peps.python.org/pep-0008/)