Conversation
… matrix on toggle
Greptile SummaryThis PR implements per-node maintenance mode for VectorFlow's fleet management. When enabled, the agent config endpoint returns Key changes:
Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Admin as Admin Browser
participant tRPC as tRPC (fleet.setMaintenanceMode)
participant DB as PostgreSQL
participant Agent as Vector Agent
Admin->>tRPC: setMaintenanceMode({ nodeId, enabled: true })
tRPC->>DB: withTeamAccess resolves nodeId → teamId
tRPC->>DB: UPDATE VectorNode SET maintenanceMode=true, maintenanceModeAt=now()
DB-->>tRPC: updated node
tRPC-->>Admin: success → invalidate fleet.list, listWithPipelineStatus, fleet.get
Note over Agent: next config poll (≤15s)
Agent->>DB: GET /api/agent/config (bearer token)
DB-->>Agent: { pipelines: [], pollIntervalMs, secretBackend, pendingAction }
Note over Agent: stops all running pipelines naturally
Admin->>tRPC: setMaintenanceMode({ nodeId, enabled: false })
tRPC->>DB: UPDATE VectorNode SET maintenanceMode=false, maintenanceModeAt=null
DB-->>tRPC: updated node
tRPC-->>Admin: success
Note over Agent: next config poll
Agent->>DB: GET /api/agent/config
DB-->>Agent: { pipelines: [...full config...], ... }
Note over Agent: resumes all pipelines
Last reviewed commit: b23ff14 |
| if (node?.maintenanceMode) { | ||
| const environment = await prisma.environment.findUnique({ | ||
| where: { id: agent.environmentId }, | ||
| select: { secretBackend: true }, | ||
| }); | ||
| const settings = await prisma.systemSettings.findUnique({ | ||
| where: { id: "singleton" }, | ||
| select: { fleetPollIntervalMs: true }, | ||
| }); | ||
| return NextResponse.json({ | ||
| pipelines: [], | ||
| pollIntervalMs: settings?.fleetPollIntervalMs ?? 15_000, | ||
| secretBackend: environment?.secretBackend ?? "BUILTIN", | ||
| pendingAction: node.pendingAction ?? undefined, | ||
| }); | ||
| } |
There was a problem hiding this comment.
secretBackendConfig omitted for non-BUILTIN backends in maintenance response
When the node is in maintenance mode, the early return fetches the environment with only { secretBackend: true } and never includes secretBackendConfig in the response. The normal path includes it for all non-BUILTIN backends:
// normal path
...(environment.secretBackend !== "BUILTIN"
? { secretBackendConfig: environment.secretBackendConfig }
: {}),If an environment uses Vault, AWS SM, or another external backend and the agent relies on receiving secretBackendConfig to maintain or re-initialize its connection to that backend on each config poll, it would lose that initialization data for the duration of maintenance mode. When maintenance ends, the first poll would restore the full config, but if the agent's secret-backend client has any transient state derived from that field it could fail to reconnect cleanly.
The fix is to select secretBackendConfig alongside secretBackend in the maintenance-mode environment query, and then conditionally include it in the early-return payload to match the normal path:
const environment = await prisma.environment.findUnique({
where: { id: agent.environmentId },
select: { secretBackend: true, secretBackendConfig: true },
});
// ...
return NextResponse.json({
pipelines: [],
pollIntervalMs: settings?.fleetPollIntervalMs ?? 15_000,
secretBackend: environment?.secretBackend ?? "BUILTIN",
...(environment?.secretBackend !== "BUILTIN" && environment?.secretBackendConfig
? { secretBackendConfig: environment.secretBackendConfig }
: {}),
pendingAction: node.pendingAction ?? undefined,
});Prompt To Fix With AI
This is a comment left during a code review.
Path: src/app/api/agent/config/route.ts
Line: 22-37
Comment:
**`secretBackendConfig` omitted for non-BUILTIN backends in maintenance response**
When the node is in maintenance mode, the early return fetches the environment with only `{ secretBackend: true }` and never includes `secretBackendConfig` in the response. The normal path includes it for all non-BUILTIN backends:
```ts
// normal path
...(environment.secretBackend !== "BUILTIN"
? { secretBackendConfig: environment.secretBackendConfig }
: {}),
```
If an environment uses Vault, AWS SM, or another external backend and the agent relies on receiving `secretBackendConfig` to maintain or re-initialize its connection to that backend on each config poll, it would lose that initialization data for the duration of maintenance mode. When maintenance ends, the first poll would restore the full config, but if the agent's secret-backend client has any transient state derived from that field it could fail to reconnect cleanly.
The fix is to select `secretBackendConfig` alongside `secretBackend` in the maintenance-mode environment query, and then conditionally include it in the early-return payload to match the normal path:
```ts
const environment = await prisma.environment.findUnique({
where: { id: agent.environmentId },
select: { secretBackend: true, secretBackendConfig: true },
});
// ...
return NextResponse.json({
pipelines: [],
pollIntervalMs: settings?.fleetPollIntervalMs ?? 15_000,
secretBackend: environment?.secretBackend ?? "BUILTIN",
...(environment?.secretBackend !== "BUILTIN" && environment?.secretBackendConfig
? { secretBackendConfig: environment.secretBackendConfig }
: {}),
pendingAction: node.pendingAction ?? undefined,
});
```
How can I resolve this? If you propose a fix, please make it concise.
Summary
maintenanceModeboolean andmaintenanceModeAttimestamp on VectorNode, with Prisma migrationpipelines: []when node is in maintenance (agent stops pipelines naturally, zero agent changes)setMaintenanceModefleet router mutation (ADMIN-only, audit logged)Test Plan
maintenanceModeandmaintenanceModeAtcolumns exist on VectorNode