0) ? (float)round($r['kr_current_sum'] / $r['kr_target_sum'] * 100, 1) : 0; } unset($r); echo json_encode(['directives' => $rows]); break; // GET directives/get?id=X — full directive with key results and links case 'get': $id = (int)($_GET['id'] ?? 0); if (!$id) { echo json_encode(['error' => 'Missing id']); break; } $d = JarvisDB::single("SELECT * FROM directives WHERE id=?", [$id]); if (!$d) { echo json_encode(['error' => 'Not found']); break; } $krs = JarvisDB::query("SELECT * FROM directive_key_results WHERE directive_id=? ORDER BY id ASC", [$id]) ?: []; $links = JarvisDB::query( "SELECT dl.*, t.title AS task_title, a.title AS appt_title FROM directive_links dl LEFT JOIN tasks t ON dl.link_type='task' AND t.id=dl.link_id LEFT JOIN appointments a ON dl.link_type='appointment' AND a.id=dl.link_id WHERE dl.directive_id=? ORDER BY dl.created_at DESC", [$id] ) ?: []; $sum_cur = array_sum(array_column($krs, 'current_value')); $sum_tgt = array_sum(array_column($krs, 'target_value')); $d['progress'] = ($sum_tgt > 0) ? round($sum_cur / $sum_tgt * 100, 1) : 0; $d['key_results'] = $krs; $d['links'] = $links; echo json_encode($d); break; // POST directives/save — create or update directive + key results case 'save': $id = (int)($data['id'] ?? 0); $title = trim($data['title'] ?? ''); $description = trim($data['description'] ?? ''); $category = $data['category'] ?? 'work'; $status = $data['status'] ?? 'active'; $priority = (int)($data['priority'] ?? 5); $target_date = !empty($data['target_date']) ? $data['target_date'] : null; if (!$title) { echo json_encode(['error' => 'Title required']); break; } if ($id) { JarvisDB::execute( "UPDATE directives SET title=?,description=?,category=?,status=?,priority=?,target_date=?,updated_at=NOW() WHERE id=?", [$title,$description,$category,$status,$priority,$target_date,$id] ); } else { $id = JarvisDB::insert( "INSERT INTO directives (title,description,category,status,priority,target_date) VALUES (?,?,?,?,?,?)", [$title,$description,$category,$status,$priority,$target_date] ); } // Replace key results if provided if (isset($data['key_results']) && is_array($data['key_results'])) { JarvisDB::execute("DELETE FROM directive_key_results WHERE directive_id=?", [$id]); foreach ($data['key_results'] as $kr) { $krtitle = trim($kr['title'] ?? ''); if (!$krtitle) continue; JarvisDB::execute( "INSERT INTO directive_key_results (directive_id,title,current_value,target_value,unit) VALUES (?,?,?,?,?)", [$id, $krtitle, (float)($kr['current_value']??0), (float)($kr['target_value']??100), $kr['unit']??'%'] ); } } echo json_encode(['ok' => true, 'id' => $id]); break; // POST directives/delete?id=X case 'delete': $id = (int)($_GET['id'] ?? $data['id'] ?? 0); if (!$id) { echo json_encode(['error' => 'Missing id']); break; } JarvisDB::execute("DELETE FROM directive_key_results WHERE directive_id=?", [$id]); JarvisDB::execute("DELETE FROM directive_links WHERE directive_id=?", [$id]); JarvisDB::execute("DELETE FROM directives WHERE id=?", [$id]); echo json_encode(['ok' => true]); break; // POST directives/key_result_update — update a single KR's current value case 'key_result_update': $krid = (int)($data['id'] ?? 0); $value = (float)($data['current_value'] ?? 0); if (!$krid) { echo json_encode(['error' => 'Missing kr id']); break; } JarvisDB::execute( "UPDATE directive_key_results SET current_value=?, updated_at=NOW() WHERE id=?", [$value, $krid] ); echo json_encode(['ok' => true]); break; // POST directives/link — link a task or appointment to a directive case 'link': $did = (int)($data['directive_id'] ?? 0); $link_type = $data['link_type'] ?? 'task'; $link_id = (int)($data['link_id'] ?? 0); $note = trim($data['note'] ?? ''); if (!$did) { echo json_encode(['error' => 'Missing directive_id']); break; } JarvisDB::execute( "INSERT INTO directive_links (directive_id,link_type,link_id,note) VALUES (?,?,?,?)", [$did, $link_type, $link_id ?: null, $note] ); echo json_encode(['ok' => true]); break; // POST directives/unlink?id=X — remove a link case 'unlink': $lid = (int)($_GET['id'] ?? $data['id'] ?? 0); if (!$lid) { echo json_encode(['error' => 'Missing id']); break; } JarvisDB::execute("DELETE FROM directive_links WHERE id=?", [$lid]); echo json_encode(['ok' => true]); break; // GET directives/summary — compact progress snapshot for chat/briefing injection case 'summary': $rows = JarvisDB::query( "SELECT d.id, d.title, d.category, d.target_date, COALESCE(SUM(kr.current_value),0) AS kr_cur, COALESCE(SUM(kr.target_value),1) AS kr_tgt FROM directives d LEFT JOIN directive_key_results kr ON kr.directive_id=d.id WHERE d.status='active' GROUP BY d.id ORDER BY d.priority DESC, d.target_date ASC LIMIT 10" ) ?: []; $summary = []; foreach ($rows as $r) { $pct = round($r['kr_cur'] / max($r['kr_tgt'], 1) * 100, 0); $summary[] = [ 'id' => $r['id'], 'title' => $r['title'], 'category' => $r['category'], 'target_date' => $r['target_date'], 'progress' => $pct, ]; } echo json_encode(['directives' => $summary]); break; default: http_response_code(404); echo json_encode(['error' => "Unknown directives action: {$action}"]); }