Add extensive logging to trace data flow and fix API to handle tasks array

This commit is contained in:
OpenClaw Bot 2026-02-19 21:05:12 -06:00
parent 30d8d7022b
commit 79bffbf0b8
3 changed files with 68 additions and 12 deletions

View File

@ -87,21 +87,30 @@ export async function GET() {
// POST - create or update tasks, projects, or sprints // POST - create or update tasks, projects, or sprints
export async function POST(request: Request) { export async function POST(request: Request) {
try { try {
const { task, projects, sprints } = await request.json(); const body = await request.json();
console.log('>>> API POST: received body keys:', Object.keys(body));
console.log('>>> API POST: has task?', !!body.task, '| has tasks?', !!body.tasks, '| has projects?', !!body.projects, '| has sprints?', !!body.sprints);
console.log('>>> API POST: tasks array length:', body.tasks?.length);
const { task, tasks, projects, sprints } = body;
const data = getData(); const data = getData();
console.log('>>> API POST: current data in file - tasks:', data.tasks?.length, 'projects:', data.projects?.length, 'sprints:', data.sprints?.length);
// Update projects if provided // Update projects if provided
if (projects) { if (projects) {
console.log('>>> API POST: updating projects:', projects.length);
data.projects = projects; data.projects = projects;
} }
// Update sprints if provided // Update sprints if provided
if (sprints) { if (sprints) {
console.log('>>> API POST: updating sprints:', sprints.length);
data.sprints = sprints; data.sprints = sprints;
} }
// Update or add task // Update or add single task
if (task) { if (task) {
console.log('>>> API POST: updating single task:', task.id);
const existingIndex = data.tasks.findIndex((t) => t.id === task.id); const existingIndex = data.tasks.findIndex((t) => t.id === task.id);
if (existingIndex >= 0) { if (existingIndex >= 0) {
data.tasks[existingIndex] = { ...task, updatedAt: new Date().toISOString() }; data.tasks[existingIndex] = { ...task, updatedAt: new Date().toISOString() };
@ -115,9 +124,17 @@ export async function POST(request: Request) {
} }
} }
// Update all tasks if tasks array provided
if (tasks && Array.isArray(tasks)) {
console.log('>>> API POST: updating ALL tasks array:', tasks.length);
data.tasks = tasks;
}
saveData(data); saveData(data);
console.log('>>> API POST: saved! New task count:', data.tasks.length);
return NextResponse.json({ success: true, data }); return NextResponse.json({ success: true, data });
} catch (error) { } catch (error) {
console.error('>>> API POST: error:', error);
return NextResponse.json({ error: "Failed to save" }, { status: 500 }); return NextResponse.json({ error: "Failed to save" }, { status: 500 });
} }
} }

View File

@ -56,6 +56,7 @@ const sprintColumns: { key: string; label: string; statuses: TaskStatus[] }[] =
] ]
export default function Home() { export default function Home() {
console.log('>>> PAGE: Component rendering')
const { const {
projects, projects,
tasks, tasks,
@ -95,9 +96,19 @@ export default function Home() {
// Sync from server on mount // Sync from server on mount
useEffect(() => { useEffect(() => {
syncFromServer() console.log('>>> PAGE: useEffect for syncFromServer running')
console.log('>>> PAGE: tasks count before sync:', tasks.length)
syncFromServer().then(() => {
console.log('>>> PAGE: syncFromServer completed')
console.log('>>> PAGE: tasks count after sync:', tasks.length)
})
}, [syncFromServer]) }, [syncFromServer])
// Log when tasks change
useEffect(() => {
console.log('>>> PAGE: tasks changed, new count:', tasks.length)
}, [tasks])
const selectedProject = projects.find((p) => p.id === selectedProjectId) const selectedProject = projects.find((p) => p.id === selectedProjectId)
const selectedTask = tasks.find((t) => t.id === selectedTaskId) const selectedTask = tasks.find((t) => t.id === selectedTaskId)

View File

@ -377,22 +377,25 @@ const defaultTasks: Task[] = [
// Helper to sync to server // Helper to sync to server
async function syncToServer(projects: Project[], tasks: Task[], sprints: Sprint[]) { async function syncToServer(projects: Project[], tasks: Task[], sprints: Sprint[]) {
console.log('syncToServer: saving', tasks.length, 'tasks') console.log('>>> syncToServer: saving', tasks.length, 'tasks,', projects.length, 'projects,', sprints.length, 'sprints')
const t2 = tasks.find(t => t.id === '2') const t2 = tasks.find(t => t.id === '2')
if (t2) console.log('syncToServer: task 2 sprintId:', t2.sprintId) if (t2) console.log('>>> syncToServer: task 2 sprintId:', t2.sprintId)
try { try {
const body = JSON.stringify({ projects, tasks, sprints })
console.log('>>> syncToServer: sending body with keys:', Object.keys(JSON.parse(body)))
const res = await fetch('/api/tasks', { const res = await fetch('/api/tasks', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ projects, tasks, sprints }), body: body,
}) })
if (res.ok) { if (res.ok) {
console.log('syncToServer: saved successfully') const responseData = await res.json()
console.log('>>> syncToServer: saved successfully, server now has', responseData.data?.tasks?.length, 'tasks')
} else { } else {
console.error('syncToServer: failed with status', res.status) console.error('>>> syncToServer: failed with status', res.status)
} }
} catch (error) { } catch (error) {
console.error('Failed to sync to server:', error) console.error('>>> syncToServer: Failed to sync to server:', error)
} }
} }
@ -409,12 +412,21 @@ export const useTaskStore = create<TaskStore>()(
lastSynced: null, lastSynced: null,
syncFromServer: async () => { syncFromServer: async () => {
console.log('>>> syncFromServer START')
set({ isLoading: true }) set({ isLoading: true })
try { try {
const res = await fetch('/api/tasks') const res = await fetch('/api/tasks')
console.log('>>> syncFromServer: API response status:', res.status)
if (res.ok) { if (res.ok) {
const data = await res.json() const data = await res.json()
console.log('syncFromServer: fetched', data.tasks?.length, 'tasks') console.log('>>> syncFromServer: fetched data:', {
projectsCount: data.projects?.length,
tasksCount: data.tasks?.length,
sprintsCount: data.sprints?.length,
firstTaskTitle: data.tasks?.[0]?.title,
lastUpdated: data.lastUpdated,
})
console.log('>>> syncFromServer: current store tasks count BEFORE set:', get().tasks.length)
// ALWAYS use server data if API returns successfully // ALWAYS use server data if API returns successfully
set({ set({
projects: data.projects || [], projects: data.projects || [],
@ -422,14 +434,16 @@ export const useTaskStore = create<TaskStore>()(
sprints: data.sprints || [], sprints: data.sprints || [],
lastSynced: Date.now(), lastSynced: Date.now(),
}) })
console.log('>>> syncFromServer: store tasks count AFTER set:', get().tasks.length)
} else { } else {
console.error('syncFromServer: API returned', res.status) console.error('>>> syncFromServer: API returned error status:', res.status)
} }
} catch (error) { } catch (error) {
console.error('Failed to sync from server:', error) console.error('>>> syncFromServer: Failed to sync from server:', error)
// Keep local data if server fails // Keep local data if server fails
} finally { } finally {
set({ isLoading: false }) set({ isLoading: false })
console.log('>>> syncFromServer END')
} }
}, },
@ -617,6 +631,20 @@ export const useTaskStore = create<TaskStore>()(
selectedTaskId: state.selectedTaskId, selectedTaskId: state.selectedTaskId,
selectedSprintId: state.selectedSprintId, selectedSprintId: state.selectedSprintId,
}), }),
onRehydrateStorage: () => {
console.log('>>> PERSIST: onRehydrateStorage called')
return (state, error) => {
if (error) {
console.log('>>> PERSIST: Rehydration error:', error)
} else {
console.log('>>> PERSIST: Rehydrated state:', {
selectedProjectId: state?.selectedProjectId,
selectedTaskId: state?.selectedTaskId,
tasksCount: state?.tasks?.length,
})
}
}
},
} }
) )
) )