Merge branch 'pr-385'
This commit is contained in:
@@ -7,7 +7,7 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from middleware.auth_middleware import get_current_user
|
||||
from services.database import get_db
|
||||
from services.today_workflow_service import get_or_create_daily_workflow_plan, update_task_status
|
||||
from services.today_workflow_service import coerce_dependencies, get_or_create_daily_workflow_plan, update_task_status
|
||||
from models.daily_workflow_models import DailyWorkflowPlan, DailyWorkflowTask
|
||||
import asyncio
|
||||
from services.intelligence.txtai_service import TxtaiIntelligenceService
|
||||
@@ -62,6 +62,19 @@ async def get_today_workflow(
|
||||
|
||||
tasks = await run_in_threadpool(_fetch_tasks)
|
||||
|
||||
def _normalize_legacy_dependencies(task_rows):
|
||||
rows_updated = False
|
||||
for row in task_rows:
|
||||
normalized_dependencies = coerce_dependencies(row.dependencies)
|
||||
if row.dependencies != normalized_dependencies:
|
||||
row.dependencies = normalized_dependencies
|
||||
db.add(row)
|
||||
rows_updated = True
|
||||
if rows_updated:
|
||||
db.commit()
|
||||
|
||||
await run_in_threadpool(_normalize_legacy_dependencies, tasks)
|
||||
|
||||
response_tasks = []
|
||||
for t in tasks:
|
||||
response_tasks.append(
|
||||
@@ -73,7 +86,7 @@ async def get_today_workflow(
|
||||
"status": "skipped" if t.status == "dismissed" else t.status,
|
||||
"priority": t.priority,
|
||||
"estimatedTime": t.estimated_time,
|
||||
"dependencies": t.dependencies or [],
|
||||
"dependencies": coerce_dependencies(t.dependencies),
|
||||
"actionUrl": t.action_url,
|
||||
"actionType": t.action_type,
|
||||
"metadata": t.metadata_json or {},
|
||||
|
||||
@@ -30,6 +30,25 @@ def _coerce_status(value: Any) -> str:
|
||||
return "pending"
|
||||
|
||||
|
||||
def coerce_dependencies(value: Any) -> List[str]:
|
||||
if isinstance(value, list):
|
||||
return [str(dep).strip() for dep in value if str(dep).strip()]
|
||||
|
||||
if isinstance(value, str):
|
||||
raw = value.strip()
|
||||
if not raw:
|
||||
return []
|
||||
try:
|
||||
parsed = json.loads(raw)
|
||||
if isinstance(parsed, list):
|
||||
return [str(dep).strip() for dep in parsed if str(dep).strip()]
|
||||
except Exception:
|
||||
pass
|
||||
return [raw]
|
||||
|
||||
return []
|
||||
|
||||
|
||||
def _proposal_priority_rank(priority: str) -> int:
|
||||
return {"low": 0, "medium": 1, "high": 2}.get(str(priority or "").lower(), 1)
|
||||
|
||||
@@ -531,7 +550,7 @@ async def get_or_create_daily_workflow_plan(db: Session, user_id: str, date: Opt
|
||||
estimated_time=int(t.get("estimatedTime") or 15),
|
||||
action_type=str(t.get("actionType") or "navigate").strip()[:20],
|
||||
action_url=str(t.get("actionUrl") or "").strip(),
|
||||
dependencies=json.dumps(t.get("dependencies") or []),
|
||||
dependencies=coerce_dependencies(t.get("dependencies")),
|
||||
metadata_json=t.get("metadata") or {},
|
||||
enabled=bool(t.get("enabled", True)),
|
||||
created_at=datetime.utcnow(),
|
||||
|
||||
@@ -14,6 +14,39 @@ import { apiClient } from '../api/client';
|
||||
|
||||
const isServerWorkflowId = (workflowId: string) => workflowId.startsWith('daily-');
|
||||
|
||||
|
||||
const normalizeDependencies = (dependencies: unknown): string[] => {
|
||||
if (Array.isArray(dependencies)) {
|
||||
return dependencies.map(dep => String(dep).trim()).filter(Boolean);
|
||||
}
|
||||
|
||||
if (typeof dependencies === 'string') {
|
||||
const raw = dependencies.trim();
|
||||
if (!raw) return [];
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(raw);
|
||||
if (Array.isArray(parsed)) {
|
||||
return parsed.map(dep => String(dep).trim()).filter(Boolean);
|
||||
}
|
||||
} catch {}
|
||||
|
||||
return [raw];
|
||||
}
|
||||
|
||||
return [];
|
||||
};
|
||||
|
||||
const normalizeServerWorkflow = (workflow: DailyWorkflow): DailyWorkflow => ({
|
||||
...workflow,
|
||||
tasks: Array.isArray(workflow.tasks)
|
||||
? workflow.tasks.map(task => ({
|
||||
...task,
|
||||
dependencies: normalizeDependencies(task.dependencies),
|
||||
}))
|
||||
: [],
|
||||
});
|
||||
|
||||
const computeProgressAndNavigation = (workflow: DailyWorkflow): { progress: WorkflowProgress; navigation: NavigationState } => {
|
||||
const tasks = Array.isArray(workflow.tasks) ? workflow.tasks : [];
|
||||
const totalTasks = tasks.length;
|
||||
@@ -118,9 +151,10 @@ export const useWorkflowStore = create<WorkflowState>()(
|
||||
const resp = await apiClient.get('/api/today-workflow', { params: date ? { date } : {} });
|
||||
const serverWorkflow = resp?.data?.data?.workflow as DailyWorkflow | undefined;
|
||||
if (serverWorkflow && Array.isArray(serverWorkflow.tasks)) {
|
||||
const derived = computeProgressAndNavigation(serverWorkflow);
|
||||
const normalizedWorkflow = normalizeServerWorkflow(serverWorkflow);
|
||||
const derived = computeProgressAndNavigation(normalizedWorkflow);
|
||||
set({
|
||||
currentWorkflow: serverWorkflow,
|
||||
currentWorkflow: normalizedWorkflow,
|
||||
workflowProgress: derived.progress,
|
||||
navigationState: derived.navigation,
|
||||
isLoading: false
|
||||
|
||||
Reference in New Issue
Block a user