Initial commit: KPI Management System Backend

Features:
- FastAPI backend with JWT authentication
- MySQL database with SQLAlchemy ORM
- KPI workflow: draft → pending → approved → evaluation → completed
- Ollama LLM API integration for AI features
- Gitea API integration for version control
- Complete API endpoints for KPI, dashboard, notifications

Tables: KPI_D_* prefix naming convention

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-11 16:20:57 +08:00
commit f810ddc2ea
48 changed files with 4950 additions and 0 deletions

125
ddl/02_seed_data.sql Normal file
View File

@@ -0,0 +1,125 @@
-- KPI 管理系統 - 種子資料
-- 版本: 1.0
-- 建立日期: 2024-12
-- ============================================
-- 1. 部門資料
-- ============================================
INSERT INTO departments (code, name, level, parent_id) VALUES
('COMPANY', '總公司', 'COMPANY', NULL),
('BU_TECH', '技術事業部', 'BU', 1),
('BU_SALES', '業務事業部', 'BU', 1),
('DEPT_RD', '研發部', 'DEPT', 2),
('DEPT_QA', '品保部', 'DEPT', 2),
('DEPT_SALES', '業務部', 'DEPT', 3),
('DEPT_MARKETING', '行銷部', 'DEPT', 3),
('DEPT_HR', '人力資源部', 'DEPT', 1),
('DEPT_FINANCE', '財務部', 'DEPT', 1);
-- ============================================
-- 2. 員工資料 (密碼: password123)
-- bcrypt hash for 'password123'
-- ============================================
INSERT INTO employees (employee_no, name, email, password_hash, department_id, manager_id, job_title, role, status, hire_date) VALUES
-- 管理層
('EMP00001', '王大明', 'admin@example.com', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.yHvLt7c2bF5Eni', 1, NULL, '總經理', 'admin', 'active', '2020-01-01'),
-- 技術事業部
('EMP00002', '陳志強', 'chen.zhiqiang@example.com', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.yHvLt7c2bF5Eni', 2, 1, '技術長', 'manager', 'active', '2020-03-15'),
('EMP00003', '林小華', 'lin.xiaohua@example.com', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.yHvLt7c2bF5Eni', 4, 2, '研發經理', 'manager', 'active', '2021-01-10'),
('EMP00004', '張美玲', 'zhang.meiling@example.com', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.yHvLt7c2bF5Eni', 4, 3, '資深工程師', 'employee', 'active', '2021-06-01'),
('EMP00005', '李建國', 'li.jianguo@example.com', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.yHvLt7c2bF5Eni', 4, 3, '工程師', 'employee', 'active', '2022-03-01'),
('EMP00006', '黃雅琪', 'huang.yaqi@example.com', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.yHvLt7c2bF5Eni', 5, 2, '品保經理', 'manager', 'active', '2021-02-15'),
('EMP00007', '吳宗翰', 'wu.zonghan@example.com', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.yHvLt7c2bF5Eni', 5, 6, 'QA工程師', 'employee', 'active', '2022-08-01'),
-- 業務事業部
('EMP00008', '趙文傑', 'zhao.wenjie@example.com', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.yHvLt7c2bF5Eni', 3, 1, '業務長', 'manager', 'active', '2020-05-01'),
('EMP00009', '周曉明', 'zhou.xiaoming@example.com', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.yHvLt7c2bF5Eni', 6, 8, '業務經理', 'manager', 'active', '2021-04-01'),
('EMP00010', '蔡佳蓉', 'cai.jiarong@example.com', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.yHvLt7c2bF5Eni', 6, 9, '業務專員', 'employee', 'active', '2022-01-15'),
-- 人資部
('EMP00011', '許淑芬', 'xu.shufen@example.com', '$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/X4.yHvLt7c2bF5Eni', 8, 1, '人資經理', 'hr', 'active', '2020-06-01');
-- ============================================
-- 3. KPI 期間資料
-- ============================================
INSERT INTO kpi_periods (code, name, start_date, end_date, setting_start, setting_end, self_eval_start, self_eval_end, manager_eval_start, manager_eval_end, status) VALUES
('2024H1', '2024年上半年', '2024-01-01', '2024-06-30', '2024-01-01', '2024-01-14', '2024-06-15', '2024-06-25', '2024-06-26', '2024-06-30', 'completed'),
('2024H2', '2024年下半年', '2024-07-01', '2024-12-31', '2024-07-01', '2024-07-14', '2024-12-15', '2024-12-25', '2024-12-26', '2024-12-31', 'setting'),
('2025H1', '2025年上半年', '2025-01-01', '2025-06-30', '2025-01-01', '2025-01-14', '2025-06-15', '2025-06-25', '2025-06-26', '2025-06-30', 'draft');
-- ============================================
-- 4. KPI 範本資料
-- ============================================
INSERT INTO kpi_templates (code, name, category, description, default_weight, level0_desc, level1_desc, level2_desc, level3_desc, level4_desc) VALUES
-- 財務類
('FIN001', '單位製造成本降低率', 'financial', '製造成本控制指標', 25,
'成本反升或降低 <2%', '降低 2.0%-2.9%', '降低 3.0%', '降低 3.1%-3.9%', '降低 ≥4.0%'),
('FIN002', '營收達成率', 'financial', '營收目標達成指標', 30,
'達成率 <80%', '達成率 80%-89%', '達成率 90%-99%', '達成率 100%-109%', '達成率 ≥110%'),
('FIN003', '毛利率提升', 'financial', '毛利率改善指標', 20,
'毛利率下降', '維持不變', '提升 0.1%-0.5%', '提升 0.6%-1.0%', '提升 >1.0%'),
-- 客戶類
('CUS001', '客戶滿意度', 'customer', '客戶滿意度調查結果', 25,
'滿意度 <70%', '滿意度 70%-79%', '滿意度 80%-89%', '滿意度 90%-94%', '滿意度 ≥95%'),
('CUS002', '客訴處理時效', 'customer', '客訴回應與解決時間', 15,
'平均 >72 小時', '平均 48-72 小時', '平均 24-48 小時', '平均 12-24 小時', '平均 <12 小時'),
('CUS003', '新客戶開發數', 'customer', '新客戶獲取數量', 20,
'0 家', '1-2 家', '3-4 家', '5-6 家', '≥7 家'),
-- 內部流程類
('INT001', '專案準時完成率', 'internal', '專案如期交付比率', 25,
'準時率 <70%', '準時率 70%-79%', '準時率 80%-89%', '準時率 90%-94%', '準時率 ≥95%'),
('INT002', '流程改善提案', 'internal', '提出並執行的流程改善', 15,
'0 件', '1 件', '2 件', '3 件', '≥4 件'),
('INT003', '系統穩定度', 'internal', '系統可用率指標', 20,
'可用率 <95%', '可用率 95%-96.9%', '可用率 97%-98.4%', '可用率 98.5%-99.4%', '可用率 ≥99.5%'),
-- 學習成長類
('LRN001', '專業證照取得', 'learning', '取得專業認證', 15,
'未取得', '考試中', '取得 1 張', '取得 2 張', '取得 ≥3 張'),
('LRN002', '內部訓練時數', 'learning', '參與內部培訓時數', 10,
'<10 小時', '10-19 小時', '20-29 小時', '30-39 小時', '≥40 小時'),
('LRN003', '知識分享場次', 'learning', '進行內部知識分享', 10,
'0 場', '1 場', '2 場', '3 場', '≥4 場');
-- ============================================
-- 5. KPI 預設組合資料
-- ============================================
INSERT INTO kpi_presets (code, name, description, applicable_roles) VALUES
('PRESET_ENG', '工程師標準組合', '適用於研發、品保工程師', ARRAY['employee']),
('PRESET_SALES', '業務人員標準組合', '適用於業務專員', ARRAY['employee']),
('PRESET_MGR', '主管標準組合', '適用於部門主管', ARRAY['manager']);
-- ============================================
-- 6. KPI 預設項目資料
-- ============================================
-- 工程師組合
INSERT INTO kpi_preset_items (preset_id, template_id, default_weight, is_mandatory, sort_order) VALUES
(1, 7, 30, TRUE, 1), -- 專案準時完成率
(1, 9, 25, TRUE, 2), -- 系統穩定度
(1, 8, 15, FALSE, 3), -- 流程改善提案
(1, 10, 15, FALSE, 4), -- 專業證照取得
(1, 12, 15, FALSE, 5); -- 知識分享場次
-- 業務人員組合
INSERT INTO kpi_preset_items (preset_id, template_id, default_weight, is_mandatory, sort_order) VALUES
(2, 2, 40, TRUE, 1), -- 營收達成率
(2, 6, 25, TRUE, 2), -- 新客戶開發數
(2, 4, 20, FALSE, 3), -- 客戶滿意度
(2, 11, 15, FALSE, 4); -- 內部訓練時數
-- 主管組合
INSERT INTO kpi_preset_items (preset_id, template_id, default_weight, is_mandatory, sort_order) VALUES
(3, 2, 30, TRUE, 1), -- 營收達成率
(3, 7, 25, TRUE, 2), -- 專案準時完成率
(3, 4, 20, FALSE, 3), -- 客戶滿意度
(3, 8, 15, FALSE, 4), -- 流程改善提案
(3, 12, 10, FALSE, 5); -- 知識分享場次
-- ============================================
-- 7. 通知偏好預設資料
-- ============================================
INSERT INTO notification_preferences (employee_id, email_enabled, in_app_enabled, reminder_days_before)
SELECT id, TRUE, TRUE, 3 FROM employees;