feat(taskflow): add core task API, storage persistence, csv export, stats page, and test coverage

This commit is contained in:
Alexander Kalinovsky
2026-04-01 17:56:03 +03:00
commit 19d659df6b
31 changed files with 4197 additions and 0 deletions

60
app/domain/tasks.py Normal file
View File

@@ -0,0 +1,60 @@
from __future__ import annotations
from datetime import datetime, UTC
from app.storage.models import StoredTask
class InvalidTransitionError(Exception):
"""Raised when task workflow transition is invalid."""
def start_task(task: StoredTask) -> StoredTask:
"""
Transition task from backlog → in_progress.
Rules:
- Idempotent: if already started, do not change started_at
- Cannot start a task that is already done
"""
# already done → invalid
if task.done_at is not None:
raise InvalidTransitionError("invalid_transaction")
# already started → idempotent (no change)
if task.started_at is not None:
return task
return StoredTask(
id=task.id,
title=task.title,
created_at=task.created_at,
started_at=datetime.now(UTC),
done_at=task.done_at,
)
def complete_task(task: StoredTask) -> StoredTask:
"""
Transition task from in_progress → done.
Rules:
- Allowed only if task is started
- Idempotent: if already done, do not change done_at
"""
# not started → invalid
if task.started_at is None:
raise InvalidTransitionError("invalid_transaction")
# already done → idempotent
if task.done_at is not None:
return task
return StoredTask(
id=task.id,
title=task.title,
created_at=task.created_at,
started_at=task.started_at,
done_at=datetime.now(UTC),
)