PMFlow/PMFlow-Dev-Plan.md

9.4 KiB
Raw Blame History

PMFlow Dev Plan — User / Skill / Workload Modules

Stack: FastAPI + React + shadcn/ui + Tailwind | Timeline: ~11 days, 1 dev


Phase 1 — Core Foundation (Day 1–3)

Day 1 — DB Migration + User CRUD

DB

ALTER TABLE users ADD COLUMN is_active BOOLEAN NOT NULL DEFAULT TRUE;

CREATE TABLE user_projects (
    id BIGSERIAL PRIMARY KEY,
    tenant_id BIGINT NOT NULL DEFAULT 1,
    user_id BIGINT NOT NULL,
    project_id BIGINT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (tenant_id) REFERENCES tenants(id),
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (project_id) REFERENCES projects(id),
    UNIQUE(tenant_id, user_id, project_id)
);

Backend

  • Update ORM: User.is_active, new UserProject model
  • GET /api/users — paginated list with filters (role/status/project/workload/skill)
  • POST /api/users — create user (bcrypt password, auto-init user_workloads row with 40h/week)
  • PUT /api/users/{id} — update user
  • DELETE /api/users/{id} — block if user has incomplete tasks
  • POST /api/users/{id}/reset-password
  • PATCH /api/users/{id}/status — disable: clear tasks.assignee_id, zero out workload
  • POST /api/users/import — bulk import via Excel (max 50 rows, return per-row result)
  • Transaction: delete user → cascade delete user_skill_bindings + user_workloads
  • Log all mutations (actor, time, diff)

Frontend

  • Routes: /users, /skills, /workloads, /workloads/:id
  • /users page: top bar (title + New/Import/Bulk-delete buttons + search)
  • Right filter panel (280px, collapsible): role / status / project / workload-state / skill multi-select
  • Table: avatar+name / email / role badge / linked projects / top-3 skill tags / workload% / status / actions
  • New/Edit user modal (form validation, edit pre-fills data)
  • Reset password modal
  • Bulk import modal (preview first 10 rows, highlight errors, show import result summary)
  • Workload% color: green <70%, yellow 70–100%, red >100%

Day 2 — Skill & Workload APIs

Backend — Skills

  • Seed system skill tags on startup (Python, FastAPI, LangChain, React, Prompt Eng, etc.)
  • GET /api/skill-tags — list with category filter
  • POST /api/skill-tags — admin only
  • PUT /api/skill-tags/{id} — system tags: category only; custom: name + category
  • DELETE /api/skill-tags/{id} — block if is_system=true; cascade delete user_skill_bindings
  • GET /api/users/{id}/skills — user skill bindings
  • POST /api/users/{id}/skills — bind skill (default: beginner, scores 0.0)
  • PUT /api/users/{id}/skills/{skill_id} — update proficiency / scores
  • DELETE /api/users/{id}/skills/{skill_id} — unbind (block system-auto-bound skills)

Backend — Workload

  • Workload calc util: ratio = assigned_hours / ((max_weekly_hours / 5) * remaining_workdays)
  • GET /api/workloads — team list with project/date filters
  • GET /api/workloads/{user_id} — personal detail
  • PUT /api/workloads/{user_id} — update max weekly hours (triggers ratio recalc)
  • GET /api/workloads/{user_id}/tasks — assigned task list
  • GET /api/workloads/{user_id}/trend — daily ratio for last 7/30 days
  • Cron job at 00:00 daily: recalc ratio for all users based on updated remaining workdays
  • Auto-trigger ratio recalc on: task assign / estimate change / task complete / task delete

Day 3 — Skill & Workload Frontend

Frontend — Skill Tags (/skills)

  • Table: name / category badge / linked-user count / actions
  • System tags: show "System" label, disable delete, disable name edit
  • New/Edit skill tag modal
  • Category badge colors: dev=blue / algorithm=purple / product=orange / pm=green / qa=gray

Frontend — User Skill Detail (/users/:id/skills)

  • Top bar: avatar / name / role / linked projects / "Batch Edit" + "Refresh Scores" buttons
  • Left 60%: skills grouped by category (collapsible), each row: name / proficiency dropdown / quality score / efficiency score / last used (read-only)
  • "Remove" button per row (disabled for system-bound skills)
  • "Add Skill" button → modal to select skill tags
  • Right 40%: recharts RadarChart — weighted score per skill, filter by category, hover shows detail
  • "Export Chart" button (save as image)

