mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-10 12:37:55 +01:00
Address recovery review cleanup notes
This commit is contained in:
1 parent
ff19cf66b1
commit
48d95bd237
2 files changed
+55
-32
No files matched your search
+33
-14
@@ -422,11 +422,11 @@ type RecoveryActionsLister = {
|
||||
) => Promise<Map<string, NonNullable<IssueRelationIssueSummary["activeRecoveryAction"]>>>;
|
||||
};
|
||||
|
||||
async function annotateRelationSummariesWithRecoveryActions(
|
||||
async function relationRecoveryActionMap(
|
||||
recoveryActionsSvc: RecoveryActionsLister,
|
||||
companyId: string,
|
||||
relations: { blockedBy: IssueRelationIssueSummary[]; blocks: IssueRelationIssueSummary[] },
|
||||
) {
|
||||
): Promise<Map<string, NonNullable<IssueRelationIssueSummary["activeRecoveryAction"]>>> {
|
||||
const candidates: IssueRelationIssueSummary[] = [];
|
||||
const visit = (summary: IssueRelationIssueSummary) => {
|
||||
candidates.push(summary);
|
||||
@@ -436,13 +436,24 @@ async function annotateRelationSummariesWithRecoveryActions(
|
||||
};
|
||||
for (const blocker of relations.blockedBy) visit(blocker);
|
||||
for (const blocking of relations.blocks) visit(blocking);
|
||||
if (candidates.length === 0) return;
|
||||
if (candidates.length === 0) return new Map();
|
||||
const ids = [...new Set(candidates.map((summary) => summary.id))];
|
||||
const map = await recoveryActionsSvc.listActiveForIssues(companyId, ids);
|
||||
for (const summary of candidates) {
|
||||
const action = map.get(summary.id) ?? null;
|
||||
if (action) summary.activeRecoveryAction = action;
|
||||
}
|
||||
return recoveryActionsSvc.listActiveForIssues(companyId, ids);
|
||||
}
|
||||
|
||||
function withRecoveryActionsOnRelationSummaries(
|
||||
relations: { blockedBy: IssueRelationIssueSummary[]; blocks: IssueRelationIssueSummary[] },
|
||||
recoveryActionByIssueId: Map<string, NonNullable<IssueRelationIssueSummary["activeRecoveryAction"]>>,
|
||||
) {
|
||||
const augment = (summary: IssueRelationIssueSummary): IssueRelationIssueSummary => ({
|
||||
...summary,
|
||||
activeRecoveryAction: recoveryActionByIssueId.get(summary.id) ?? summary.activeRecoveryAction ?? null,
|
||||
terminalBlockers: summary.terminalBlockers?.map(augment),
|
||||
});
|
||||
return {
|
||||
blockedBy: relations.blockedBy.map(augment),
|
||||
blocks: relations.blocks.map(augment),
|
||||
};
|
||||
}
|
||||
|
||||
const ACTIVE_REVIEW_APPROVAL_STATUSES = new Set(["pending", "revision_requested"]);
|
||||
@@ -1599,11 +1610,15 @@ export function issueRoutes(
|
||||
currentExecutionWorkspacePromise,
|
||||
recoveryActionsSvc.getActiveForIssue(issue.companyId, issue.id),
|
||||
]);
|
||||
await annotateRelationSummariesWithRecoveryActions(
|
||||
const recoveryActionsByRelationIssue = await relationRecoveryActionMap(
|
||||
recoveryActionsSvc,
|
||||
issue.companyId,
|
||||
relations,
|
||||
);
|
||||
const relationsWithRecoveryActions = withRecoveryActionsOnRelationSummaries(
|
||||
relations,
|
||||
recoveryActionsByRelationIssue,
|
||||
);
|
||||
|
||||
res.json({
|
||||
issue: {
|
||||
@@ -1621,8 +1636,8 @@ export function issueRoutes(
|
||||
projectId: issue.projectId,
|
||||
goalId: goal?.id ?? issue.goalId,
|
||||
parentId: issue.parentId,
|
||||
blockedBy: relations.blockedBy,
|
||||
blocks: relations.blocks,
|
||||
blockedBy: relationsWithRecoveryActions.blockedBy,
|
||||
blocks: relationsWithRecoveryActions.blocks,
|
||||
assigneeAgentId: issue.assigneeAgentId,
|
||||
assigneeUserId: issue.assigneeUserId,
|
||||
originKind: issue.originKind,
|
||||
@@ -1713,11 +1728,15 @@ export function issueRoutes(
|
||||
svc.getCurrentScheduledRetry(issue.id),
|
||||
recoveryActionsSvc.getActiveForIssue(issue.companyId, issue.id),
|
||||
]);
|
||||
await annotateRelationSummariesWithRecoveryActions(
|
||||
const recoveryActionsByRelationIssue = await relationRecoveryActionMap(
|
||||
recoveryActionsSvc,
|
||||
issue.companyId,
|
||||
relations,
|
||||
);
|
||||
const relationsWithRecoveryActions = withRecoveryActionsOnRelationSummaries(
|
||||
relations,
|
||||
recoveryActionsByRelationIssue,
|
||||
);
|
||||
const mentionedProjects = mentionedProjectIds.length > 0
|
||||
? await projectsSvc.listByIds(issue.companyId, mentionedProjectIds)
|
||||
: [];
|
||||
@@ -1734,8 +1753,8 @@ export function issueRoutes(
|
||||
successfulRunHandoff: successfulRunHandoffStates.get(issue.id) ?? null,
|
||||
scheduledRetry,
|
||||
activeRecoveryAction,
|
||||
blockedBy: relations.blockedBy,
|
||||
blocks: relations.blocks,
|
||||
blockedBy: relationsWithRecoveryActions.blockedBy,
|
||||
blocks: relationsWithRecoveryActions.blocks,
|
||||
relatedWork: referenceSummary,
|
||||
referencedIssueIdentifiers: referenceSummary.outbound.map((item) => item.issue.identifier ?? item.issue.id),
|
||||
...documentPayload,
|
||||
|
||||
@@ -2193,7 +2193,7 @@ export function recoveryService(db: Db, deps: { enqueueWakeup: RecoveryWakeup })
|
||||
}
|
||||
|
||||
async function collectIssueGraphLivenessFindings() {
|
||||
const issueRows = await db
|
||||
const issueRowsPromise = Promise.resolve(db
|
||||
.select({
|
||||
id: issues.id,
|
||||
companyId: issues.companyId,
|
||||
@@ -2218,10 +2218,10 @@ export function recoveryService(db: Db, deps: { enqueueWakeup: RecoveryWakeup })
|
||||
isNull(issues.hiddenAt),
|
||||
notInArray(issues.originKind, [RECOVERY_ORIGIN_KINDS.issueGraphLivenessEscalation]),
|
||||
),
|
||||
);
|
||||
const issueIdsUnderAnalysis = issueRows.map((row) => row.id);
|
||||
));
|
||||
|
||||
const [
|
||||
issueRows,
|
||||
relationRows,
|
||||
agentRows,
|
||||
activeRunRows,
|
||||
@@ -2232,6 +2232,7 @@ export function recoveryService(db: Db, deps: { enqueueWakeup: RecoveryWakeup })
|
||||
recoveryIssueRows,
|
||||
recoveryActionRows,
|
||||
] = await Promise.all([
|
||||
issueRowsPromise,
|
||||
db
|
||||
.select({
|
||||
companyId: issueRelations.companyId,
|
||||
@@ -2321,21 +2322,24 @@ export function recoveryService(db: Db, deps: { enqueueWakeup: RecoveryWakeup })
|
||||
notInArray(issues.status, ["done", "cancelled"]),
|
||||
),
|
||||
),
|
||||
issueIdsUnderAnalysis.length === 0
|
||||
? Promise.resolve([])
|
||||
: db
|
||||
.select({
|
||||
companyId: issueRecoveryActions.companyId,
|
||||
issueId: issueRecoveryActions.sourceIssueId,
|
||||
status: issueRecoveryActions.status,
|
||||
})
|
||||
.from(issueRecoveryActions)
|
||||
.where(
|
||||
and(
|
||||
inArray(issueRecoveryActions.status, ["active", "escalated"]),
|
||||
inArray(issueRecoveryActions.sourceIssueId, issueIdsUnderAnalysis),
|
||||
),
|
||||
),
|
||||
issueRowsPromise.then((rows) => {
|
||||
const issueIdsUnderAnalysis = rows.map((row) => row.id);
|
||||
return issueIdsUnderAnalysis.length === 0
|
||||
? []
|
||||
: db
|
||||
.select({
|
||||
companyId: issueRecoveryActions.companyId,
|
||||
issueId: issueRecoveryActions.sourceIssueId,
|
||||
status: issueRecoveryActions.status,
|
||||
})
|
||||
.from(issueRecoveryActions)
|
||||
.where(
|
||||
and(
|
||||
inArray(issueRecoveryActions.status, ["active", "escalated"]),
|
||||
inArray(issueRecoveryActions.sourceIssueId, issueIdsUnderAnalysis),
|
||||
),
|
||||
);
|
||||
}),
|
||||
]);
|
||||
|
||||
const openRecoveryIssues = recoveryIssueRows.flatMap((row) => {
|
||||
|
||||
Reference in new issue
Block a user