@shipfox/annotations 12.0.0 → 12.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +19 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/db/annotations.d.ts +20 -0
- package/dist/db/annotations.d.ts.map +1 -1
- package/dist/db/annotations.js +51 -1
- package/dist/db/annotations.js.map +1 -1
- package/dist/db/db.d.ts +2 -2
- package/dist/db/index.d.ts +2 -2
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/schema/annotations.d.ts +2 -2
- package/dist/presentation/routes/index.d.ts.map +1 -1
- package/dist/presentation/routes/index.js +2 -0
- package/dist/presentation/routes/index.js.map +1 -1
- package/dist/presentation/routes/read-annotation-summary.d.ts +2 -0
- package/dist/presentation/routes/read-annotation-summary.d.ts.map +1 -0
- package/dist/presentation/routes/read-annotation-summary.js +43 -0
- package/dist/presentation/routes/read-annotation-summary.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/db/annotations.ts +84 -1
- package/src/db/index.ts +10 -2
- package/src/presentation/routes/index.ts +2 -1
- package/src/presentation/routes/read-annotation-summary.ts +50 -0
- package/src/presentation/routes/read-annotations.test.ts +56 -1
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ shipfox-swc
|
|
2
|
-
Successfully compiled:
|
|
2
|
+
Successfully compiled: 18 files with swc (421.16ms)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @shipfox/annotations
|
|
2
2
|
|
|
3
|
+
## 12.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4b0731e: Adds workflow troubleshooting details, evaluation traces, failure annotations, runner context, step output metadata, and lazy paginated annotation summaries.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [4b0731e]
|
|
12
|
+
- @shipfox/annotations-dto@12.3.0
|
|
13
|
+
|
|
14
|
+
## 12.2.0
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- @shipfox/node-fastify@0.4.2
|
|
19
|
+
- @shipfox/node-module@1.0.6
|
|
20
|
+
- @shipfox/api-auth-context@12.2.0
|
|
21
|
+
|
|
3
22
|
## 12.0.0
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,2BAA4B,SAAQ,KAAK;aACxB,QAAQ,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,2BAA4B,SAAQ,KAAK;aACxB,QAAQ,EAAE,MAAM;IAA5C,YAA4B,QAAQ,EAAE,MAAM,EAG3C;CACF;AAED,qBAAa,iCAAkC,SAAQ,KAAK;aAC9B,cAAc,EAAE,MAAM;IAAlD,YAA4B,cAAc,EAAE,MAAM,EAGjD;CACF;AAED,qBAAa,sCAAuC,SAAQ,KAAK;aACnC,QAAQ,EAAE,MAAM;IAA5C,YAA4B,QAAQ,EAAE,MAAM,EAG3C;CACF"}
|
package/dist/db/annotations.d.ts
CHANGED
|
@@ -21,6 +21,26 @@ export interface ListAnnotationsForRunAttemptResult {
|
|
|
21
21
|
} | null;
|
|
22
22
|
}
|
|
23
23
|
export declare function listAnnotationsForRunAttempt(params: ListAnnotationsForRunAttemptParams): Promise<ListAnnotationsForRunAttemptResult>;
|
|
24
|
+
export interface AnnotationSummary {
|
|
25
|
+
total: number;
|
|
26
|
+
error: number;
|
|
27
|
+
warning: number;
|
|
28
|
+
info: number;
|
|
29
|
+
success: number;
|
|
30
|
+
stepCounts: Array<{
|
|
31
|
+
originStepId: string;
|
|
32
|
+
originStepAttempt: number;
|
|
33
|
+
total: number;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
export interface SummarizeAnnotationsForRunAttemptParams {
|
|
37
|
+
workflowRunId: string;
|
|
38
|
+
workflowRunAttempt: number;
|
|
39
|
+
workspaceIds: readonly string[];
|
|
40
|
+
jobExecutionId?: string | undefined;
|
|
41
|
+
}
|
|
42
|
+
/** Count annotation styles without reading any annotation bodies. */
|
|
43
|
+
export declare function summarizeAnnotationsForRunAttempt(params: SummarizeAnnotationsForRunAttemptParams): Promise<AnnotationSummary>;
|
|
24
44
|
export interface StoredAnnotation {
|
|
25
45
|
id: string;
|
|
26
46
|
context: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotations.d.ts","sourceRoot":"","sources":["../../src/db/annotations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,kBAAkB,EAA6B,MAAM,0BAA0B,CAAC;AAE7F,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,8BAA8B,CAAC;AAI7D,eAAO,MAAM,8BAA8B,MAA6B,CAAC;AAEzE,MAAM,WAAW,kCAAkC;IACjD,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,KAAK,CAAC,EAAE;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAC,GAAG,SAAS,CAAC;IACnD,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,kCAAkC;IACjD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI,CAAC;CACnD;AAED,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,kCAAkC,GACzC,OAAO,CAAC,kCAAkC,CAAC,CAoC7C;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACvF,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC5E,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC7E;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK,OAAO,CAAC,CAAC,CAAC,GACpD,OAAO,CAAC,CAAC,CAAC,CAuEZ"}
|
|
1
|
+
{"version":3,"file":"annotations.d.ts","sourceRoot":"","sources":["../../src/db/annotations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,kBAAkB,EAA6B,MAAM,0BAA0B,CAAC;AAE7F,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,8BAA8B,CAAC;AAI7D,eAAO,MAAM,8BAA8B,MAA6B,CAAC;AAEzE,MAAM,WAAW,kCAAkC;IACjD,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,KAAK,CAAC,EAAE;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAC,GAAG,SAAS,CAAC;IACnD,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,kCAAkC;IACjD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI,CAAC;CACnD;AAED,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,kCAAkC,GACzC,OAAO,CAAC,kCAAkC,CAAC,CAoC7C;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,KAAK,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,uCAAuC;IACtD,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,qEAAqE;AACrE,wBAAsB,iCAAiC,CACrD,MAAM,EAAE,uCAAuC,GAC9C,OAAO,CAAC,iBAAiB,CAAC,CA0D5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACvF,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC5E,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC7E;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK,OAAO,CAAC,CAAC,CAAC,GACpD,OAAO,CAAC,CAAC,CAAC,CAuEZ"}
|
package/dist/db/annotations.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { READ_ANNOTATIONS_MAX_LIMIT } from '@shipfox/annotations-dto';
|
|
2
|
-
import { and, asc, eq, gt, inArray, or, sql } from 'drizzle-orm';
|
|
2
|
+
import { and, asc, count, eq, gt, inArray, or, sql } from 'drizzle-orm';
|
|
3
3
|
import { db } from './db.js';
|
|
4
4
|
import { annotations, toAnnotation } from './schema/annotations.js';
|
|
5
5
|
export const DEFAULT_ANNOTATIONS_READ_LIMIT = READ_ANNOTATIONS_MAX_LIMIT;
|
|
@@ -36,6 +36,56 @@ export async function listAnnotationsForRunAttempt(params) {
|
|
|
36
36
|
} : null
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
|
+
/** Count annotation styles without reading any annotation bodies. */ export async function summarizeAnnotationsForRunAttempt(params) {
|
|
40
|
+
const summary = {
|
|
41
|
+
total: 0,
|
|
42
|
+
error: 0,
|
|
43
|
+
warning: 0,
|
|
44
|
+
info: 0,
|
|
45
|
+
success: 0,
|
|
46
|
+
stepCounts: []
|
|
47
|
+
};
|
|
48
|
+
if (params.workspaceIds.length === 0) return summary;
|
|
49
|
+
const conditions = [
|
|
50
|
+
eq(annotations.workflowRunId, params.workflowRunId),
|
|
51
|
+
eq(annotations.workflowRunAttempt, params.workflowRunAttempt),
|
|
52
|
+
inArray(annotations.workspaceId, [
|
|
53
|
+
...params.workspaceIds
|
|
54
|
+
])
|
|
55
|
+
];
|
|
56
|
+
if (params.jobExecutionId) {
|
|
57
|
+
conditions.push(eq(annotations.jobExecutionId, params.jobExecutionId));
|
|
58
|
+
}
|
|
59
|
+
const { rows, stepRows } = await db().transaction(async (tx)=>{
|
|
60
|
+
// Both aggregates must observe the same committed state. READ COMMITTED would allow a
|
|
61
|
+
// concurrent annotation write between these selects, producing contradictory totals.
|
|
62
|
+
await tx.execute(sql`set transaction isolation level repeatable read, read only`);
|
|
63
|
+
const rows = await tx.select({
|
|
64
|
+
style: annotations.style,
|
|
65
|
+
count: count()
|
|
66
|
+
}).from(annotations).where(and(...conditions)).groupBy(annotations.style);
|
|
67
|
+
const stepRows = await tx.select({
|
|
68
|
+
originStepId: annotations.originStepId,
|
|
69
|
+
originStepAttempt: annotations.originStepAttempt,
|
|
70
|
+
total: count()
|
|
71
|
+
}).from(annotations).where(and(...conditions)).groupBy(annotations.originStepId, annotations.originStepAttempt).orderBy(asc(annotations.originStepId), asc(annotations.originStepAttempt));
|
|
72
|
+
return {
|
|
73
|
+
rows,
|
|
74
|
+
stepRows
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
for (const row of rows){
|
|
78
|
+
const value = Number(row.count);
|
|
79
|
+
summary.total += value;
|
|
80
|
+
if (row.style !== 'default') summary[row.style] += value;
|
|
81
|
+
}
|
|
82
|
+
summary.stepCounts = stepRows.map((row)=>({
|
|
83
|
+
originStepId: row.originStepId,
|
|
84
|
+
originStepAttempt: row.originStepAttempt,
|
|
85
|
+
total: Number(row.total)
|
|
86
|
+
}));
|
|
87
|
+
return summary;
|
|
88
|
+
}
|
|
39
89
|
export function withAnnotationLock(jobExecutionId, work) {
|
|
40
90
|
return db().transaction(async (tx)=>{
|
|
41
91
|
await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${jobExecutionId}))`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/db/annotations.ts"],"sourcesContent":["import {type AnnotationStyleDto, READ_ANNOTATIONS_MAX_LIMIT} from '@shipfox/annotations-dto';\nimport {and, asc, eq, gt, inArray, or, type SQL, sql} from 'drizzle-orm';\nimport type {Annotation} from '#core/entities/annotation.js';\nimport {db} from './db.js';\nimport {annotations, toAnnotation} from './schema/annotations.js';\n\nexport const DEFAULT_ANNOTATIONS_READ_LIMIT = READ_ANNOTATIONS_MAX_LIMIT;\n\nexport interface ListAnnotationsForRunAttemptParams {\n workflowRunId: string;\n workflowRunAttempt: number;\n workspaceIds: readonly string[];\n jobExecutionId?: string | undefined;\n after?: {sequence: number; id: string} | undefined;\n limit?: number | undefined;\n}\n\nexport interface ListAnnotationsForRunAttemptResult {\n annotations: Annotation[];\n hasMore: boolean;\n nextCursor: {sequence: number; id: string} | null;\n}\n\nexport async function listAnnotationsForRunAttempt(\n params: ListAnnotationsForRunAttemptParams,\n): Promise<ListAnnotationsForRunAttemptResult> {\n if (params.workspaceIds.length === 0) return {annotations: [], hasMore: false, nextCursor: null};\n\n const limit = params.limit ?? DEFAULT_ANNOTATIONS_READ_LIMIT;\n\n const conditions: SQL[] = [\n eq(annotations.workflowRunId, params.workflowRunId),\n eq(annotations.workflowRunAttempt, params.workflowRunAttempt),\n inArray(annotations.workspaceId, [...params.workspaceIds]),\n ];\n if (params.jobExecutionId) {\n conditions.push(eq(annotations.jobExecutionId, params.jobExecutionId));\n }\n if (params.after) {\n const cursorCondition = or(\n gt(annotations.sequence, params.after.sequence),\n and(eq(annotations.sequence, params.after.sequence), gt(annotations.id, params.after.id)),\n );\n if (cursorCondition) conditions.push(cursorCondition);\n }\n\n const rows = await db()\n .select()\n .from(annotations)\n .where(and(...conditions))\n .orderBy(asc(annotations.sequence), asc(annotations.id))\n .limit(limit + 1);\n\n const pageRows = rows.slice(0, limit);\n const last = pageRows.at(-1);\n\n return {\n annotations: pageRows.map(toAnnotation),\n hasMore: rows.length > limit,\n nextCursor: rows.length > limit && last ? {sequence: last.sequence, id: last.id} : null,\n };\n}\n\nexport interface StoredAnnotation {\n id: string;\n context: string;\n style: AnnotationStyleDto;\n body: string;\n bodyBytes: number;\n sequence: number;\n}\n\nexport interface CreateAnnotationParams {\n workspaceId: string;\n projectId: string;\n workflowRunId: string;\n workflowRunAttempt: number;\n workflowRunAttemptId: string;\n jobId: string;\n jobExecutionId: string;\n originStepId: string;\n originStepAttempt: number;\n context: string;\n style: AnnotationStyleDto;\n body: string;\n bodyBytes: number;\n sequence: number;\n}\n\nexport interface UpdateAnnotationParams {\n id: string;\n originStepId: string;\n originStepAttempt: number;\n style: AnnotationStyleDto;\n body: string;\n bodyBytes: number;\n}\n\nexport interface AnnotationWriteRepository {\n loadCurrentAnnotations(jobExecutionId: string): Promise<Map<string, StoredAnnotation>>;\n removeAnnotation(jobExecutionId: string, context: string): Promise<void>;\n createAnnotation(params: CreateAnnotationParams): Promise<StoredAnnotation>;\n updateAnnotation(params: UpdateAnnotationParams): Promise<StoredAnnotation>;\n}\n\nexport function withAnnotationLock<T>(\n jobExecutionId: string,\n work: (repo: AnnotationWriteRepository) => Promise<T>,\n): Promise<T> {\n return db().transaction(async (tx) => {\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${jobExecutionId}))`);\n\n const repo: AnnotationWriteRepository = {\n loadCurrentAnnotations: async (lockedJobExecutionId) => {\n const rows = await tx\n .select({\n id: annotations.id,\n context: annotations.context,\n style: annotations.style,\n body: annotations.body,\n bodyBytes: annotations.bodyBytes,\n sequence: annotations.sequence,\n })\n .from(annotations)\n .where(eq(annotations.jobExecutionId, lockedJobExecutionId));\n\n return new Map(rows.map((row) => [row.context, row]));\n },\n removeAnnotation: async (lockedJobExecutionId, context) => {\n await tx\n .delete(annotations)\n .where(\n and(\n eq(annotations.jobExecutionId, lockedJobExecutionId),\n eq(annotations.context, context),\n ),\n );\n },\n createAnnotation: async (params) => {\n const [row] = await tx.insert(annotations).values(params).returning({\n id: annotations.id,\n context: annotations.context,\n style: annotations.style,\n body: annotations.body,\n bodyBytes: annotations.bodyBytes,\n sequence: annotations.sequence,\n });\n\n if (!row) throw new Error('createAnnotation: insert returned no row');\n return row;\n },\n updateAnnotation: async (params) => {\n const [row] = await tx\n .update(annotations)\n .set({\n originStepId: params.originStepId,\n originStepAttempt: params.originStepAttempt,\n style: params.style,\n body: params.body,\n bodyBytes: params.bodyBytes,\n updatedAt: new Date(),\n })\n .where(eq(annotations.id, params.id))\n .returning({\n id: annotations.id,\n context: annotations.context,\n style: annotations.style,\n body: annotations.body,\n bodyBytes: annotations.bodyBytes,\n sequence: annotations.sequence,\n });\n\n if (!row) throw new Error('updateAnnotation: update returned no row');\n return row;\n },\n };\n\n return await work(repo);\n });\n}\n"],"names":["READ_ANNOTATIONS_MAX_LIMIT","and","asc","eq","gt","inArray","or","sql","db","annotations","toAnnotation","DEFAULT_ANNOTATIONS_READ_LIMIT","listAnnotationsForRunAttempt","params","workspaceIds","length","hasMore","nextCursor","limit","conditions","workflowRunId","workflowRunAttempt","workspaceId","jobExecutionId","push","after","cursorCondition","sequence","id","rows","select","from","where","orderBy","pageRows","slice","last","at","map","withAnnotationLock","work","transaction","tx","execute","repo","loadCurrentAnnotations","lockedJobExecutionId","context","style","body","bodyBytes","Map","row","removeAnnotation","delete","createAnnotation","insert","values","returning","Error","updateAnnotation","update","set","originStepId","originStepAttempt","updatedAt","Date"],"mappings":"AAAA,SAAiCA,0BAA0B,QAAO,2BAA2B;AAC7F,SAAQC,GAAG,EAAEC,GAAG,EAAEC,EAAE,EAAEC,EAAE,EAAEC,OAAO,EAAEC,EAAE,EAAYC,GAAG,QAAO,cAAc;AAEzE,SAAQC,EAAE,QAAO,UAAU;AAC3B,SAAQC,WAAW,EAAEC,YAAY,QAAO,0BAA0B;AAElE,OAAO,MAAMC,iCAAiCX,2BAA2B;AAiBzE,OAAO,eAAeY,6BACpBC,MAA0C;IAE1C,IAAIA,OAAOC,YAAY,CAACC,MAAM,KAAK,GAAG,OAAO;QAACN,aAAa,EAAE;QAAEO,SAAS;QAAOC,YAAY;IAAI;IAE/F,MAAMC,QAAQL,OAAOK,KAAK,IAAIP;IAE9B,MAAMQ,aAAoB;QACxBhB,GAAGM,YAAYW,aAAa,EAAEP,OAAOO,aAAa;QAClDjB,GAAGM,YAAYY,kBAAkB,EAAER,OAAOQ,kBAAkB;QAC5DhB,QAAQI,YAAYa,WAAW,EAAE;eAAIT,OAAOC,YAAY;SAAC;KAC1D;IACD,IAAID,OAAOU,cAAc,EAAE;QACzBJ,WAAWK,IAAI,CAACrB,GAAGM,YAAYc,cAAc,EAAEV,OAAOU,cAAc;IACtE;IACA,IAAIV,OAAOY,KAAK,EAAE;QAChB,MAAMC,kBAAkBpB,GACtBF,GAAGK,YAAYkB,QAAQ,EAAEd,OAAOY,KAAK,CAACE,QAAQ,GAC9C1B,IAAIE,GAAGM,YAAYkB,QAAQ,EAAEd,OAAOY,KAAK,CAACE,QAAQ,GAAGvB,GAAGK,YAAYmB,EAAE,EAAEf,OAAOY,KAAK,CAACG,EAAE;QAEzF,IAAIF,iBAAiBP,WAAWK,IAAI,CAACE;IACvC;IAEA,MAAMG,OAAO,MAAMrB,KAChBsB,MAAM,GACNC,IAAI,CAACtB,aACLuB,KAAK,CAAC/B,OAAOkB,aACbc,OAAO,CAAC/B,IAAIO,YAAYkB,QAAQ,GAAGzB,IAAIO,YAAYmB,EAAE,GACrDV,KAAK,CAACA,QAAQ;IAEjB,MAAMgB,WAAWL,KAAKM,KAAK,CAAC,GAAGjB;IAC/B,MAAMkB,OAAOF,SAASG,EAAE,CAAC,CAAC;IAE1B,OAAO;QACL5B,aAAayB,SAASI,GAAG,CAAC5B;QAC1BM,SAASa,KAAKd,MAAM,GAAGG;QACvBD,YAAYY,KAAKd,MAAM,GAAGG,SAASkB,OAAO;YAACT,UAAUS,KAAKT,QAAQ;YAAEC,IAAIQ,KAAKR,EAAE;QAAA,IAAI;IACrF;AACF;AA4CA,OAAO,SAASW,mBACdhB,cAAsB,EACtBiB,IAAqD;IAErD,OAAOhC,KAAKiC,WAAW,CAAC,OAAOC;QAC7B,MAAMA,GAAGC,OAAO,CAACpC,GAAG,CAAC,sCAAsC,EAAEgB,eAAe,EAAE,CAAC;QAE/E,MAAMqB,OAAkC;YACtCC,wBAAwB,OAAOC;gBAC7B,MAAMjB,OAAO,MAAMa,GAChBZ,MAAM,CAAC;oBACNF,IAAInB,YAAYmB,EAAE;oBAClBmB,SAAStC,YAAYsC,OAAO;oBAC5BC,OAAOvC,YAAYuC,KAAK;oBACxBC,MAAMxC,YAAYwC,IAAI;oBACtBC,WAAWzC,YAAYyC,SAAS;oBAChCvB,UAAUlB,YAAYkB,QAAQ;gBAChC,GACCI,IAAI,CAACtB,aACLuB,KAAK,CAAC7B,GAAGM,YAAYc,cAAc,EAAEuB;gBAExC,OAAO,IAAIK,IAAItB,KAAKS,GAAG,CAAC,CAACc,MAAQ;wBAACA,IAAIL,OAAO;wBAAEK;qBAAI;YACrD;YACAC,kBAAkB,OAAOP,sBAAsBC;gBAC7C,MAAML,GACHY,MAAM,CAAC7C,aACPuB,KAAK,CACJ/B,IACEE,GAAGM,YAAYc,cAAc,EAAEuB,uBAC/B3C,GAAGM,YAAYsC,OAAO,EAAEA;YAGhC;YACAQ,kBAAkB,OAAO1C;gBACvB,MAAM,CAACuC,IAAI,GAAG,MAAMV,GAAGc,MAAM,CAAC/C,aAAagD,MAAM,CAAC5C,QAAQ6C,SAAS,CAAC;oBAClE9B,IAAInB,YAAYmB,EAAE;oBAClBmB,SAAStC,YAAYsC,OAAO;oBAC5BC,OAAOvC,YAAYuC,KAAK;oBACxBC,MAAMxC,YAAYwC,IAAI;oBACtBC,WAAWzC,YAAYyC,SAAS;oBAChCvB,UAAUlB,YAAYkB,QAAQ;gBAChC;gBAEA,IAAI,CAACyB,KAAK,MAAM,IAAIO,MAAM;gBAC1B,OAAOP;YACT;YACAQ,kBAAkB,OAAO/C;gBACvB,MAAM,CAACuC,IAAI,GAAG,MAAMV,GACjBmB,MAAM,CAACpD,aACPqD,GAAG,CAAC;oBACHC,cAAclD,OAAOkD,YAAY;oBACjCC,mBAAmBnD,OAAOmD,iBAAiB;oBAC3ChB,OAAOnC,OAAOmC,KAAK;oBACnBC,MAAMpC,OAAOoC,IAAI;oBACjBC,WAAWrC,OAAOqC,SAAS;oBAC3Be,WAAW,IAAIC;gBACjB,GACClC,KAAK,CAAC7B,GAAGM,YAAYmB,EAAE,EAAEf,OAAOe,EAAE,GAClC8B,SAAS,CAAC;oBACT9B,IAAInB,YAAYmB,EAAE;oBAClBmB,SAAStC,YAAYsC,OAAO;oBAC5BC,OAAOvC,YAAYuC,KAAK;oBACxBC,MAAMxC,YAAYwC,IAAI;oBACtBC,WAAWzC,YAAYyC,SAAS;oBAChCvB,UAAUlB,YAAYkB,QAAQ;gBAChC;gBAEF,IAAI,CAACyB,KAAK,MAAM,IAAIO,MAAM;gBAC1B,OAAOP;YACT;QACF;QAEA,OAAO,MAAMZ,KAAKI;IACpB;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../src/db/annotations.ts"],"sourcesContent":["import {type AnnotationStyleDto, READ_ANNOTATIONS_MAX_LIMIT} from '@shipfox/annotations-dto';\nimport {and, asc, count, eq, gt, inArray, or, type SQL, sql} from 'drizzle-orm';\nimport type {Annotation} from '#core/entities/annotation.js';\nimport {db} from './db.js';\nimport {annotations, toAnnotation} from './schema/annotations.js';\n\nexport const DEFAULT_ANNOTATIONS_READ_LIMIT = READ_ANNOTATIONS_MAX_LIMIT;\n\nexport interface ListAnnotationsForRunAttemptParams {\n workflowRunId: string;\n workflowRunAttempt: number;\n workspaceIds: readonly string[];\n jobExecutionId?: string | undefined;\n after?: {sequence: number; id: string} | undefined;\n limit?: number | undefined;\n}\n\nexport interface ListAnnotationsForRunAttemptResult {\n annotations: Annotation[];\n hasMore: boolean;\n nextCursor: {sequence: number; id: string} | null;\n}\n\nexport async function listAnnotationsForRunAttempt(\n params: ListAnnotationsForRunAttemptParams,\n): Promise<ListAnnotationsForRunAttemptResult> {\n if (params.workspaceIds.length === 0) return {annotations: [], hasMore: false, nextCursor: null};\n\n const limit = params.limit ?? DEFAULT_ANNOTATIONS_READ_LIMIT;\n\n const conditions: SQL[] = [\n eq(annotations.workflowRunId, params.workflowRunId),\n eq(annotations.workflowRunAttempt, params.workflowRunAttempt),\n inArray(annotations.workspaceId, [...params.workspaceIds]),\n ];\n if (params.jobExecutionId) {\n conditions.push(eq(annotations.jobExecutionId, params.jobExecutionId));\n }\n if (params.after) {\n const cursorCondition = or(\n gt(annotations.sequence, params.after.sequence),\n and(eq(annotations.sequence, params.after.sequence), gt(annotations.id, params.after.id)),\n );\n if (cursorCondition) conditions.push(cursorCondition);\n }\n\n const rows = await db()\n .select()\n .from(annotations)\n .where(and(...conditions))\n .orderBy(asc(annotations.sequence), asc(annotations.id))\n .limit(limit + 1);\n\n const pageRows = rows.slice(0, limit);\n const last = pageRows.at(-1);\n\n return {\n annotations: pageRows.map(toAnnotation),\n hasMore: rows.length > limit,\n nextCursor: rows.length > limit && last ? {sequence: last.sequence, id: last.id} : null,\n };\n}\n\nexport interface AnnotationSummary {\n total: number;\n error: number;\n warning: number;\n info: number;\n success: number;\n stepCounts: Array<{\n originStepId: string;\n originStepAttempt: number;\n total: number;\n }>;\n}\n\nexport interface SummarizeAnnotationsForRunAttemptParams {\n workflowRunId: string;\n workflowRunAttempt: number;\n workspaceIds: readonly string[];\n jobExecutionId?: string | undefined;\n}\n\n/** Count annotation styles without reading any annotation bodies. */\nexport async function summarizeAnnotationsForRunAttempt(\n params: SummarizeAnnotationsForRunAttemptParams,\n): Promise<AnnotationSummary> {\n const summary: AnnotationSummary = {\n total: 0,\n error: 0,\n warning: 0,\n info: 0,\n success: 0,\n stepCounts: [],\n };\n if (params.workspaceIds.length === 0) return summary;\n\n const conditions: SQL[] = [\n eq(annotations.workflowRunId, params.workflowRunId),\n eq(annotations.workflowRunAttempt, params.workflowRunAttempt),\n inArray(annotations.workspaceId, [...params.workspaceIds]),\n ];\n if (params.jobExecutionId) {\n conditions.push(eq(annotations.jobExecutionId, params.jobExecutionId));\n }\n\n const {rows, stepRows} = await db().transaction(async (tx) => {\n // Both aggregates must observe the same committed state. READ COMMITTED would allow a\n // concurrent annotation write between these selects, producing contradictory totals.\n await tx.execute(sql`set transaction isolation level repeatable read, read only`);\n\n const rows = await tx\n .select({style: annotations.style, count: count()})\n .from(annotations)\n .where(and(...conditions))\n .groupBy(annotations.style);\n\n const stepRows = await tx\n .select({\n originStepId: annotations.originStepId,\n originStepAttempt: annotations.originStepAttempt,\n total: count(),\n })\n .from(annotations)\n .where(and(...conditions))\n .groupBy(annotations.originStepId, annotations.originStepAttempt)\n .orderBy(asc(annotations.originStepId), asc(annotations.originStepAttempt));\n\n return {rows, stepRows};\n });\n\n for (const row of rows) {\n const value = Number(row.count);\n summary.total += value;\n if (row.style !== 'default') summary[row.style] += value;\n }\n\n summary.stepCounts = stepRows.map((row) => ({\n originStepId: row.originStepId,\n originStepAttempt: row.originStepAttempt,\n total: Number(row.total),\n }));\n\n return summary;\n}\n\nexport interface StoredAnnotation {\n id: string;\n context: string;\n style: AnnotationStyleDto;\n body: string;\n bodyBytes: number;\n sequence: number;\n}\n\nexport interface CreateAnnotationParams {\n workspaceId: string;\n projectId: string;\n workflowRunId: string;\n workflowRunAttempt: number;\n workflowRunAttemptId: string;\n jobId: string;\n jobExecutionId: string;\n originStepId: string;\n originStepAttempt: number;\n context: string;\n style: AnnotationStyleDto;\n body: string;\n bodyBytes: number;\n sequence: number;\n}\n\nexport interface UpdateAnnotationParams {\n id: string;\n originStepId: string;\n originStepAttempt: number;\n style: AnnotationStyleDto;\n body: string;\n bodyBytes: number;\n}\n\nexport interface AnnotationWriteRepository {\n loadCurrentAnnotations(jobExecutionId: string): Promise<Map<string, StoredAnnotation>>;\n removeAnnotation(jobExecutionId: string, context: string): Promise<void>;\n createAnnotation(params: CreateAnnotationParams): Promise<StoredAnnotation>;\n updateAnnotation(params: UpdateAnnotationParams): Promise<StoredAnnotation>;\n}\n\nexport function withAnnotationLock<T>(\n jobExecutionId: string,\n work: (repo: AnnotationWriteRepository) => Promise<T>,\n): Promise<T> {\n return db().transaction(async (tx) => {\n await tx.execute(sql`select pg_advisory_xact_lock(hashtext(${jobExecutionId}))`);\n\n const repo: AnnotationWriteRepository = {\n loadCurrentAnnotations: async (lockedJobExecutionId) => {\n const rows = await tx\n .select({\n id: annotations.id,\n context: annotations.context,\n style: annotations.style,\n body: annotations.body,\n bodyBytes: annotations.bodyBytes,\n sequence: annotations.sequence,\n })\n .from(annotations)\n .where(eq(annotations.jobExecutionId, lockedJobExecutionId));\n\n return new Map(rows.map((row) => [row.context, row]));\n },\n removeAnnotation: async (lockedJobExecutionId, context) => {\n await tx\n .delete(annotations)\n .where(\n and(\n eq(annotations.jobExecutionId, lockedJobExecutionId),\n eq(annotations.context, context),\n ),\n );\n },\n createAnnotation: async (params) => {\n const [row] = await tx.insert(annotations).values(params).returning({\n id: annotations.id,\n context: annotations.context,\n style: annotations.style,\n body: annotations.body,\n bodyBytes: annotations.bodyBytes,\n sequence: annotations.sequence,\n });\n\n if (!row) throw new Error('createAnnotation: insert returned no row');\n return row;\n },\n updateAnnotation: async (params) => {\n const [row] = await tx\n .update(annotations)\n .set({\n originStepId: params.originStepId,\n originStepAttempt: params.originStepAttempt,\n style: params.style,\n body: params.body,\n bodyBytes: params.bodyBytes,\n updatedAt: new Date(),\n })\n .where(eq(annotations.id, params.id))\n .returning({\n id: annotations.id,\n context: annotations.context,\n style: annotations.style,\n body: annotations.body,\n bodyBytes: annotations.bodyBytes,\n sequence: annotations.sequence,\n });\n\n if (!row) throw new Error('updateAnnotation: update returned no row');\n return row;\n },\n };\n\n return await work(repo);\n });\n}\n"],"names":["READ_ANNOTATIONS_MAX_LIMIT","and","asc","count","eq","gt","inArray","or","sql","db","annotations","toAnnotation","DEFAULT_ANNOTATIONS_READ_LIMIT","listAnnotationsForRunAttempt","params","workspaceIds","length","hasMore","nextCursor","limit","conditions","workflowRunId","workflowRunAttempt","workspaceId","jobExecutionId","push","after","cursorCondition","sequence","id","rows","select","from","where","orderBy","pageRows","slice","last","at","map","summarizeAnnotationsForRunAttempt","summary","total","error","warning","info","success","stepCounts","stepRows","transaction","tx","execute","style","groupBy","originStepId","originStepAttempt","row","value","Number","withAnnotationLock","work","repo","loadCurrentAnnotations","lockedJobExecutionId","context","body","bodyBytes","Map","removeAnnotation","delete","createAnnotation","insert","values","returning","Error","updateAnnotation","update","set","updatedAt","Date"],"mappings":"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"}
|
package/dist/db/db.d.ts
CHANGED
|
@@ -196,7 +196,7 @@ export declare const schema: {
|
|
|
196
196
|
tableName: "annotations";
|
|
197
197
|
dataType: "string";
|
|
198
198
|
columnType: "PgEnumColumn";
|
|
199
|
-
data: "default" | "
|
|
199
|
+
data: "default" | "error" | "info" | "success" | "warning";
|
|
200
200
|
driverParam: string;
|
|
201
201
|
notNull: true;
|
|
202
202
|
hasDefault: true;
|
|
@@ -294,7 +294,7 @@ export declare const schema: {
|
|
|
294
294
|
generated: undefined;
|
|
295
295
|
}, {}, {}>;
|
|
296
296
|
};
|
|
297
|
-
dialect:
|
|
297
|
+
dialect: 'pg';
|
|
298
298
|
}>;
|
|
299
299
|
};
|
|
300
300
|
export type Database = NodePgDatabase<typeof schema>;
|
package/dist/db/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const migrationsPath: string;
|
|
2
|
-
export type { ListAnnotationsForRunAttemptParams } from './annotations.js';
|
|
3
|
-
export { DEFAULT_ANNOTATIONS_READ_LIMIT, listAnnotationsForRunAttempt } from './annotations.js';
|
|
2
|
+
export type { AnnotationSummary, ListAnnotationsForRunAttemptParams, SummarizeAnnotationsForRunAttemptParams, } from './annotations.js';
|
|
3
|
+
export { DEFAULT_ANNOTATIONS_READ_LIMIT, listAnnotationsForRunAttempt, summarizeAnnotationsForRunAttempt, } from './annotations.js';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/db/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc,QAAoE,CAAC;AAEhG,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc,QAAoE,CAAC;AAEhG,YAAY,EACV,iBAAiB,EACjB,kCAAkC,EAClC,uCAAuC,GACxC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,8BAA8B,EAC9B,4BAA4B,EAC5B,iCAAiC,GAClC,MAAM,kBAAkB,CAAC"}
|
package/dist/db/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { dirname, resolve } from 'node:path';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
export const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');
|
|
4
|
-
export { DEFAULT_ANNOTATIONS_READ_LIMIT, listAnnotationsForRunAttempt } from './annotations.js';
|
|
4
|
+
export { DEFAULT_ANNOTATIONS_READ_LIMIT, listAnnotationsForRunAttempt, summarizeAnnotationsForRunAttempt } from './annotations.js';
|
|
5
5
|
|
|
6
6
|
//# sourceMappingURL=index.js.map
|
package/dist/db/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/db/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\n\nexport const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');\n\nexport type {ListAnnotationsForRunAttemptParams} from './annotations.js';\nexport {DEFAULT_ANNOTATIONS_READ_LIMIT
|
|
1
|
+
{"version":3,"sources":["../../src/db/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\n\nexport const migrationsPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../drizzle');\n\nexport type {\n AnnotationSummary,\n ListAnnotationsForRunAttemptParams,\n SummarizeAnnotationsForRunAttemptParams,\n} from './annotations.js';\nexport {\n DEFAULT_ANNOTATIONS_READ_LIMIT,\n listAnnotationsForRunAttempt,\n summarizeAnnotationsForRunAttempt,\n} from './annotations.js';\n"],"names":["dirname","resolve","fileURLToPath","migrationsPath","url","DEFAULT_ANNOTATIONS_READ_LIMIT","listAnnotationsForRunAttempt","summarizeAnnotationsForRunAttempt"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAY;AAC3C,SAAQC,aAAa,QAAO,WAAW;AAEvC,OAAO,MAAMC,iBAAiBF,QAAQD,QAAQE,cAAc,YAAYE,GAAG,IAAI,iBAAiB;AAOhG,SACEC,8BAA8B,EAC9BC,4BAA4B,EAC5BC,iCAAiC,QAC5B,mBAAmB"}
|
|
@@ -196,7 +196,7 @@ export declare const annotations: import("drizzle-orm/pg-core").PgTableWithColum
|
|
|
196
196
|
tableName: "annotations";
|
|
197
197
|
dataType: "string";
|
|
198
198
|
columnType: "PgEnumColumn";
|
|
199
|
-
data: "default" | "
|
|
199
|
+
data: "default" | "error" | "info" | "success" | "warning";
|
|
200
200
|
driverParam: string;
|
|
201
201
|
notNull: true;
|
|
202
202
|
hasDefault: true;
|
|
@@ -294,7 +294,7 @@ export declare const annotations: import("drizzle-orm/pg-core").PgTableWithColum
|
|
|
294
294
|
generated: undefined;
|
|
295
295
|
}, {}, {}>;
|
|
296
296
|
};
|
|
297
|
-
dialect:
|
|
297
|
+
dialect: 'pg';
|
|
298
298
|
}>;
|
|
299
299
|
export type AnnotationDb = typeof annotations.$inferSelect;
|
|
300
300
|
export type AnnotationCreateDb = typeof annotations.$inferInsert;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AAKtD,eAAO,MAAM,iBAAiB,EAAE,UAAU,EAWzC,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AUTH_LEASED_JOB, AUTH_USER } from '@shipfox/api-auth-context';
|
|
2
|
+
import { readAnnotationSummaryRoute } from './read-annotation-summary.js';
|
|
2
3
|
import { readAnnotationsRoute } from './read-annotations.js';
|
|
3
4
|
import { writeAnnotationsRoute } from './write-annotations.js';
|
|
4
5
|
export const annotationsRoutes = [
|
|
@@ -6,6 +7,7 @@ export const annotationsRoutes = [
|
|
|
6
7
|
prefix: '/annotations',
|
|
7
8
|
auth: AUTH_USER,
|
|
8
9
|
routes: [
|
|
10
|
+
readAnnotationSummaryRoute,
|
|
9
11
|
readAnnotationsRoute
|
|
10
12
|
]
|
|
11
13
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/presentation/routes/index.ts"],"sourcesContent":["import {AUTH_LEASED_JOB, AUTH_USER} from '@shipfox/api-auth-context';\nimport type {RouteGroup} from '@shipfox/node-fastify';\nimport {readAnnotationsRoute} from './read-annotations.js';\nimport {writeAnnotationsRoute} from './write-annotations.js';\n\nexport const annotationsRoutes: RouteGroup[] = [\n {\n prefix: '/annotations',\n auth: AUTH_USER,\n routes: [readAnnotationsRoute],\n },\n {\n prefix: '/runs/jobs/current',\n auth: AUTH_LEASED_JOB,\n routes: [writeAnnotationsRoute],\n },\n];\n"],"names":["AUTH_LEASED_JOB","AUTH_USER","readAnnotationsRoute","writeAnnotationsRoute","annotationsRoutes","prefix","auth","routes"],"mappings":"AAAA,SAAQA,eAAe,EAAEC,SAAS,QAAO,4BAA4B;AAErE,SAAQC,oBAAoB,QAAO,wBAAwB;AAC3D,SAAQC,qBAAqB,QAAO,yBAAyB;AAE7D,OAAO,MAAMC,oBAAkC;IAC7C;QACEC,QAAQ;QACRC,
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/index.ts"],"sourcesContent":["import {AUTH_LEASED_JOB, AUTH_USER} from '@shipfox/api-auth-context';\nimport type {RouteGroup} from '@shipfox/node-fastify';\nimport {readAnnotationSummaryRoute} from './read-annotation-summary.js';\nimport {readAnnotationsRoute} from './read-annotations.js';\nimport {writeAnnotationsRoute} from './write-annotations.js';\n\nexport const annotationsRoutes: RouteGroup[] = [\n {\n prefix: '/annotations',\n auth: AUTH_USER,\n routes: [readAnnotationSummaryRoute, readAnnotationsRoute],\n },\n {\n prefix: '/runs/jobs/current',\n auth: AUTH_LEASED_JOB,\n routes: [writeAnnotationsRoute],\n },\n];\n"],"names":["AUTH_LEASED_JOB","AUTH_USER","readAnnotationSummaryRoute","readAnnotationsRoute","writeAnnotationsRoute","annotationsRoutes","prefix","auth","routes"],"mappings":"AAAA,SAAQA,eAAe,EAAEC,SAAS,QAAO,4BAA4B;AAErE,SAAQC,0BAA0B,QAAO,+BAA+B;AACxE,SAAQC,oBAAoB,QAAO,wBAAwB;AAC3D,SAAQC,qBAAqB,QAAO,yBAAyB;AAE7D,OAAO,MAAMC,oBAAkC;IAC7C;QACEC,QAAQ;QACRC,MAAMN;QACNO,QAAQ;YAACN;YAA4BC;SAAqB;IAC5D;IACA;QACEG,QAAQ;QACRC,MAAMP;QACNQ,QAAQ;YAACJ;SAAsB;IACjC;CACD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-annotation-summary.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/read-annotation-summary.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,0BAA0B,iDAyCrC,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { annotationSummaryResponseSchema, readAnnotationsQuerySchema } from '@shipfox/annotations-dto';
|
|
2
|
+
import { requireUserContext } from '@shipfox/api-auth-context';
|
|
3
|
+
import { defineRoute } from '@shipfox/node-fastify';
|
|
4
|
+
import { summarizeAnnotationsForRunAttempt } from '#db/index.js';
|
|
5
|
+
export const readAnnotationSummaryRoute = defineRoute({
|
|
6
|
+
method: 'GET',
|
|
7
|
+
path: '/summary',
|
|
8
|
+
description: 'Read annotation counts for a workflow run attempt.',
|
|
9
|
+
schema: {
|
|
10
|
+
querystring: readAnnotationsQuerySchema.omit({
|
|
11
|
+
cursor: true,
|
|
12
|
+
limit: true
|
|
13
|
+
}),
|
|
14
|
+
response: {
|
|
15
|
+
200: annotationSummaryResponseSchema
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
handler: async (request)=>{
|
|
19
|
+
const user = requireUserContext(request);
|
|
20
|
+
const { workflow_run_id: workflowRunId, attempt, job_execution_id: jobExecutionId } = request.query;
|
|
21
|
+
const workspaceIds = user.memberships.filter((membership)=>membership.workspaceStatus === 'active').map((membership)=>membership.workspaceId);
|
|
22
|
+
const summary = await summarizeAnnotationsForRunAttempt({
|
|
23
|
+
workflowRunId,
|
|
24
|
+
workflowRunAttempt: attempt,
|
|
25
|
+
workspaceIds,
|
|
26
|
+
jobExecutionId
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
total: summary.total,
|
|
30
|
+
error: summary.error,
|
|
31
|
+
warning: summary.warning,
|
|
32
|
+
info: summary.info,
|
|
33
|
+
success: summary.success,
|
|
34
|
+
step_counts: summary.stepCounts.map((step)=>({
|
|
35
|
+
origin_step_id: step.originStepId,
|
|
36
|
+
origin_step_attempt: step.originStepAttempt,
|
|
37
|
+
total: step.total
|
|
38
|
+
}))
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=read-annotation-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/read-annotation-summary.ts"],"sourcesContent":["import {\n annotationSummaryResponseSchema,\n readAnnotationsQuerySchema,\n} from '@shipfox/annotations-dto';\nimport {requireUserContext} from '@shipfox/api-auth-context';\nimport {defineRoute} from '@shipfox/node-fastify';\nimport {summarizeAnnotationsForRunAttempt} from '#db/index.js';\n\nexport const readAnnotationSummaryRoute = defineRoute({\n method: 'GET',\n path: '/summary',\n description: 'Read annotation counts for a workflow run attempt.',\n schema: {\n querystring: readAnnotationsQuerySchema.omit({cursor: true, limit: true}),\n response: {\n 200: annotationSummaryResponseSchema,\n },\n },\n handler: async (request) => {\n const user = requireUserContext(request);\n const {\n workflow_run_id: workflowRunId,\n attempt,\n job_execution_id: jobExecutionId,\n } = request.query;\n const workspaceIds = user.memberships\n .filter((membership) => membership.workspaceStatus === 'active')\n .map((membership) => membership.workspaceId);\n\n const summary = await summarizeAnnotationsForRunAttempt({\n workflowRunId,\n workflowRunAttempt: attempt,\n workspaceIds,\n jobExecutionId,\n });\n\n return {\n total: summary.total,\n error: summary.error,\n warning: summary.warning,\n info: summary.info,\n success: summary.success,\n step_counts: summary.stepCounts.map((step) => ({\n origin_step_id: step.originStepId,\n origin_step_attempt: step.originStepAttempt,\n total: step.total,\n })),\n };\n },\n});\n"],"names":["annotationSummaryResponseSchema","readAnnotationsQuerySchema","requireUserContext","defineRoute","summarizeAnnotationsForRunAttempt","readAnnotationSummaryRoute","method","path","description","schema","querystring","omit","cursor","limit","response","handler","request","user","workflow_run_id","workflowRunId","attempt","job_execution_id","jobExecutionId","query","workspaceIds","memberships","filter","membership","workspaceStatus","map","workspaceId","summary","workflowRunAttempt","total","error","warning","info","success","step_counts","stepCounts","step","origin_step_id","originStepId","origin_step_attempt","originStepAttempt"],"mappings":"AAAA,SACEA,+BAA+B,EAC/BC,0BAA0B,QACrB,2BAA2B;AAClC,SAAQC,kBAAkB,QAAO,4BAA4B;AAC7D,SAAQC,WAAW,QAAO,wBAAwB;AAClD,SAAQC,iCAAiC,QAAO,eAAe;AAE/D,OAAO,MAAMC,6BAA6BF,YAAY;IACpDG,QAAQ;IACRC,MAAM;IACNC,aAAa;IACbC,QAAQ;QACNC,aAAaT,2BAA2BU,IAAI,CAAC;YAACC,QAAQ;YAAMC,OAAO;QAAI;QACvEC,UAAU;YACR,KAAKd;QACP;IACF;IACAe,SAAS,OAAOC;QACd,MAAMC,OAAOf,mBAAmBc;QAChC,MAAM,EACJE,iBAAiBC,aAAa,EAC9BC,OAAO,EACPC,kBAAkBC,cAAc,EACjC,GAAGN,QAAQO,KAAK;QACjB,MAAMC,eAAeP,KAAKQ,WAAW,CAClCC,MAAM,CAAC,CAACC,aAAeA,WAAWC,eAAe,KAAK,UACtDC,GAAG,CAAC,CAACF,aAAeA,WAAWG,WAAW;QAE7C,MAAMC,UAAU,MAAM3B,kCAAkC;YACtDe;YACAa,oBAAoBZ;YACpBI;YACAF;QACF;QAEA,OAAO;YACLW,OAAOF,QAAQE,KAAK;YACpBC,OAAOH,QAAQG,KAAK;YACpBC,SAASJ,QAAQI,OAAO;YACxBC,MAAML,QAAQK,IAAI;YAClBC,SAASN,QAAQM,OAAO;YACxBC,aAAaP,QAAQQ,UAAU,CAACV,GAAG,CAAC,CAACW,OAAU,CAAA;oBAC7CC,gBAAgBD,KAAKE,YAAY;oBACjCC,qBAAqBH,KAAKI,iBAAiB;oBAC3CX,OAAOO,KAAKP,KAAK;gBACnB,CAAA;QACF;IACF;AACF,GAAG"}
|