@shipfox/api-workflows 10.1.0 → 11.0.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shipfox/api-workflows",
3
3
  "license": "MIT",
4
- "version": "10.1.0",
4
+ "version": "11.0.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/ShipfoxHQ/shipfox.git",
@@ -22,29 +22,29 @@
22
22
  "@temporalio/workflow": "1.18.1",
23
23
  "drizzle-orm": "^0.45.2",
24
24
  "zod": "^4.4.3",
25
- "@shipfox/api-auth-context": "10.1.0",
26
- "@shipfox/api-auth-dto": "10.1.0",
25
+ "@shipfox/api-auth-context": "11.0.0",
26
+ "@shipfox/api-auth-dto": "10.2.0",
27
27
  "@shipfox/api-agent-dto": "10.0.0",
28
28
  "@shipfox/annotations-dto": "9.0.2",
29
- "@shipfox/api-definitions-dto": "10.0.0",
29
+ "@shipfox/api-definitions-dto": "11.0.0",
30
30
  "@shipfox/api-projects-dto": "10.1.0",
31
31
  "@shipfox/api-integration-core-dto": "9.0.2",
32
- "@shipfox/api-runners-dto": "10.0.0",
33
32
  "@shipfox/api-secrets-dto": "9.0.2",
34
33
  "@shipfox/api-workflows-dto": "10.0.0",
35
- "@shipfox/api-workspaces-dto": "10.0.0",
36
34
  "@shipfox/inter-module": "0.2.2",
37
- "@shipfox/expression": "1.2.0",
35
+ "@shipfox/expression": "1.2.1",
36
+ "@shipfox/api-workspaces-dto": "11.0.0",
37
+ "@shipfox/api-runners-dto": "10.2.0",
38
38
  "@shipfox/node-drizzle": "0.3.4",
39
39
  "@shipfox/node-error-monitoring": "0.3.0",
40
- "@shipfox/node-fastify": "0.4.0",
41
40
  "@shipfox/node-module": "1.0.4",
42
41
  "@shipfox/node-opentelemetry": "0.6.3",
43
42
  "@shipfox/node-outbox": "0.2.6",
44
43
  "@shipfox/node-postgres": "0.4.4",
45
44
  "@shipfox/node-temporal": "0.4.4",
46
45
  "@shipfox/runner-labels": "0.1.3",
47
- "@shipfox/workflow-document": "2.1.3"
46
+ "@shipfox/workflow-document": "2.1.3",
47
+ "@shipfox/node-fastify": "0.4.0"
48
48
  },
