'use client' import { useState, useCallback } from 'react' import Link from 'next/link' import { useFlowRun } from '@/hooks/useFlowRun' import StreamingTerminal from '@/components/StreamingTerminal' import ConfirmDialog from '@/components/ConfirmDialog' const FLOW_KEY = 'redeploy_all' const STEPS = [ 'git status Scrum4Me (show current state)', 'git fetch Scrum4Me (fetch remote refs)', 'git log (commits ahead of upstream)', 'git pull --ff-only Scrum4Me (aborts if dirty)', 'npm ci (install dependencies)', 'prisma migrate deploy (apply migrations)', 'npm run build (build application)', 'systemctl restart scrum4me-web', 'smoke test: curl /api/products (expect 200 or 401)', 'git status scrum4me-docker (show current state)', 'git fetch scrum4me-docker (fetch remote refs)', 'git pull --ff-only scrum4me-docker (aborts if dirty)', 'git pull --ff-only scrum4me-mcp (lokale sync)', 'rebuild worker image — cache-busted MCP clone', 'docker compose up -d --force-recreate worker-idea', 'wait for worker pre-flight to pass', ] export default function FlowPanel() { const [pendingDryRun, setPendingDryRun] = useState(null) const [completedFlowRunId, setCompletedFlowRunId] = useState(null) const handleComplete = useCallback((flowRunId: string) => { setCompletedFlowRunId(flowRunId) }, []) const flowRun = useFlowRun(handleComplete) const handleConfirm = useCallback(() => { if (pendingDryRun === null) return const dryRun = pendingDryRun setPendingDryRun(null) setCompletedFlowRunId(null) flowRun.startFlow(FLOW_KEY, dryRun) }, [pendingDryRun, flowRun]) const handleReset = useCallback(() => { flowRun.reset() setCompletedFlowRunId(null) }, [flowRun]) return (

Volledige stack-redeploy: eerst de hoofd-app (scrum4me-web — pull, migrate, build, restart), dan de MCP-worker (cache-busted image rebuild zodat de nieuwe scrum4me-mcp code wordt opgepikt).

repos: Scrum4Me · scrum4me-docker · scrum4me-mcp

    {STEPS.map((step, i) => (
  1. {i + 1}. {step}
  2. ))}
{flowRun.status !== 'idle' && flowRun.status !== 'running' && ( )}
{flowRun.status !== 'idle' && (
Output {completedFlowRunId && ( View in audit log → )}
)} ` ${i + 1}. ${s}`).join('\n')}` } onConfirm={handleConfirm} onCancel={() => setPendingDryRun(null)} />
) }