Frontend — Team Workload (/workloads)

  • Filter bar: project select + date range (this week / this month / custom)
  • 3 stat cards: avg team ratio / headcount by state (idle/normal/overloaded) / AI alert summary
  • Table: member info / projects / assigned hours / max weekly hours / ratio% / remaining hours / actions
  • Overloaded rows: red highlight + warning icon

Frontend — Personal Workload (/workloads/:id)

  • Header: ratio% / remaining hours / "Adjust Hours" button
  • recharts LineChart: daily ratio trend (7d/30d toggle), 70% + 100% reference lines, overloaded segments in red
  • Task list table: title / project / priority / est. hours / due date / status / view link
  • Task list filters: status / priority / due date

Phase 2 — Sync Logic + AI (Day 4–8)

Day 4–5 — Cross-module Sync

Backend

  • User create → init empty user_skill_bindings, init user_workloads
  • User delete → transaction: delete bindings + workload record
  • User disable → zero current_assigned_hours + workload_ratio, clear task assignments
  • Skill score update → recalc top-3 skills for user, sync to user list response
  • Workload ratio change → sync to user list workload_ratio field
  • Skill proficiency level → pass to task estimation: expert → lower est. hours → lower ratio

Frontend

  • User list table: workload% and top-3 skill tags update without page reload (TanStack Query invalidation)
  • Skill detail page: manual score edit shows warning "AI will overwrite on next update"
  • Workload team table: ratio column updates in real-time after task changes

Day 6–7 — SSTC Kanban Integration

Backend

  • Task assign endpoint: filter candidates to current-project users only, exclude disabled users
  • GET /api/tasks/recommend-assignees?task_id= — rank users by skill match + proficiency + ratio (<70% preferred)
  • Task status → done: trigger async job to update current_assigned_hours (subtract est. hours) and recalc ratio
  • GET /api/workloads/summary — team health card data for kanban top bar

Frontend

  • SSTC kanban top bar: "Team Workload Health" card (avg ratio + overload count), click → /workloads
  • Task breakdown panel: recommended assignees list shows name / role / top skills / ratio badge
  • Assignee dropdown: disabled users grayed out and unselectable
  • Task status change → trigger workload refetch (TanStack Query)

Day 8 — AI Features

Backend

  • New LangChain prompt: skill score update — input: task quality_score + (est_hours / actual_hours), output: quality/efficiency score delta per skill tag
  • Trigger on tasks.status = done: async call above prompt, apply weighted update (higher priority task = higher weight)
  • New LangChain prompt: workload optimization — input: all members' skills + ratios, output: suggested task reassignments
  • POST /api/workloads/ai-optimize — run optimization, return preview plan (no auto-apply)
  • POST /api/workloads/ai-optimize/apply — apply approved plan (batch update tasks.assignee_id)
  • Overload alert: ratio >100% → send notification (Feishu/email); if unresolved 24h → auto-generate transfer suggestion

Frontend

  • "AI Optimize Assignments" button → show optimization preview modal (old vs new assignee per task)
  • Confirm → apply; Cancel → discard
  • Overload alert banner on team workload page when any member >100%

Phase 3 — Polish (Day 9–11)

Day 9 — Filters / Export / Bulk Actions

  • Verify all filter combinations work correctly across all 3 pages
  • Export workload report (Excel/PDF)
  • Export skill radar chart (PNG)
  • Bulk delete users (with incomplete-task guard)
  • Bulk assign project / role to selected users

Day 10 — Permissions

Role Users Skills Workload
admin Full Full Full
manager Own project users (no delete) Bind/edit scores for own project View + optimize own project
member View all + edit own profile View own + edit own proficiency View own + edit own weekly hours
  • Backend: permission middleware on all mutation endpoints
  • Frontend: route guards + button-level permission checks

Day 11 — Final QA

  • Dark mode audit across all new pages
  • Empty state / loading state / error state for all tables and cards
  • Toast notifications for all CRUD operations
  • End-to-end flow test: create user → bind skills → assign task → complete task → verify score + workload update
  • Fix bugs, merge

Reference

Workload ratio formula:

ratio = current_assigned_hours / ((max_weekly_hours / 5) * remaining_workdays_this_week)

Ratio recalc triggers: task assign · est hours change · task complete · task delete · weekly hours update · daily cron

API response format:

{ "code": 200, "message": "ok", "data": {} }