feat: milestone state machine + propose flow + task state machine #8

Merged
hzhang merged 23 commits from feat/milestone-propose-state-machine into main 2026-03-19 11:11:09 +00:00

23 Commits

Author SHA1 Message Date
zhi
43742f69da fix: add values_callable to all SQLAlchemy Enum columns
SQLAlchemy 2.0 defaults to mapping Python enum *names* (OPEN, CLOSED)
to DB values, but MySQL stores lowercase *values* (open, closed).
This mismatch causes LookupError on read.

Adding values_callable=lambda x: [e.value for e in x] tells SQLAlchemy
to use the enum values for DB mapping.

Affected models: milestone, task, meeting, propose, support
2026-03-19 09:38:37 +00:00
zhi
e938507a24 test(P13.3): propose backend tests — 19 tests covering CRUD, accept/reject/reopen, code generation, feat_task_id protection, edit restrictions, permissions 2026-03-18 05:01:56 +00:00
zhi
c21e4ee335 test(P13.2): task state-machine tests — 34 tests covering transitions, assignee guards, comments, permissions, edit restrictions 2026-03-18 04:02:29 +00:00
zhi
011a2262ce test(P13.1): add milestone state machine tests — 17 tests covering freeze/start/close/auto-complete/preflight
New test infrastructure:
- tests/conftest.py: SQLite in-memory fixtures, TestClient wired to test DB,
  factory fixtures for User/Project/Milestone/Task/Roles/Permissions
- tests/test_milestone_actions.py: 17 tests covering:
  - freeze success/no-release-task/multiple-release-tasks/wrong-status
  - start success+started_at/deps-not-met/wrong-status
  - close from open/freeze/undergoing, rejected from completed/closed
  - auto-complete on release task finish, no auto-complete for non-release/wrong-status
  - preflight allowed/not-allowed
2026-03-18 03:07:30 +00:00
zhi
7bad57eb0e feat(P5): sync batch transition with P5.3-P5.6 guards — auth, assignee, comment, permission, deps, auto-complete 2026-03-18 01:01:59 +00:00
zhi
00a1786ec3 feat(P12.1): CLI — add propose subcommands, remove task_type=task, add milestone status filter, transition comment support 2026-03-18 00:01:52 +00:00
zhi
586e06f66a feat(P3.6): lock feature story task body edits when milestone is freeze/undergoing/completed/closed 2026-03-17 23:01:39 +00:00
zhi
ec91a15f65 fix(P7.1): remove TaskType.TASK from models.py + fix milestone task defaults (issue/pending) 2026-03-17 23:01:02 +00:00
zhi
8e38d4cf4d feat(P2.2): add default mgr/dev role seeds with preset permissions for milestone/task/propose actions 2026-03-17 19:02:44 +00:00
zhi
0c75045f6f feat(P4.3): wire task depend_on check into pending→open transition via reusable helper 2026-03-17 18:02:08 +00:00
zhi
c6b14ac25f P4.1: Extract reusable dependency check helper, deduplicate milestone_actions.py
- New app/services/dependency_check.py with check_milestone_deps()
- Replaces 3x duplicated JSON-parse + query + filter logic
- Supports both milestone and task dependency checking
- Returns structured DepCheckResult with ok/blockers/reason
- Refactored preflight and start endpoints to use shared helper
2026-03-17 17:03:45 +00:00
zhi
89e3bcdd0f feat(P7.1): remove task_type='task' — migrate to issue/defect, update defaults and DB migration 2026-03-17 16:05:32 +00:00
zhi
3afbbc2a88 feat(P2.1): register 9 new permissions (milestone/task/propose actions) + wire check_permission in all action endpoints
- Add milestone.freeze/start/close, task.close/reopen_closed/reopen_completed, propose.accept/reject/reopen to DEFAULT_PERMISSIONS
- Replace placeholder check_project_role with check_permission in proposes.py accept/reject/reopen
- Replace freeform permission strings with dotted names in milestone_actions.py
- Add task.close and task.reopen_* permission checks in tasks.py transition endpoint
- Admin role auto-inherits all new permissions via init_wizard
2026-03-17 15:03:48 +00:00
zhi
c18b8f3850 feat(P9.6): block story/feature and maintenance/release task creation via general create endpoints 2026-03-17 13:02:46 +00:00
zhi
7542f2d7c1 feat(P5.7): task edit restrictions — block body edits in undergoing/completed/closed, enforce assignee-only edit in open+assigned 2026-03-17 12:04:12 +00:00
zhi
ffb0fa6058 feat(P5.3+P5.4): enforce assignee identity on start/complete + require completion comment in transition endpoint 2026-03-17 11:02:19 +00:00
zhi
7a16639aac feat(P8.3): milestone preflight endpoint for freeze/start button pre-condition checks 2026-03-17 10:04:17 +00:00
zhi
314040cef5 feat(P3.6): milestone edit restrictions — block PATCH in terminal states, restrict scope fields in freeze/undergoing, protect delete 2026-03-17 09:01:40 +00:00
zhi
589b1cc8de feat(P5.1-P5.6): task state-machine validation — enforce legal transitions in transition/batch/update endpoints 2026-03-17 08:02:37 +00:00
zhi
7d8c448cb8 feat(P3.1): milestone action endpoints — freeze/start/close + auto-complete hook
- New milestone_actions router with POST freeze/start/close endpoints
- freeze: validates exactly 1 release maintenance task exists
- start: validates all milestone/task dependencies completed, records started_at
- close: allows from open/freeze/undergoing with reason
- try_auto_complete_milestone helper: auto-completes milestone when sole release task finishes
- Wired auto-complete into task transition and update endpoints
- Added freeze enforcement: no new feature story tasks after freeze
- Added started_at to milestone serializer
- All actions write activity logs
2026-03-17 04:03:05 +00:00
zhi
75ccbcb362 feat: propose CRUD router + accept/reject/reopen actions (P6.1-P6.4) 2026-03-17 03:01:49 +00:00
zhi
2bea75e843 feat: add Propose model/schema + DB enum migration scripts
- New Propose model (app/models/propose.py) with status enum (open/accepted/rejected)
- New Propose schemas (ProposeCreate/Update/Response) in schemas.py
- MySQL enum migration in main.py for milestone/task status columns
  - milestone: pending→open, deferred→closed, progressing→undergoing
  - task: progressing→undergoing
- Import propose model in startup for create_all
- Add started_at column migration for milestones
2026-03-17 02:04:42 +00:00
zhi
9e22c97ae8 refactor: update milestone/task status enums to new state machine values
Milestone: open/freeze/undergoing/completed/closed (was open/pending/deferred/progressing/closed)
Task: open/pending/undergoing/completed/closed (was open/pending/progressing/closed)

- Add MilestoneStatusEnum to schemas with typed validation
- Add started_at field to Milestone model
- Update all router/CLI references from progressing->undergoing
- Add completed status handling in task transition logic
2026-03-17 00:04:29 +00:00