package vip.mate.activity;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import vip.mate.approval.model.ToolApprovalEntity;
import vip.mate.approval.repository.ToolApprovalMapper;
import vip.mate.audit.model.AuditEventEntity;
import vip.mate.audit.repository.AuditEventMapper;
import vip.mate.audit.service.AuditEventService;
import vip.mate.common.result.R;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import vip.mate.workspace.core.annotation.RequireWorkspaceRole;
/**
* RFC-090 §4.5 / §7 — unified Activity feed.
*
*
Merges three sources into one chronologically-ordered stream:
*
* - {@code audit_event} — CRUD-style events on agents / channels /
* skills / wiki / workspace (the existing audit log)
* - {@code tool_approval} — approval requests + their resolution
* (granted / denied / expired). Ties tool gating decisions
* directly to the audit timeline.
* - Successful tool calls — RFC §4.5 mentions these, but the
* runtime doesn't yet persist a row per successful call.
* Returning an empty bucket keeps the API contract stable so
* the UI can light up automatically once a future commit adds
* persistence.
*
*
* Pagination is best-effort: each source is paged from index 0
* up to {@code size * 2}, then the merged list is trimmed and offset
* in-memory. For workspaces with >>1k events / day a follow-up should
* push merging into SQL; this is good enough for v1.
*/
@Tag(name = "Activity Feed (RFC-090)")
@RestController
@RequestMapping("/api/v1/activity")
@RequiredArgsConstructor
public class ActivityFeedController {
private final AuditEventService auditEventService;
private final AuditEventMapper auditEventMapper;
private final ToolApprovalMapper toolApprovalMapper;
/**
* RFC-090 §4.5 — paginated activity feed.
*
*
Pagination strategy:
*
* - Single-source filter (source=audit | approval) →
* direct {@code BaseMapper.selectPage(...)} on the matching
* table. Both total and records are SQL-accurate.
* - Combined feed (source unset) → fetch
* {@code page*size} rows from each side, merge by time-desc,
* slice to the requested window. {@code total} is the sum
* of {@code selectCount} across both tables — exact for
* count, best-effort for time-merge ordering at very deep
* page numbers (the merge buffer is bounded but typical
* use stays within a few hundred rows).
*
*
* Caps: {@code size} clamped to [1, 200]; {@code page} ≥ 1.
*/
@Operation(summary = "Unified activity feed (audit + approval + tool calls)")
@GetMapping("/feed")
@RequireWorkspaceRole("admin")
public R