Commit graph

5 commits

Author SHA1 Message Date
Janpeter Visser
3b5cee823c
Load/render workspace alignment (#182)
* docs: plan load render workspace alignment

* fix: normalize workspace status hydration

* fix: avoid duplicate backlog hydration load

* refactor: use sprint store active story

* refactor: migrate solo to workspace store

* chore: stabilize verification ignores
2026-05-10 07:34:58 +02:00
Janpeter Visser
d750676f5e
PBI-56 + ST-1275: PLAN_READY → GRILLING re-grill + SKIPPED status rendering (#147)
* fix(ST-1272): allow PLAN_READY → GRILLING re-grill transition

actions/ideas.ts already lists PLAN_READY in GRILL_TRIGGERABLE_FROM,
but lib/idea-status.ts ALLOWED_TRANSITIONS was missing the
PLAN_READY → GRILLING edge. As a result, clicking Grill on a PLAN_READY
idea returned 422 "Status-transitie ongeldig" while the UI button was
enabled. Mirrors the existing PLANNED → GRILLING re-grill behaviour.

- lib/idea-status.ts: PLAN_READY allows GRILLING in addition to
  PLANNING/PLANNED
- __tests__/lib/idea-status.test.ts: explicit assert for
  PLAN_READY → GRILLING and PLAN_READY added to the regrill loop
  covering every GRILL_TRIGGERABLE_FROM status

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(ST-1275): render SKIPPED job status in chart-colors and insights

Closing the gap left when ClaudeJobStatus.SKIPPED was added to the schema:
the badge map and case-mapper already covered it, but the chart palette,
the per-day insights aggregator and the stacked-bar chart did not. SKIPPED
jobs (e.g. cmovkur8 manually flipped during the no-op-exit hotfix) now
render with a muted style consistent with cancelled.

- lib/chart-colors.ts: JOB_STATUS_COLORS gains a 'skipped' entry
  (var(--muted-foreground), same intensity as cancelled — neither rood/orange)
- lib/insights/agent-throughput.ts: DayCount + STATUSES + perDay zero-fill
  now include 'skipped'; the SQL terminal_7d filter already counted SKIPPED
- app/(app)/insights/components/agent-throughput.tsx: STACKED_STATUSES and
  the empty-state guard include 'skipped'
- __tests__: chart-colors keys list, job-status round-trip ('all 7 statuses')
  and the insights non-zero filter all account for SKIPPED

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:36:44 +02:00
Janpeter Visser
94f4f6ffd8
feat(PBI-33): chat-kanaal UI + lint cleanup (#145)
* feat(PBI-33): chat-kanaal UI — IdeaTimeline merge + UserChatInput

Voltooit de UI-laag van PLAN_CHAT (gebruikersvragen over plan, Claude
antwoordt async). Backend (UserQuestion model, createUserQuestionAction,
SSE-handling, server-side prop-passing) was al aanwezig — alleen de
UI-koppeling ontbrak waardoor userQuestions ongebruikt bleven.

- IdeaDetailLayout geeft userQuestions/planMd/ideaId/isDemo door aan
  IdeaTimeline en telt user-questions mee in de tab-count
- IdeaTimeline mergt user-questions chronologisch met logs+questions,
  rendert ze met MessageCircle-icoon en pending/answered status, en
  toont onderaan UserChatInput wanneer plan_md aanwezig is
- UserChatInput nieuw component met textarea + verzend-knop dat
  createUserQuestionAction aanroept en op success router.refresh()
  triggert zodat SSE de pending-state oppikt
- useNotificationsRealtime: router toegevoegd aan useEffect-deps zodat
  router.refresh() op user_question/idea-job events werkt zonder
  stale-closure waarschuwing

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(lint): unused vars/imports + react-hook-form watch incompatibility

Resolves de overige lint-warnings van de gefaalde sprint-build die los
staan van PBI-33. Eslint-config staat unused vars/args toe als ze met
'_' prefixen, dus required interface-params krijgen een prefix terwijl
losse dode constantes/imports verwijderd worden.

- sprint-header: productId is required prop maar nog niet gebruikt
  → prefix _productId i.p.v. verwijderen (caller passeert het door)
- agent-throughput: STATUSES-constante was dood — verwijderd, queries
  gebruiken hardcoded status-velden in de perDay-loop
- claude-jobs: productAccessFilter en enforceUserRateLimit waren
  dode imports — verwijderd
- story-log.test: ongebruikte 'data' binding vervangen door bare
  await res.json() zodat de stream nog wel geconsumeerd wordt
- product-dialog: form.watch('auto_pr') vervangen door useWatch met
  control-prop — useWatch is veilig voor React Compiler memoization

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 16:04:53 +02:00
deb70a9e20 feat(T-572): map SKIPPED in lib/job-status + alle terminal-checks
- lib/job-status.ts: SKIPPED ↔ 'skipped' mapping in beide richtingen
- components/shared/job-status.ts: label "Overgeslagen" + neutrale italic styling
- actions/admin/jobs.ts: cancel-guard erkent SKIPPED als eindstatus
- app/api/cron/cleanup-agent-artifacts: SKIPPED ook opruimen na 7d
- lib/insights/agent-throughput: SKIPPED telt mee als terminal

ACTIVE_JOB_STATUSES bewust ongewijzigd — SKIPPED is afgerond.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 23:10:14 +02:00
739037a60b
Agent throughput: jobs per dag stacked bar + KPI-strip (#49)
* feat(insights): add getJobsPerDay helper — agent throughput per day + KPIs

Raw SQL aggregation of claude_jobs by day and status over 14 days with
zero-fill for missing days. KPIs: todayCount, successRate7d, avgDurationSeconds7d.
Optional productId filter.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(insights): add AgentThroughputCard — stacked BarChart + KPI-strip + product filter

KPI strip (jobs today, 7d success rate, 7d avg duration), 14-day stacked
BarChart with JOB_STATUS_COLORS, and URL-bookmarkable product dropdown via
useTransition + router.replace. Empty-state when no activity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 16:30:06 +02:00