github-issue-tower-defence-management 1.46.0 → 1.48.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.
Files changed (99) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +70 -25
  3. package/bin/adapter/entry-points/cli/index.js +2 -104
  4. package/bin/adapter/entry-points/cli/index.js.map +1 -1
  5. package/bin/adapter/entry-points/cli/projectConfig.js +0 -15
  6. package/bin/adapter/entry-points/cli/projectConfig.js.map +1 -1
  7. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +28 -62
  8. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
  9. package/bin/adapter/entry-points/handlers/situationFileWriter.js +98 -0
  10. package/bin/adapter/entry-points/handlers/situationFileWriter.js.map +1 -0
  11. package/bin/adapter/repositories/GraphqlProjectRepository.js +37 -0
  12. package/bin/adapter/repositories/GraphqlProjectRepository.js.map +1 -1
  13. package/bin/domain/entities/WorkflowStatus.js +36 -0
  14. package/bin/domain/entities/WorkflowStatus.js.map +1 -0
  15. package/bin/domain/usecases/AnalyzeStoriesUseCase.js +2 -1
  16. package/bin/domain/usecases/AnalyzeStoriesUseCase.js.map +1 -1
  17. package/bin/domain/usecases/ChangeStatusByStoryColorUseCase.js +4 -3
  18. package/bin/domain/usecases/ChangeStatusByStoryColorUseCase.js.map +1 -1
  19. package/bin/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.js +2 -1
  20. package/bin/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.js.map +1 -1
  21. package/bin/domain/usecases/CreateEstimationIssueUseCase.js +2 -1
  22. package/bin/domain/usecases/CreateEstimationIssueUseCase.js.map +1 -1
  23. package/bin/domain/usecases/CreateNewStoryByLabelUseCase.js.map +1 -1
  24. package/bin/domain/usecases/HandleScheduledEventUseCase.js +9 -17
  25. package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
  26. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +13 -15
  27. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
  28. package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js +4 -5
  29. package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js.map +1 -1
  30. package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js +47 -0
  31. package/bin/domain/usecases/SetupTowerDefenceProjectUseCase.js.map +1 -0
  32. package/bin/domain/usecases/StartPreparationUseCase.js +7 -8
  33. package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
  34. package/bin/domain/usecases/UpdateIssueStatusByLabelUseCase.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/adapter/entry-points/cli/index.test.ts +8 -258
  37. package/src/adapter/entry-points/cli/index.ts +6 -106
  38. package/src/adapter/entry-points/cli/projectConfig.ts +0 -33
  39. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.test.ts +24 -58
  40. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +36 -41
  41. package/src/adapter/entry-points/handlers/situationFileWriter.test.ts +417 -0
  42. package/src/adapter/entry-points/handlers/situationFileWriter.ts +168 -0
  43. package/src/adapter/repositories/GraphqlProjectRepository.ts +55 -1
  44. package/src/domain/entities/WorkflowStatus.ts +41 -0
  45. package/src/domain/usecases/AnalyzeStoriesUseCase.ts +2 -2
  46. package/src/domain/usecases/ChangeStatusByStoryColorUseCase.test.ts +5 -10
  47. package/src/domain/usecases/ChangeStatusByStoryColorUseCase.ts +4 -4
  48. package/src/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.test.ts +0 -11
  49. package/src/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.ts +2 -2
  50. package/src/domain/usecases/CreateEstimationIssueUseCase.ts +2 -2
  51. package/src/domain/usecases/CreateNewStoryByLabelUseCase.test.ts +0 -4
  52. package/src/domain/usecases/CreateNewStoryByLabelUseCase.ts +0 -1
  53. package/src/domain/usecases/HandleScheduledEventUseCase.test.ts +4 -41
  54. package/src/domain/usecases/HandleScheduledEventUseCase.ts +9 -27
  55. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +0 -202
  56. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +18 -31
  57. package/src/domain/usecases/RevertOrphanedPreparationUseCase.test.ts +13 -101
  58. package/src/domain/usecases/RevertOrphanedPreparationUseCase.ts +10 -10
  59. package/src/domain/usecases/SetupTowerDefenceProjectUseCase.test.ts +187 -0
  60. package/src/domain/usecases/SetupTowerDefenceProjectUseCase.ts +69 -0
  61. package/src/domain/usecases/StartPreparationUseCase.test.ts +1 -151
  62. package/src/domain/usecases/StartPreparationUseCase.ts +11 -20
  63. package/src/domain/usecases/UpdateIssueStatusByLabelUseCase.test.ts +2 -47
  64. package/src/domain/usecases/UpdateIssueStatusByLabelUseCase.ts +1 -5
  65. package/src/domain/usecases/adapter-interfaces/ProjectRepository.ts +6 -1
  66. package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
  67. package/types/adapter/entry-points/cli/projectConfig.d.ts +0 -3
  68. package/types/adapter/entry-points/cli/projectConfig.d.ts.map +1 -1
  69. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
  70. package/types/adapter/entry-points/handlers/situationFileWriter.d.ts +30 -0
  71. package/types/adapter/entry-points/handlers/situationFileWriter.d.ts.map +1 -0
  72. package/types/adapter/repositories/GraphqlProjectRepository.d.ts +4 -1
  73. package/types/adapter/repositories/GraphqlProjectRepository.d.ts.map +1 -1
  74. package/types/domain/entities/WorkflowStatus.d.ts +13 -0
  75. package/types/domain/entities/WorkflowStatus.d.ts.map +1 -0
  76. package/types/domain/usecases/AnalyzeStoriesUseCase.d.ts +0 -1
  77. package/types/domain/usecases/AnalyzeStoriesUseCase.d.ts.map +1 -1
  78. package/types/domain/usecases/ChangeStatusByStoryColorUseCase.d.ts +0 -1
  79. package/types/domain/usecases/ChangeStatusByStoryColorUseCase.d.ts.map +1 -1
  80. package/types/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.d.ts +0 -1
  81. package/types/domain/usecases/ConvertCheckboxToIssueInStoryIssueUseCase.d.ts.map +1 -1
  82. package/types/domain/usecases/CreateEstimationIssueUseCase.d.ts +0 -1
  83. package/types/domain/usecases/CreateEstimationIssueUseCase.d.ts.map +1 -1
  84. package/types/domain/usecases/CreateNewStoryByLabelUseCase.d.ts +0 -1
  85. package/types/domain/usecases/CreateNewStoryByLabelUseCase.d.ts.map +1 -1
  86. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +3 -8
  87. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
  88. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts +1 -4
  89. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
  90. package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts +0 -3
  91. package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts.map +1 -1
  92. package/types/domain/usecases/SetupTowerDefenceProjectUseCase.d.ts +10 -0
  93. package/types/domain/usecases/SetupTowerDefenceProjectUseCase.d.ts.map +1 -0
  94. package/types/domain/usecases/StartPreparationUseCase.d.ts +1 -3
  95. package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
  96. package/types/domain/usecases/UpdateIssueStatusByLabelUseCase.d.ts +0 -1
  97. package/types/domain/usecases/UpdateIssueStatusByLabelUseCase.d.ts.map +1 -1
  98. package/types/domain/usecases/adapter-interfaces/ProjectRepository.d.ts +3 -1
  99. package/types/domain/usecases/adapter-interfaces/ProjectRepository.d.ts.map +1 -1
