feat(issues): S4b frontend — open-issues lists + issue plumbing
CI & Build / Python lint (push) Successful in 5s
CI & Build / TypeScript typecheck (push) Successful in 40s
CI & Build / Python tests (push) Successful in 1m36s
CI & Build / Build & push image (push) Successful in 59s

- types/note.ts: Note gains systems? + arose_from_id?; TaskKind includes 'issue'.
- stores/tasks.ts: create/update accept IssueFields (kind/system_ids/arose_from_id).
- api/systems.ts: getProjectIssues + TaskLike.
- DashboardView.vue: 'Open issues' rail section from dashboard.open_issues
  (links to /tasks/<id>, project + status).
- SystemsSection.vue (project Systems tab): 'Open issues' list via getProjectIssues,
  with system chips, links to /tasks/<id>. Both reuse existing CSS tokens.

Issue-editor controls (kind selector / system multi-select / arose-from picker
in WorkspaceTaskPanel) are the remaining S4b piece. NEEDS operator browser
verification (CI typechecks only).

Refs plan 825 (S4b frontend — lists).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-14 10:50:41 -04:00
parent 79040fe5db
commit 94d32c524a
5 changed files with 101 additions and 5 deletions
+12 -2
View File
@@ -3,6 +3,16 @@ import { defineStore } from "pinia";
import { apiGet, apiPost, apiPut, apiPatch, apiDelete } from "@/api/client";
import { useToastStore } from "@/stores/toast";
import type { Task, TaskStatus, TaskPriority, StartPlanningResult } from "@/types/task";
import type { TaskKind } from "@/types/note";
// Issues + Systems write-only fields accepted by the task create/update API.
// `kind` selects work/plan/issue; system_ids / arose_from_id are not mirrored
// 1:1 on the Task model (the read side exposes `systems` + `arose_from_id`).
interface IssueFields {
kind?: TaskKind;
system_ids?: number[];
arose_from_id?: number | null;
}
// Single-task + mutation surface. The list/filter/sort/pagination surface that
// backed the removed /tasks list view was dropped in the 2026-06-02 drift-audit
@@ -34,7 +44,7 @@ export const useTasksStore = defineStore("tasks", () => {
milestone_id?: number | null;
parent_id?: number | null;
recurrence_rule?: Record<string, unknown> | null;
}): Promise<Task> {
} & IssueFields): Promise<Task> {
try {
return await apiPost<Task>("/api/tasks", data);
} catch (e) {
@@ -47,7 +57,7 @@ export const useTasksStore = defineStore("tasks", () => {
id: number,
data: Partial<
Pick<Task, "title" | "body" | "tags" | "status" | "priority" | "due_date" | "project_id" | "milestone_id" | "parent_id" | "recurrence_rule">
>
> & IssueFields
): Promise<Task> {
try {
const task = await apiPut<Task>(`/api/tasks/${id}`, data);