audit: Tier 5.4 — wrap moveFolder cycle check + write in a tx

Concurrency-auditor HIGH: the cycle walk + UPDATE used to run as
separate statements. Two concurrent moves (A→B and B→A) could each
pass the walk against the pre-move tree and both write, leaving an
A↔B cycle. Whole sequence now runs inside one db.transaction().

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-12 17:19:24 +02:00
parent ad74e4a174
commit bfed1543b7
3 changed files with 57 additions and 45 deletions

View File

@@ -40,8 +40,7 @@ const LeadSourceChart = dynamic(
{ loading: ChartFallback, ssr: false },
);
const OccupancyTimelineChart = dynamic(
() =>
import('./occupancy-timeline-chart').then((m) => ({ default: m.OccupancyTimelineChart })),
() => import('./occupancy-timeline-chart').then((m) => ({ default: m.OccupancyTimelineChart })),
{ loading: ChartFallback, ssr: false },
);
const PipelineFunnelChart = dynamic(