mateclaw/mateclaw-server/src/main/java/vip/mate/approval
matevip 2f93d53737 refactor(approval): unify state machine across DB/metadata/memory
Foundation for the ghost-approval root-cause fix.

Adds ResolveOutcome / MetadataDecision; rewrites ApprovalWorkflowService so
every resolve / consume / timeout / supersede transitions through one
two-phase contract: snapshot → DB UPDATE conditional on status=PENDING →
metadata reconciliation → afterCommit memory mutation. ChatController,
ChannelMessageRouter, and ApprovalController all switch to the workflow;
ApprovalService.resolve / resolveAndConsume / consumeApproved /
cancelStalePending / denyAllByConversation are physically removed so
DB-bypass is no longer reachable at compile time.

Specific fixes:
- recoverFromDb preserves DB pendingId + createdAt (was generating fresh
  random ids, breaking every later DB sync)
- effectiveExpireAt = expireAt ?? createdAt + PENDING_TTL: legacy rows
  with NULL expireAt no longer resurrect as live PENDING after restart
- markPendingApprovalsResolved flips pendingApproval.status + currentPhase
  + MessageEntity.status atomically (was only flipping the first field;
  message.status uses existing completed/stopped, not approved/denied,
  to stay within the frontend Message.status union)
- GC scheduler moves to ApprovalWorkflowService; timeouts and overflow
  evictions now sync DB + metadata + memory through markTimeout
- DB UPDATE rows=0 returns alreadyResolved (concurrent-resolve safe);
  exception propagates so @Transactional rolls back; memory stays untouched
- expireRecoveredRow gates metadata write on DB success (was writing
  metadata even when DB update failed, producing the worst-case ghost)
- Mockito JDK 21 agent attach fixed via maven-dependency-plugin properties
  + surefire argLine (no more flaky self-attach across machines)

Tests: 34 new across 4 classes (recovery, resolve, GC, metadata sync).
Full suite: 788 / 788.
2026-04-27 19:30:52 +08:00
..
model refactor(db): drop @TableLogic on all entities, purge soft-deleted rows 2026-04-18 23:31:48 +08:00
repository Initial commit: MateClaw — Java + Vue 3 AI Assistant System 2026-04-04 19:03:49 +08:00
ApprovalController.java refactor(approval): unify state machine across DB/metadata/memory 2026-04-27 19:30:52 +08:00
ApprovalDecision.java Initial commit: MateClaw — Java + Vue 3 AI Assistant System 2026-04-04 19:03:49 +08:00
ApprovalPlaceholderUtil.java Initial commit: MateClaw — Java + Vue 3 AI Assistant System 2026-04-04 19:03:49 +08:00
ApprovalService.java refactor(approval): unify state machine across DB/metadata/memory 2026-04-27 19:30:52 +08:00
ApprovalStatus.java Initial commit: MateClaw — Java + Vue 3 AI Assistant System 2026-04-04 19:03:49 +08:00
ApprovalWorkflowService.java refactor(approval): unify state machine across DB/metadata/memory 2026-04-27 19:30:52 +08:00
MetadataDecision.java refactor(approval): unify state machine across DB/metadata/memory 2026-04-27 19:30:52 +08:00
PendingApproval.java refactor(approval): unify state machine across DB/metadata/memory 2026-04-27 19:30:52 +08:00
ResolveOutcome.java refactor(approval): unify state machine across DB/metadata/memory 2026-04-27 19:30:52 +08:00