49
49
  "imports": {
50
50
  "#*": "./dist/*"
@@ -34,7 +34,7 @@ describe('POST /api/workflows/runs/:id/cancel', () => {
34
34
  buildUserContext({
35
35
  userId: crypto.randomUUID(),
36
36
  email: 'user@example.com',
37
- memberships: [{workspaceId, role: 'admin'}],
37
+ memberships: [{workspaceId, role: 'admin', workspaceStatus: 'active'}],
38
38
  }),
39
39
  );
40
40
  done();
@@ -39,7 +39,7 @@ describe('GET /api/workflows/runs/aggregates', () => {
39
39
  buildUserContext({
40
40
  userId: crypto.randomUUID(),
41
41
  email: 'user@example.com',
42
- memberships: [{workspaceId, role: 'admin'}],
42
+ memberships: [{workspaceId, role: 'admin', workspaceStatus: 'active'}],
43
43
  }),
44
44
  );
45
45
  done();
@@ -49,6 +49,7 @@ const projects = {
49
49
  describe('GET /api/workflows/runs/:id', () => {
50
50
  let app: FastifyInstance;
51
51
  let workspaceId: string;
52
+ let workspaceStatus: 'active' | 'deleted';
52
53
 
53
54
  beforeAll(async () => {
54
55
  app = Fastify();
@@ -60,7 +61,7 @@ describe('GET /api/workflows/runs/:id', () => {
60
61
  buildUserContext({
61
62
  userId: crypto.randomUUID(),
62
63
  email: 'user@example.com',
63
- memberships: [{workspaceId, role: 'admin'}],
64
+ memberships: [{workspaceId, role: 'admin', workspaceStatus}],
64
65
  }),
65
66
  );
66
67
  done();
@@ -71,6 +72,7 @@ describe('GET /api/workflows/runs/:id', () => {
71
72
 
72
73
  beforeEach(() => {
73
74
  workspaceId = crypto.randomUUID();
75
+ workspaceStatus = 'active';
74
76
  projectAccessState.workspaceId = workspaceId;
75
77
  getProjectById.mockImplementation(({projectId}) =>
76
78
  Promise.resolve({
@@ -368,6 +370,30 @@ jobs:
368
370
  expect(detailSpy).not.toHaveBeenCalled();
369
371
  });
370
372
 
373
+ test('preserves workspace-inactive for a deleted membership claim', async () => {
374
+ workspaceStatus = 'deleted';
375
+ const run = await createWorkflowRun({
376
+ workspaceId,
377
+ projectId: crypto.randomUUID(),
378
+ definitionId: crypto.randomUUID(),
379
+ model: workflowModel({name: 'Test'}),
380
+ triggerPayload: {
381
+ source: 'manual',
382
+ event: 'fire',
383
+ subscriptionId: crypto.randomUUID(),
384
+ userId: crypto.randomUUID(),
385
+ },
386
+ });
387
+
388
+ const res = await app.inject({
389
+ method: 'GET',
390
+ url: `/api/workflows/runs/${run.id}`,
391
+ });
392
+
393
+ expect(res.statusCode).toBe(403);
394
+ expect(res.json().code).toBe('workspace-inactive');
395
+ });
396
+
371
397
  test('propagates unexpected errors from project access check', async () => {
372
398
  const run = await createWorkflowRun({
373
399
  workspaceId,
@@ -36,7 +36,7 @@ describe('GET /api/workflows/runs/:id/attempts', () => {
36
36
  buildUserContext({
37
37
  userId: crypto.randomUUID(),
38
38
  email: 'user@example.com',
39
- memberships: [{workspaceId, role: 'admin'}],
39
+ memberships: [{workspaceId, role: 'admin', workspaceStatus: 'active'}],
40
40
  }),
41
41
  );
42
42
  done();
@@ -43,7 +43,7 @@ describe('GET /api/workflows/runs', () => {
43
43
  buildUserContext({
44
44
  userId: crypto.randomUUID(),
45
45
  email: 'user@example.com',
46
- memberships: [{workspaceId, role: 'admin'}],
46
+ memberships: [{workspaceId, role: 'admin', workspaceStatus: 'active'}],
47
47
  }),
48
48
  );
49
49
  done();
@@ -20,7 +20,10 @@ export async function requireAccessibleRun({
20
20
  }
21
21
 
22
22
  await requireProjectAccess(request, run.projectId, projects).catch((err: unknown) => {
23
- if (err instanceof ClientError && (err.status === 403 || err.status === 404)) {
23
+ if (
24
+ err instanceof ClientError &&
25
+ (err.status === 404 || (err.status === 403 && err.code === 'forbidden'))
26
+ ) {
24
27
  throw new ClientError('Run not found', 'not-found', {status: 404});
25
28
  }
26
29
  throw err;
@@ -43,7 +43,7 @@ describe('POST /api/workflows/runs/:id/rerun', () => {
43
43
  buildUserContext({
44
44
  userId: crypto.randomUUID(),
45
45
  email: 'user@example.com',
46
- memberships: [{workspaceId, role: 'admin'}],
46
+ memberships: [{workspaceId, role: 'admin', workspaceStatus: 'active'}],
47
47
  }),
48
48
  );
49
49
  done();