@@ -3,8 +3,6 @@ import * as fs from 'fs';
3
3
 
4
4
  export type ConfigFile = {
5
5
  projectUrl?: string;
6
- awaitingWorkspaceStatus?: string;
7
- preparationStatus?: string;
8
6
  defaultAgentName?: string;
9
7
  defaultLlmModelName?: string;
10
8
  defaultLlmAgentName?: string;
@@ -12,7 +10,6 @@ export type ConfigFile = {
12
10
  allowIssueCacheMinutes?: number;
13
11
  utilizationPercentageThreshold?: number;
14
12
  allowedIssueAuthors?: string;
15
- awaitingQualityCheckStatus?: string;
16
13
  thresholdForAutoReject?: number;
17
14
  workflowBlockerResolvedWebhookUrl?: string;
18
15
  projectName?: string;
@@ -68,11 +65,6 @@ export const loadConfigFile = (configFilePath: string): ConfigFile => {
68
65
  }
69
66
  return {
70
67
  projectUrl: getStringValue(parsed, 'projectUrl'),
71
- awaitingWorkspaceStatus: getStringValue(
72
- parsed,
73
- 'awaitingWorkspaceStatus',
74
- ),
75
- preparationStatus: getStringValue(parsed, 'preparationStatus'),
76
68
  defaultAgentName: getStringValue(parsed, 'defaultAgentName'),
77
69
  defaultLlmModelName: getStringValue(parsed, 'defaultLlmModelName'),
78
70
  defaultLlmAgentName: getStringValue(parsed, 'defaultLlmAgentName'),
@@ -86,10 +78,6 @@ export const loadConfigFile = (configFilePath: string): ConfigFile => {
86
78
  'utilizationPercentageThreshold',
87
79
  ),
88
80
  allowedIssueAuthors: getStringValue(parsed, 'allowedIssueAuthors'),
89
- awaitingQualityCheckStatus: getStringValue(
90
- parsed,
91
- 'awaitingQualityCheckStatus',
92
- ),
93
81
  thresholdForAutoReject: getNumberValue(parsed, 'thresholdForAutoReject'),
94
82
  workflowBlockerResolvedWebhookUrl: getStringValue(
95
83
  parsed,
@@ -133,11 +121,6 @@ export const parseProjectReadmeConfig = (readme: string): ConfigFile => {
133
121
  return {};
134
122
  }
135
123
  return {
136
- awaitingWorkspaceStatus: getStringValue(
137
- parsed,
138
- 'awaitingWorkspaceStatus',
139
- ),
140
- preparationStatus: getStringValue(parsed, 'preparationStatus'),
141
124
  defaultAgentName: getStringValue(parsed, 'defaultAgentName'),
142
125
  defaultLlmModelName: getStringValue(parsed, 'defaultLlmModelName'),
143
126
  defaultLlmAgentName: getStringValue(parsed, 'defaultLlmAgentName'),
@@ -151,10 +134,6 @@ export const parseProjectReadmeConfig = (readme: string): ConfigFile => {
151
134
  'utilizationPercentageThreshold',
152
135
  ),
153
136
  allowedIssueAuthors: getStringValue(parsed, 'allowedIssueAuthors'),
154
- awaitingQualityCheckStatus: getStringValue(
155
- parsed,
156
- 'awaitingQualityCheckStatus',
157
- ),
158
137
  thresholdForAutoReject: getNumberValue(parsed, 'thresholdForAutoReject'),
159
138
  workflowBlockerResolvedWebhookUrl: getStringValue(
160
139
  parsed,
@@ -183,14 +162,6 @@ export const mergeConfigs = (
183
162
  readmeOverrides: ConfigFile,
184
163
  ): ConfigFile => ({
185
164
  projectUrl: cliOverrides.projectUrl ?? configFile.projectUrl,
186
- awaitingWorkspaceStatus:
187
- readmeOverrides.awaitingWorkspaceStatus ??
188
- cliOverrides.awaitingWorkspaceStatus ??
189
- configFile.awaitingWorkspaceStatus,
190
- preparationStatus:
191
- readmeOverrides.preparationStatus ??
192
- cliOverrides.preparationStatus ??
193
- configFile.preparationStatus,
194
165
  defaultAgentName:
195
166
  readmeOverrides.defaultAgentName ??
196
167
  cliOverrides.defaultAgentName ??
@@ -219,10 +190,6 @@ export const mergeConfigs = (
219
190
  readmeOverrides.allowedIssueAuthors ??
220
191
  cliOverrides.allowedIssueAuthors ??
221
192
  configFile.allowedIssueAuthors,
222
- awaitingQualityCheckStatus:
223
- readmeOverrides.awaitingQualityCheckStatus ??
224
- cliOverrides.awaitingQualityCheckStatus ??
225
- configFile.awaitingQualityCheckStatus,
226
193
  thresholdForAutoReject:
227
194
  readmeOverrides.thresholdForAutoReject ??
228
195
  cliOverrides.thresholdForAutoReject ??
@@ -113,8 +113,12 @@ jest.mock('../../repositories/GitHubIssueCommentRepository', () => ({
113
113
  jest.mock('../../repositories/FetchWebhookRepository', () => ({
114
114
  FetchWebhookRepository: jest.fn().mockImplementation(() => ({})),
115
115
  }));
116
+ jest.mock('./situationFileWriter', () => ({
117
+ writeSituationFile: jest.fn().mockResolvedValue(undefined),
118
+ }));
116
119
 
117
120
  import { HandleScheduledEventUseCaseHandler } from './HandleScheduledEventUseCaseHandler';
121
+ import { writeSituationFile } from './situationFileWriter';
118
122
  import { GraphqlProjectRepository } from '../../repositories/GraphqlProjectRepository';
119
123
  import { ApiV3IssueRepository } from '../../repositories/issue/ApiV3IssueRepository';
120
124
  import { RestIssueRepository } from '../../repositories/issue/RestIssueRepository';
@@ -137,8 +141,6 @@ const validConfig = {
137
141
  projectUrl: 'https://github.com/users/TestOrg/projects/1',
138
142
  manager: 'TestManager',
139
143
  urlOfStoryView: 'https://github.com/users/TestOrg/projects/1/views/1',
140
- disabledStatus: 'Icebox',
141
- defaultStatus: 'Unread',
142
144
  disabled: false,
143
145
  allowIssueCacheMinutes: 1,
144
146
  workingReport: {
@@ -258,22 +260,17 @@ describe('HandleScheduledEventUseCaseHandler', () => {
258
260
  }
259
261
  });
260
262
 
261
- it('should write runtimeConfig-{projectId}.json atomically after successful run', async () => {
263
+ it('should write situation file after successful run with resolved config values', async () => {
262
264
  const configWithPreparation = {
263
265
  ...validConfig,
264
266
  allowIssueCacheMinutes: 5,
265
267
  startPreparation: {
266
- awaitingWorkspaceStatus: 'Awaiting',
267
- preparationStatus: 'Preparing',
268
268
  defaultAgentName: 'agent1',
269
269
  configFilePath: './config.yml',
270
270
  maximumPreparingIssuesCount: 10,
271
271
  utilizationPercentageThreshold: 97,
272
272
  },
273
273
  notifyFinishedPreparation: {
274
- preparationStatus: 'Preparing',
275
- awaitingWorkspaceStatus: 'Awaiting',
276
- awaitingQualityCheckStatus: 'Awaiting QC',
277
274
  thresholdForAutoReject: 30,
278
275
  workflowBlockerResolvedWebhookUrl: null,
279
276
  },
@@ -286,64 +283,40 @@ describe('HandleScheduledEventUseCaseHandler', () => {
286
283
  await handler.handle('config.yml', false);
287
284
 
288
285
  const expectedCachePath = `./tmp/cache/${validConfig.projectName}`;
289
- const expectedFinalPath = `${expectedCachePath}/runtimeConfig-PVT_kwHOtest123.json`;
290
- const expectedTmpPath = `${expectedFinalPath}.tmp`;
291
-
292
- expect(jest.mocked(fs.mkdirSync)).toHaveBeenCalledWith(expectedCachePath, {
293
- recursive: true,
294
- });
295
- expect(jest.mocked(fs.writeFileSync)).toHaveBeenCalledWith(
296
- expectedTmpPath,
297
- expect.stringContaining('"maximumPreparingIssuesCount":10'),
298
- );
299
- expect(jest.mocked(fs.writeFileSync)).toHaveBeenCalledWith(
300
- expectedTmpPath,
301
- expect.stringContaining('"utilizationPercentageThreshold":97'),
302
- );
303
- expect(jest.mocked(fs.writeFileSync)).toHaveBeenCalledWith(
304
- expectedTmpPath,
305
- expect.stringContaining('"allowIssueCacheMinutes":5'),
306
- );
307
- expect(jest.mocked(fs.writeFileSync)).toHaveBeenCalledWith(
308
- expectedTmpPath,
309
- expect.stringContaining('"thresholdForAutoReject":30'),
286
+ const firstCallArg = jest.mocked(writeSituationFile).mock.calls[0][0];
287
+ expect(firstCallArg.cachePath).toBe(expectedCachePath);
288
+ expect(firstCallArg.projectId).toBe('PVT_kwHOtest123');
289
+ expect(firstCallArg.config.maximumPreparingIssuesCount).toBe(10);
290
+ expect(firstCallArg.config.utilizationPercentageThreshold).toBe(97);
291
+ expect(firstCallArg.config.allowIssueCacheMinutes).toBe(5);
292
+ expect(firstCallArg.config.thresholdForAutoReject).toBe(30);
293
+ expect(firstCallArg.statusNames.awaitingQualityCheckStatus).toBe(
294
+ 'Awaiting Quality Check',
310
295
  );
311
- expect(jest.mocked(fs.renameSync)).toHaveBeenCalledWith(
312
- expectedTmpPath,
313
- expectedFinalPath,
296
+ expect(firstCallArg.statusNames.preparationStatus).toBe('Preparation');
297
+ expect(firstCallArg.statusNames.awaitingWorkspaceStatus).toBe(
298
+ 'Awaiting Workspace',
314
299
  );
315
300
  });
316
301
 
317
- it('should write runtimeConfig with numeric defaults when optional fields are absent', async () => {
302
+ it('should write situation file with numeric defaults when optional fields are absent', async () => {
318
303
  const handler = new HandleScheduledEventUseCaseHandler();
319
304
  await handler.handle('config.yml', false);
320
305
 
321
- const expectedCachePath = `./tmp/cache/${validConfig.projectName}`;
322
- const expectedTmpPath = `${expectedCachePath}/runtimeConfig-PVT_kwHOtest123.json.tmp`;
323
-
324
- expect(jest.mocked(fs.writeFileSync)).toHaveBeenCalledWith(
325
- expectedTmpPath,
326
- expect.stringContaining('"utilizationPercentageThreshold":90'),
327
- );
328
- expect(jest.mocked(fs.writeFileSync)).toHaveBeenCalledWith(
329
- expectedTmpPath,
330
- expect.stringContaining('"thresholdForAutoReject":3'),
331
- );
332
- expect(jest.mocked(fs.writeFileSync)).toHaveBeenCalledWith(
333
- expectedTmpPath,
334
- expect.stringContaining('"maximumPreparingIssuesCount":null'),
335
- );
306
+ const firstCallArg = jest.mocked(writeSituationFile).mock.calls[0][0];
307
+ expect(firstCallArg.config.utilizationPercentageThreshold).toBe(90);
308
+ expect(firstCallArg.config.thresholdForAutoReject).toBe(3);
309
+ expect(firstCallArg.config.maximumPreparingIssuesCount).toBeNull();
336
310
  });
337
311
 
338
- it('should not write runtimeConfig when run returns null', async () => {
312
+ it('should not write situation file when run returns null', async () => {
339
313
  mockRun.mockResolvedValueOnce(null);
340
314
  jest.mocked(fs.readFileSync).mockReturnValue(YAML.stringify(validConfig));
341
315
 
342
316
  const handler = new HandleScheduledEventUseCaseHandler();
343
317
  await handler.handle('config.yml', false);
344
318
 
345
- expect(jest.mocked(fs.writeFileSync)).not.toHaveBeenCalled();
346
- expect(jest.mocked(fs.renameSync)).not.toHaveBeenCalled();
319
+ expect(jest.mocked(writeSituationFile)).not.toHaveBeenCalled();
347
320
  });
348
321
 
349
322
  describe('README config overrides', () => {
@@ -351,8 +324,6 @@ describe('HandleScheduledEventUseCaseHandler', () => {
351
324
  ...validConfig,
352
325
  allowIssueCacheMinutes: 5,
353
326
  startPreparation: {
354
- awaitingWorkspaceStatus: 'Awaiting workspace',
355
- preparationStatus: 'Preparation',
356
327
  defaultAgentName: 'yaml-agent',
357
328
  configFilePath: '/path/to/config.yml',
358
329
  maximumPreparingIssuesCount: 10,
@@ -364,8 +335,6 @@ describe('HandleScheduledEventUseCaseHandler', () => {
364
335
  const readmeContent = `<details>
365
336
  <summary>config</summary>
366
337
  maximumPreparingIssuesCount: 0
367
- awaitingWorkspaceStatus: README Awaiting
368
- preparationStatus: README Preparation
369
338
  defaultAgentName: readme-agent
370
339
  utilizationPercentageThreshold: 80
371
340
  </details>`;
@@ -380,8 +349,6 @@ utilizationPercentageThreshold: 80
380
349
  expect(capturedRunInputs[0][0]).toMatchObject({
381
350
  startPreparation: {
382
351
  maximumPreparingIssuesCount: 0,
383
- awaitingWorkspaceStatus: 'README Awaiting',
384
- preparationStatus: 'README Preparation',
385
352
  defaultAgentName: 'readme-agent',
386
353
  utilizationPercentageThreshold: 80,
387
354
  },
@@ -441,7 +408,6 @@ allowedIssueAuthors: 'user1, user2, user3'
441
408
  allowIssueCacheMinutes: 5,
442
409
  startPreparation: {
443
410
  maximumPreparingIssuesCount: 10,
444
- awaitingWorkspaceStatus: 'Awaiting workspace',
445
411
  defaultAgentName: 'yaml-agent',
446
412
  },
447
413
  });
@@ -1,6 +1,7 @@
1
1
  import YAML from 'yaml';
2
2
  import TYPIA from 'typia';
3
3
  import fs from 'fs';
4
+ import { writeSituationFile } from './situationFileWriter';
4
5
  import {
5
6
  fetchProjectReadme,
6
7
  parseProjectReadmeConfig,
@@ -29,7 +30,6 @@ import { ConvertCheckboxToIssueInStoryIssueUseCase } from '../../../domain/useca
29
30
  import { ChangeStatusByStoryColorUseCase } from '../../../domain/usecases/ChangeStatusByStoryColorUseCase';
30
31
  import { SetNoStoryIssueToStoryUseCase } from '../../../domain/usecases/SetNoStoryIssueToStoryUseCase';
31
32
  import { CreateNewStoryByLabelUseCase } from '../../../domain/usecases/CreateNewStoryByLabelUseCase';
32
- import { ProjectRepository } from '../../../domain/usecases/adapter-interfaces/ProjectRepository';
33
33
  import { AssignNoAssigneeIssueToManagerUseCase } from '../../../domain/usecases/AssignNoAssigneeIssueToManagerUseCase';
34
34
  import { UpdateIssueStatusByLabelUseCase } from '../../../domain/usecases/UpdateIssueStatusByLabelUseCase';
35
35
  import { StartPreparationUseCase } from '../../../domain/usecases/StartPreparationUseCase';
@@ -39,6 +39,12 @@ import { NotifyFinishedIssuePreparationUseCase } from '../../../domain/usecases/
39
39
  import { RevertOrphanedPreparationUseCase } from '../../../domain/usecases/RevertOrphanedPreparationUseCase';
40
40
  import { GitHubIssueCommentRepository } from '../../repositories/GitHubIssueCommentRepository';
41
41
  import { FetchWebhookRepository } from '../../repositories/FetchWebhookRepository';
42
+ import { SetupTowerDefenceProjectUseCase } from '../../../domain/usecases/SetupTowerDefenceProjectUseCase';
43
+ import {
44
+ AWAITING_QUALITY_CHECK_STATUS_NAME,
45
+ AWAITING_WORKSPACE_STATUS_NAME,
46
+ PREPARATION_STATUS_NAME,
47
+ } from '../../../domain/entities/WorkflowStatus';
42
48
 
43
49
  export class HandleScheduledEventUseCaseHandler {
44
50
  handle = async (
@@ -96,12 +102,6 @@ export class HandleScheduledEventUseCaseHandler {
96
102
  startPreparation: input.startPreparation
97
103
  ? {
98
104
  ...input.startPreparation,
99
- awaitingWorkspaceStatus:
100
- readmeConfig.awaitingWorkspaceStatus ??
101
- input.startPreparation.awaitingWorkspaceStatus,
102
- preparationStatus:
103
- readmeConfig.preparationStatus ??
104
- input.startPreparation.preparationStatus,
105
105
  defaultAgentName:
106
106
  readmeConfig.defaultAgentName ??
107
107
  input.startPreparation.defaultAgentName,
@@ -134,15 +134,6 @@ export class HandleScheduledEventUseCaseHandler {
134
134
  notifyFinishedPreparation: input.notifyFinishedPreparation
135
135
  ? {
136
136
  ...input.notifyFinishedPreparation,
137
- awaitingWorkspaceStatus:
138
- readmeConfig.awaitingWorkspaceStatus ??
139
- input.notifyFinishedPreparation.awaitingWorkspaceStatus,
140
- preparationStatus:
141
- readmeConfig.preparationStatus ??
142
- input.notifyFinishedPreparation.preparationStatus,
143
- awaitingQualityCheckStatus:
144
- readmeConfig.awaitingQualityCheckStatus ??
145
- input.notifyFinishedPreparation.awaitingQualityCheckStatus,
146
137
  thresholdForAutoReject:
147
138
  readmeConfig.thresholdForAutoReject ??
148
139
  input.notifyFinishedPreparation.thresholdForAutoReject,
@@ -174,15 +165,9 @@ export class HandleScheduledEventUseCaseHandler {
174
165
  input.credentials.bot.github.password,
175
166
  input.credentials.bot.github.authenticatorKey,
176
167
  ];
177
- const projectRepository: ProjectRepository = {
178
- ...new GraphqlProjectRepository(...githubRepositoryParams),
179
- prepareStatus: async (
180
- _name: string,
181
- project: Project,
182
- ): Promise<Project> => {
183
- return project;
184
- },
185
- };
168
+ const projectRepository = new GraphqlProjectRepository(
169
+ ...githubRepositoryParams,
170
+ );
186
171
  const apiV3IssueRepository = new ApiV3IssueRepository(
187
172
  ...githubRepositoryParams,
188
173
  );
@@ -199,6 +184,9 @@ export class HandleScheduledEventUseCaseHandler {
199
184
  localStorageCacheRepository,
200
185
  ...githubRepositoryParams,
201
186
  );
187
+ const setupTowerDefenceProjectUseCase = new SetupTowerDefenceProjectUseCase(
188
+ projectRepository,
189
+ );
202
190
  const actionAnnouncement = new ActionAnnouncementUseCase(issueRepository);
203
191
  const setWorkflowManagementIssueToStoryUseCase =
204
192
  new SetWorkflowManagementIssueToStoryUseCase(issueRepository);
@@ -267,6 +255,7 @@ export class HandleScheduledEventUseCaseHandler {
267
255
  );
268
256
 
269
257
  const handleScheduledEventUseCase = new HandleScheduledEventUseCase(
258
+ setupTowerDefenceProjectUseCase,
270
259
  actionAnnouncement,
271
260
  setWorkflowManagementIssueToStoryUseCase,
272
261
  clearPastNextActionUseCase,
@@ -291,22 +280,28 @@ export class HandleScheduledEventUseCaseHandler {
291
280
 
292
281
  const result = await handleScheduledEventUseCase.run(mergedInput);
293
282
  if (result) {
294
- const projectId = result.project.id;
295
- const runtimeConfig = {
296
- resolvedAt: new Date().toISOString(),
297
- maximumPreparingIssuesCount:
298
- mergedInput.startPreparation?.maximumPreparingIssuesCount ?? null,
299
- utilizationPercentageThreshold:
300
- mergedInput.startPreparation?.utilizationPercentageThreshold ?? 90,
301
- allowIssueCacheMinutes: mergedInput.allowIssueCacheMinutes,
302
- thresholdForAutoReject:
303
- mergedInput.notifyFinishedPreparation?.thresholdForAutoReject ?? 3,
304
- };
305
- const finalPath = `${cachePath}/runtimeConfig-${projectId}.json`;
306
- const tmpPath = `${finalPath}.tmp`;
307
- fs.mkdirSync(cachePath, { recursive: true });
308
- fs.writeFileSync(tmpPath, JSON.stringify(runtimeConfig));
309
- fs.renameSync(tmpPath, finalPath);
283
+ await writeSituationFile({
284
+ cachePath,
285
+ projectId: result.project.id,
286
+ issues: result.issues,
287
+ statusNames: {
288
+ awaitingQualityCheckStatus: AWAITING_QUALITY_CHECK_STATUS_NAME,
289
+ preparationStatus: PREPARATION_STATUS_NAME,
290
+ awaitingWorkspaceStatus: AWAITING_WORKSPACE_STATUS_NAME,
291
+ },
292
+ config: {
293
+ maximumPreparingIssuesCount:
294
+ mergedInput.startPreparation?.maximumPreparingIssuesCount ?? null,
295
+ utilizationPercentageThreshold:
296
+ mergedInput.startPreparation?.utilizationPercentageThreshold ?? 90,
297
+ allowIssueCacheMinutes: mergedInput.allowIssueCacheMinutes,
298
+ thresholdForAutoReject:
299
+ mergedInput.notifyFinishedPreparation?.thresholdForAutoReject ?? 3,
300
+ },
301
+ preparationProcessCheckCommand:
302
+ mergedInput.startPreparation?.preparationProcessCheckCommand ?? null,
303
+ localCommandRunner: nodeLocalCommandRunner,
304
+ });
310
305
  }
311
306
  return result;
312
307
  };