pr-monitor/shared/types.ts
2026-07-28 14:44:55 +00:00

86 lines
1.9 KiB
TypeScript

export type CheckCategory = 'lint' | 'specs' | 'e2e' | 'other';
export type CategoryState = 'fail' | 'running' | 'pending' | 'pass' | 'skipped' | 'none';
export interface CheckInfo {
name: string;
state: CategoryState;
url: string | null;
}
export interface CategoryStatus {
category: CheckCategory;
state: CategoryState;
passed: number;
/** Non-skipped check count (drives the "7/9" chip summary). */
total: number;
checks: CheckInfo[];
}
export type ReviewState = 'no_review' | 'outstanding' | 'addressed';
export interface ReviewerVerdict {
reviewer: string;
state: 'APPROVED' | 'CHANGES_REQUESTED';
url: string;
submittedAt: string;
}
export interface PrSnapshot {
id: string;
repo: string;
number: number;
title: string;
url: string;
author: string;
isDraft: boolean;
branch: string;
updatedAt: string;
reviewState: ReviewState;
unresolvedThreads: number;
totalThreads: number;
verdicts: ReviewerVerdict[];
categories: CategoryStatus[];
}
export type TimelineKind = 'issue_comment' | 'review_comment' | 'review';
export interface TimelineEvent {
id: string;
prId: string;
repo: string;
prNumber: number;
prTitle: string;
kind: TimelineKind;
actor: string;
createdAt: string;
bodyExcerpt: string;
url: string;
reviewState: string | null;
path: string | null;
read: boolean;
/** Set when this is a reply within a review thread: the thread's root comment. */
inReplyTo: { actor: string; bodyExcerpt: string } | null;
}
export interface StatePayload {
prs: PrSnapshot[];
lastSyncAt: string | null;
lastSyncError: string | null;
unreadCountsByPr: Record<string, number>;
unreadTotal: number;
}
export interface TimelinePage {
events: TimelineEvent[];
nextCursor: string | null;
}
export interface SyncEventPayload {
lastSyncAt: string | null;
error: string | null;
changedPrIds: string[];
newEventCount: number;
unreadCount: number;
}