@mc1global/opencode-jarvis 0.1.1 → 0.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/dist/application/agent-registry/dtos.d.ts +66 -0
- package/dist/application/agent-registry/dtos.d.ts.map +1 -0
- package/dist/application/agent-registry/dtos.js +11 -0
- package/dist/application/agent-registry/dtos.js.map +1 -0
- package/dist/application/agent-registry/use-cases.d.ts +39 -0
- package/dist/application/agent-registry/use-cases.d.ts.map +1 -0
- package/dist/application/agent-registry/use-cases.js +222 -0
- package/dist/application/agent-registry/use-cases.js.map +1 -0
- package/dist/application/azure-sync/dtos.d.ts +210 -0
- package/dist/application/azure-sync/dtos.d.ts.map +1 -0
- package/dist/application/azure-sync/dtos.js +11 -0
- package/dist/application/azure-sync/dtos.js.map +1 -0
- package/dist/application/azure-sync/field-builders.d.ts +54 -0
- package/dist/application/azure-sync/field-builders.d.ts.map +1 -0
- package/dist/application/azure-sync/field-builders.js +166 -0
- package/dist/application/azure-sync/field-builders.js.map +1 -0
- package/dist/application/azure-sync/index.d.ts +16 -0
- package/dist/application/azure-sync/index.d.ts.map +1 -0
- package/dist/application/azure-sync/index.js +10 -0
- package/dist/application/azure-sync/index.js.map +1 -0
- package/dist/application/azure-sync/pr-use-cases.d.ts +39 -0
- package/dist/application/azure-sync/pr-use-cases.d.ts.map +1 -0
- package/dist/application/azure-sync/pr-use-cases.js +192 -0
- package/dist/application/azure-sync/pr-use-cases.js.map +1 -0
- package/dist/application/azure-sync/pull-use-cases.d.ts +43 -0
- package/dist/application/azure-sync/pull-use-cases.d.ts.map +1 -0
- package/dist/application/azure-sync/pull-use-cases.js +322 -0
- package/dist/application/azure-sync/pull-use-cases.js.map +1 -0
- package/dist/application/azure-sync/push-use-cases.d.ts +53 -0
- package/dist/application/azure-sync/push-use-cases.d.ts.map +1 -0
- package/dist/application/azure-sync/push-use-cases.js +341 -0
- package/dist/application/azure-sync/push-use-cases.js.map +1 -0
- package/dist/application/azure-sync/reverse-field-builder.d.ts +52 -0
- package/dist/application/azure-sync/reverse-field-builder.d.ts.map +1 -0
- package/dist/application/azure-sync/reverse-field-builder.js +130 -0
- package/dist/application/azure-sync/reverse-field-builder.js.map +1 -0
- package/dist/application/azure-sync/task-push-use-cases.d.ts +68 -0
- package/dist/application/azure-sync/task-push-use-cases.d.ts.map +1 -0
- package/dist/application/azure-sync/task-push-use-cases.js +162 -0
- package/dist/application/azure-sync/task-push-use-cases.js.map +1 -0
- package/dist/application/config/config-service.d.ts +64 -0
- package/dist/application/config/config-service.d.ts.map +1 -0
- package/dist/application/config/config-service.js +110 -0
- package/dist/application/config/config-service.js.map +1 -0
- package/dist/application/config/index.d.ts +5 -0
- package/dist/application/config/index.d.ts.map +1 -0
- package/dist/application/config/index.js +5 -0
- package/dist/application/config/index.js.map +1 -0
- package/dist/application/kanban/board-use-cases.d.ts.map +1 -1
- package/dist/application/kanban/board-use-cases.js +14 -0
- package/dist/application/kanban/board-use-cases.js.map +1 -1
- package/dist/application/kanban/card-use-cases.d.ts +21 -2
- package/dist/application/kanban/card-use-cases.d.ts.map +1 -1
- package/dist/application/kanban/card-use-cases.js +180 -1
- package/dist/application/kanban/card-use-cases.js.map +1 -1
- package/dist/application/kanban/dtos.d.ts +59 -0
- package/dist/application/kanban/dtos.d.ts.map +1 -1
- package/dist/application/mcp/index.d.ts +10 -0
- package/dist/application/mcp/index.d.ts.map +1 -0
- package/dist/application/mcp/index.js +8 -0
- package/dist/application/mcp/index.js.map +1 -0
- package/dist/application/mcp/middleware.d.ts +91 -0
- package/dist/application/mcp/middleware.d.ts.map +1 -0
- package/dist/application/mcp/middleware.js +84 -0
- package/dist/application/mcp/middleware.js.map +1 -0
- package/dist/application/mcp/tool-adapter.d.ts +72 -0
- package/dist/application/mcp/tool-adapter.d.ts.map +1 -0
- package/dist/application/mcp/tool-adapter.js +132 -0
- package/dist/application/mcp/tool-adapter.js.map +1 -0
- package/dist/application/pipeline/dtos.d.ts +135 -0
- package/dist/application/pipeline/dtos.d.ts.map +1 -0
- package/dist/application/pipeline/dtos.js +11 -0
- package/dist/application/pipeline/dtos.js.map +1 -0
- package/dist/application/pipeline/index.d.ts +8 -0
- package/dist/application/pipeline/index.d.ts.map +1 -0
- package/dist/application/pipeline/index.js +7 -0
- package/dist/application/pipeline/index.js.map +1 -0
- package/dist/application/pipeline/use-cases.d.ts +67 -0
- package/dist/application/pipeline/use-cases.d.ts.map +1 -0
- package/dist/application/pipeline/use-cases.js +413 -0
- package/dist/application/pipeline/use-cases.js.map +1 -0
- package/dist/application/rag/use-cases.d.ts +3 -0
- package/dist/application/rag/use-cases.d.ts.map +1 -1
- package/dist/application/rag/use-cases.js +112 -34
- package/dist/application/rag/use-cases.js.map +1 -1
- package/dist/domain/agent-registry/entities.d.ts +68 -0
- package/dist/domain/agent-registry/entities.d.ts.map +1 -0
- package/dist/domain/agent-registry/entities.js +177 -0
- package/dist/domain/agent-registry/entities.js.map +1 -0
- package/dist/domain/agent-registry/repositories.d.ts +56 -0
- package/dist/domain/agent-registry/repositories.d.ts.map +1 -0
- package/dist/domain/agent-registry/repositories.js +12 -0
- package/dist/domain/agent-registry/repositories.js.map +1 -0
- package/dist/domain/agent-registry/services.d.ts +87 -0
- package/dist/domain/agent-registry/services.d.ts.map +1 -0
- package/dist/domain/agent-registry/services.js +188 -0
- package/dist/domain/agent-registry/services.js.map +1 -0
- package/dist/domain/agent-registry/value-objects.d.ts +145 -0
- package/dist/domain/agent-registry/value-objects.d.ts.map +1 -0
- package/dist/domain/agent-registry/value-objects.js +339 -0
- package/dist/domain/agent-registry/value-objects.js.map +1 -0
- package/dist/domain/azure-sync/entities.d.ts +165 -0
- package/dist/domain/azure-sync/entities.d.ts.map +1 -0
- package/dist/domain/azure-sync/entities.js +203 -0
- package/dist/domain/azure-sync/entities.js.map +1 -0
- package/dist/domain/azure-sync/index.d.ts +16 -0
- package/dist/domain/azure-sync/index.d.ts.map +1 -0
- package/dist/domain/azure-sync/index.js +14 -0
- package/dist/domain/azure-sync/index.js.map +1 -0
- package/dist/domain/azure-sync/ports.d.ts +117 -0
- package/dist/domain/azure-sync/ports.d.ts.map +1 -0
- package/dist/domain/azure-sync/ports.js +13 -0
- package/dist/domain/azure-sync/ports.js.map +1 -0
- package/dist/domain/azure-sync/repositories.d.ts +53 -0
- package/dist/domain/azure-sync/repositories.d.ts.map +1 -0
- package/dist/domain/azure-sync/repositories.js +11 -0
- package/dist/domain/azure-sync/repositories.js.map +1 -0
- package/dist/domain/azure-sync/services.d.ts +107 -0
- package/dist/domain/azure-sync/services.d.ts.map +1 -0
- package/dist/domain/azure-sync/services.js +316 -0
- package/dist/domain/azure-sync/services.js.map +1 -0
- package/dist/domain/azure-sync/value-objects.d.ts +129 -0
- package/dist/domain/azure-sync/value-objects.d.ts.map +1 -0
- package/dist/domain/azure-sync/value-objects.js +343 -0
- package/dist/domain/azure-sync/value-objects.js.map +1 -0
- package/dist/domain/config/index.d.ts +9 -0
- package/dist/domain/config/index.d.ts.map +1 -0
- package/dist/domain/config/index.js +7 -0
- package/dist/domain/config/index.js.map +1 -0
- package/dist/domain/config/repositories.d.ts +36 -0
- package/dist/domain/config/repositories.d.ts.map +1 -0
- package/dist/domain/config/repositories.js +12 -0
- package/dist/domain/config/repositories.js.map +1 -0
- package/dist/domain/config/value-objects.d.ts +112 -0
- package/dist/domain/config/value-objects.d.ts.map +1 -0
- package/dist/domain/config/value-objects.js +93 -0
- package/dist/domain/config/value-objects.js.map +1 -0
- package/dist/domain/governance/policies.d.ts.map +1 -1
- package/dist/domain/governance/policies.js +70 -0
- package/dist/domain/governance/policies.js.map +1 -1
- package/dist/domain/kanban/entities.d.ts +67 -15
- package/dist/domain/kanban/entities.d.ts.map +1 -1
- package/dist/domain/kanban/entities.js +177 -14
- package/dist/domain/kanban/entities.js.map +1 -1
- package/dist/domain/kanban/grooming.d.ts +27 -7
- package/dist/domain/kanban/grooming.d.ts.map +1 -1
- package/dist/domain/kanban/grooming.js +50 -12
- package/dist/domain/kanban/grooming.js.map +1 -1
- package/dist/domain/kanban/services.d.ts +16 -2
- package/dist/domain/kanban/services.d.ts.map +1 -1
- package/dist/domain/kanban/services.js +29 -2
- package/dist/domain/kanban/services.js.map +1 -1
- package/dist/domain/kanban/value-objects.d.ts +48 -0
- package/dist/domain/kanban/value-objects.d.ts.map +1 -1
- package/dist/domain/kanban/value-objects.js +53 -0
- package/dist/domain/kanban/value-objects.js.map +1 -1
- package/dist/domain/pipeline/gate.d.ts +75 -0
- package/dist/domain/pipeline/gate.d.ts.map +1 -0
- package/dist/domain/pipeline/gate.js +158 -0
- package/dist/domain/pipeline/gate.js.map +1 -0
- package/dist/domain/pipeline/index.d.ts +13 -0
- package/dist/domain/pipeline/index.d.ts.map +1 -0
- package/dist/domain/pipeline/index.js +14 -0
- package/dist/domain/pipeline/index.js.map +1 -0
- package/dist/domain/pipeline/pipeline.d.ts +99 -0
- package/dist/domain/pipeline/pipeline.d.ts.map +1 -0
- package/dist/domain/pipeline/pipeline.js +257 -0
- package/dist/domain/pipeline/pipeline.js.map +1 -0
- package/dist/domain/pipeline/ports.d.ts +120 -0
- package/dist/domain/pipeline/ports.d.ts.map +1 -0
- package/dist/domain/pipeline/ports.js +12 -0
- package/dist/domain/pipeline/ports.js.map +1 -0
- package/dist/domain/pipeline/repositories.d.ts +66 -0
- package/dist/domain/pipeline/repositories.d.ts.map +1 -0
- package/dist/domain/pipeline/repositories.js +11 -0
- package/dist/domain/pipeline/repositories.js.map +1 -0
- package/dist/domain/pipeline/services.d.ts +77 -0
- package/dist/domain/pipeline/services.d.ts.map +1 -0
- package/dist/domain/pipeline/services.js +156 -0
- package/dist/domain/pipeline/services.js.map +1 -0
- package/dist/domain/pipeline/value-objects.d.ts +117 -0
- package/dist/domain/pipeline/value-objects.d.ts.map +1 -0
- package/dist/domain/pipeline/value-objects.js +313 -0
- package/dist/domain/pipeline/value-objects.js.map +1 -0
- package/dist/domain/rag/value-objects.d.ts +9 -2
- package/dist/domain/rag/value-objects.d.ts.map +1 -1
- package/dist/domain/rag/value-objects.js +8 -2
- package/dist/domain/rag/value-objects.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +113 -75
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/agent-registry/agent-profile-repository.d.ts +29 -0
- package/dist/infrastructure/agent-registry/agent-profile-repository.d.ts.map +1 -0
- package/dist/infrastructure/agent-registry/agent-profile-repository.js +109 -0
- package/dist/infrastructure/agent-registry/agent-profile-repository.js.map +1 -0
- package/dist/infrastructure/agent-registry/agent-session-adapter.d.ts +28 -0
- package/dist/infrastructure/agent-registry/agent-session-adapter.d.ts.map +1 -0
- package/dist/infrastructure/agent-registry/agent-session-adapter.js +61 -0
- package/dist/infrastructure/agent-registry/agent-session-adapter.js.map +1 -0
- package/dist/infrastructure/agent-registry/built-in-profiles.d.ts +19 -0
- package/dist/infrastructure/agent-registry/built-in-profiles.d.ts.map +1 -0
- package/dist/infrastructure/agent-registry/built-in-profiles.js +210 -0
- package/dist/infrastructure/agent-registry/built-in-profiles.js.map +1 -0
- package/dist/infrastructure/azure-sync/azure-auth.d.ts +40 -0
- package/dist/infrastructure/azure-sync/azure-auth.d.ts.map +1 -0
- package/dist/infrastructure/azure-sync/azure-auth.js +94 -0
- package/dist/infrastructure/azure-sync/azure-auth.js.map +1 -0
- package/dist/infrastructure/azure-sync/azure-devops-client.d.ts +43 -0
- package/dist/infrastructure/azure-sync/azure-devops-client.d.ts.map +1 -0
- package/dist/infrastructure/azure-sync/azure-devops-client.js +296 -0
- package/dist/infrastructure/azure-sync/azure-devops-client.js.map +1 -0
- package/dist/infrastructure/azure-sync/index.d.ts +9 -0
- package/dist/infrastructure/azure-sync/index.d.ts.map +1 -0
- package/dist/infrastructure/azure-sync/index.js +12 -0
- package/dist/infrastructure/azure-sync/index.js.map +1 -0
- package/dist/infrastructure/azure-sync/sqlite-sync-repository.d.ts +39 -0
- package/dist/infrastructure/azure-sync/sqlite-sync-repository.d.ts.map +1 -0
- package/dist/infrastructure/azure-sync/sqlite-sync-repository.js +202 -0
- package/dist/infrastructure/azure-sync/sqlite-sync-repository.js.map +1 -0
- package/dist/infrastructure/config/index.d.ts +5 -0
- package/dist/infrastructure/config/index.d.ts.map +1 -0
- package/dist/infrastructure/config/index.js +5 -0
- package/dist/infrastructure/config/index.js.map +1 -0
- package/dist/infrastructure/config/yaml-config-repository.d.ts +22 -0
- package/dist/infrastructure/config/yaml-config-repository.d.ts.map +1 -0
- package/dist/infrastructure/config/yaml-config-repository.js +68 -0
- package/dist/infrastructure/config/yaml-config-repository.js.map +1 -0
- package/dist/infrastructure/domain-map/llm-prompt-factory.d.ts +21 -0
- package/dist/infrastructure/domain-map/llm-prompt-factory.d.ts.map +1 -0
- package/dist/infrastructure/domain-map/llm-prompt-factory.js +49 -0
- package/dist/infrastructure/domain-map/llm-prompt-factory.js.map +1 -0
- package/dist/infrastructure/kanban/card-repository.d.ts +6 -0
- package/dist/infrastructure/kanban/card-repository.d.ts.map +1 -1
- package/dist/infrastructure/kanban/card-repository.js +79 -7
- package/dist/infrastructure/kanban/card-repository.js.map +1 -1
- package/dist/infrastructure/pipeline/dagger-adapter.d.ts +50 -0
- package/dist/infrastructure/pipeline/dagger-adapter.d.ts.map +1 -0
- package/dist/infrastructure/pipeline/dagger-adapter.js +153 -0
- package/dist/infrastructure/pipeline/dagger-adapter.js.map +1 -0
- package/dist/infrastructure/pipeline/dagger-scaffold-generator.d.ts +35 -0
- package/dist/infrastructure/pipeline/dagger-scaffold-generator.d.ts.map +1 -0
- package/dist/infrastructure/pipeline/dagger-scaffold-generator.js +132 -0
- package/dist/infrastructure/pipeline/dagger-scaffold-generator.js.map +1 -0
- package/dist/infrastructure/pipeline/index.d.ts +20 -0
- package/dist/infrastructure/pipeline/index.d.ts.map +1 -0
- package/dist/infrastructure/pipeline/index.js +19 -0
- package/dist/infrastructure/pipeline/index.js.map +1 -0
- package/dist/infrastructure/pipeline/pipeline-template-registry.d.ts +23 -0
- package/dist/infrastructure/pipeline/pipeline-template-registry.d.ts.map +1 -0
- package/dist/infrastructure/pipeline/pipeline-template-registry.js +63 -0
- package/dist/infrastructure/pipeline/pipeline-template-registry.js.map +1 -0
- package/dist/infrastructure/pipeline/scaffold-templates-extra.d.ts +17 -0
- package/dist/infrastructure/pipeline/scaffold-templates-extra.d.ts.map +1 -0
- package/dist/infrastructure/pipeline/scaffold-templates-extra.js +467 -0
- package/dist/infrastructure/pipeline/scaffold-templates-extra.js.map +1 -0
- package/dist/infrastructure/pipeline/scaffold-templates.d.ts +23 -0
- package/dist/infrastructure/pipeline/scaffold-templates.d.ts.map +1 -0
- package/dist/infrastructure/pipeline/scaffold-templates.js +476 -0
- package/dist/infrastructure/pipeline/scaffold-templates.js.map +1 -0
- package/dist/infrastructure/pipeline/sqlite-pipeline-repository.d.ts +32 -0
- package/dist/infrastructure/pipeline/sqlite-pipeline-repository.d.ts.map +1 -0
- package/dist/infrastructure/pipeline/sqlite-pipeline-repository.js +197 -0
- package/dist/infrastructure/pipeline/sqlite-pipeline-repository.js.map +1 -0
- package/dist/mcp-server.d.ts +3 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +300 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/tools/agent-registry-tools.d.ts +11 -0
- package/dist/tools/agent-registry-tools.d.ts.map +1 -0
- package/dist/tools/agent-registry-tools.js +208 -0
- package/dist/tools/agent-registry-tools.js.map +1 -0
- package/dist/tools/azure-sync-tools.d.ts +15 -0
- package/dist/tools/azure-sync-tools.d.ts.map +1 -0
- package/dist/tools/azure-sync-tools.js +332 -0
- package/dist/tools/azure-sync-tools.js.map +1 -0
- package/dist/tools/kanban-card-tools.d.ts.map +1 -1
- package/dist/tools/kanban-card-tools.js +41 -16
- package/dist/tools/kanban-card-tools.js.map +1 -1
- package/dist/tools/kanban-gate-tools.d.ts +7 -0
- package/dist/tools/kanban-gate-tools.d.ts.map +1 -0
- package/dist/tools/kanban-gate-tools.js +106 -0
- package/dist/tools/kanban-gate-tools.js.map +1 -0
- package/dist/tools/kanban-grooming-tools.d.ts +7 -0
- package/dist/tools/kanban-grooming-tools.d.ts.map +1 -0
- package/dist/tools/kanban-grooming-tools.js +180 -0
- package/dist/tools/kanban-grooming-tools.js.map +1 -0
- package/dist/tools/pipeline-tools.d.ts +15 -0
- package/dist/tools/pipeline-tools.d.ts.map +1 -0
- package/dist/tools/pipeline-tools.js +424 -0
- package/dist/tools/pipeline-tools.js.map +1 -0
- package/package.json +7 -2
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Azure Sync Application — Use Cases
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates discover, push, and sync-status operations.
|
|
5
|
+
* Coordinates between azure-sync domain, kanban BC, and Azure DevOps.
|
|
6
|
+
*
|
|
7
|
+
* SOLID: SRP — sync orchestration only
|
|
8
|
+
* SOLID: DIP — depends on interfaces (ports, repositories)
|
|
9
|
+
* DDD: Application service coordinating bounded contexts
|
|
10
|
+
*/
|
|
11
|
+
import { ok, fail, Timestamp } from "../../domain/shared/value-objects.js";
|
|
12
|
+
import { FieldMapper, AZURE_FIELDS, sanitizeIterationName } from "../../domain/azure-sync/services.js";
|
|
13
|
+
import { SyncMapping, SyncLog } from "../../domain/azure-sync/entities.js";
|
|
14
|
+
import { SyncMappingId, SyncLogId, WorkItemId } from "../../domain/azure-sync/value-objects.js";
|
|
15
|
+
import { AzureFieldBuilder } from "./field-builders.js";
|
|
16
|
+
import { TaskPushUseCases } from "./task-push-use-cases.js";
|
|
17
|
+
// ─── Use Cases ────────────────────────────────────────────────────────────────
|
|
18
|
+
/**
|
|
19
|
+
* Orchestrates Azure DevOps sync operations.
|
|
20
|
+
* Coordinates local kanban data with Azure DevOps Board via REST API.
|
|
21
|
+
*/
|
|
22
|
+
export class AzureSyncUseCases {
|
|
23
|
+
deps;
|
|
24
|
+
fieldMapper = new FieldMapper();
|
|
25
|
+
fieldBuilder = new AzureFieldBuilder(this.fieldMapper);
|
|
26
|
+
taskPush;
|
|
27
|
+
constructor(deps) {
|
|
28
|
+
this.deps = deps;
|
|
29
|
+
this.taskPush = new TaskPushUseCases({
|
|
30
|
+
azureClient: deps.azureClient,
|
|
31
|
+
syncMappingRepo: deps.syncMappingRepo,
|
|
32
|
+
syncLogRepo: deps.syncLogRepo,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
// ── Discover ──────────────────────────────────────────────────────
|
|
36
|
+
/** Detect project template, list existing work items and iterations. */
|
|
37
|
+
async discover(req) {
|
|
38
|
+
const projResult = await this.deps.azureClient.getProjectInfo(req.org, req.project);
|
|
39
|
+
if (!projResult.success)
|
|
40
|
+
return projResult;
|
|
41
|
+
const proj = projResult.data;
|
|
42
|
+
const wiType = this.fieldMapper.mapWorkItemType(proj.processTemplate, "card");
|
|
43
|
+
let workItems = [];
|
|
44
|
+
if (wiType) {
|
|
45
|
+
const wiResult = await this.deps.azureClient.listWorkItems(req.org, req.project, wiType, 50);
|
|
46
|
+
if (wiResult.success) {
|
|
47
|
+
workItems = wiResult.data.map((wi) => {
|
|
48
|
+
const f = wi.fields;
|
|
49
|
+
return {
|
|
50
|
+
id: wi.id,
|
|
51
|
+
title: String(f[AZURE_FIELDS.TITLE] ?? ""),
|
|
52
|
+
type: String(f[AZURE_FIELDS.WORK_ITEM_TYPE] ?? ""),
|
|
53
|
+
state: String(f[AZURE_FIELDS.STATE] ?? ""),
|
|
54
|
+
tags: String(f[AZURE_FIELDS.TAGS] ?? ""),
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const iterResult = await this.deps.azureClient.listIterations(req.org, req.project);
|
|
60
|
+
const iterations = iterResult.success
|
|
61
|
+
? iterResult.data.map((it) => ({
|
|
62
|
+
name: it.name,
|
|
63
|
+
path: it.path,
|
|
64
|
+
startDate: it.attributes?.startDate,
|
|
65
|
+
finishDate: it.attributes?.finishDate,
|
|
66
|
+
}))
|
|
67
|
+
: [];
|
|
68
|
+
const types = wiType ? ["Epic", wiType, "Task"] : ["Epic", "Task"];
|
|
69
|
+
return ok({
|
|
70
|
+
projectName: proj.name,
|
|
71
|
+
projectId: proj.id,
|
|
72
|
+
processTemplate: proj.processTemplate,
|
|
73
|
+
workItemTypes: types,
|
|
74
|
+
existingWorkItems: workItems,
|
|
75
|
+
iterations,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// ── Push ──────────────────────────────────────────────────────────
|
|
79
|
+
/** Push local entities to Azure DevOps as work items. */
|
|
80
|
+
async push(req) {
|
|
81
|
+
const projResult = await this.deps.azureClient.getProjectInfo(req.org, req.project);
|
|
82
|
+
if (!projResult.success)
|
|
83
|
+
return projResult;
|
|
84
|
+
const template = projResult.data.processTemplate;
|
|
85
|
+
const pushed = [];
|
|
86
|
+
const skipped = [];
|
|
87
|
+
const errors = [];
|
|
88
|
+
if (req.entityType === "epic" || req.entityType === "all") {
|
|
89
|
+
await this.pushEpics(req, template, pushed, skipped, errors);
|
|
90
|
+
}
|
|
91
|
+
if (req.entityType === "card" || req.entityType === "all") {
|
|
92
|
+
await this.pushCards(req, template, pushed, skipped, errors);
|
|
93
|
+
}
|
|
94
|
+
if (req.entityType === "sprint" || req.entityType === "all") {
|
|
95
|
+
await this.pushSprints(req, template, pushed, skipped, errors);
|
|
96
|
+
}
|
|
97
|
+
const summary = `Pushed ${pushed.length}, skipped ${skipped.length}, errors ${errors.length}`;
|
|
98
|
+
return ok({ pushed, skipped, errors, summary });
|
|
99
|
+
}
|
|
100
|
+
// ── Sync Status ───────────────────────────────────────────────────
|
|
101
|
+
/** Show diff between local kanban and Azure DevOps board. */
|
|
102
|
+
async syncStatus(req) {
|
|
103
|
+
const mappings = await this.deps.syncMappingRepo.findByProject(req.project);
|
|
104
|
+
const mappingItems = mappings.map((m) => ({
|
|
105
|
+
localId: m.localId,
|
|
106
|
+
localTitle: m.localId,
|
|
107
|
+
azureWorkItemId: m.azureWorkItemId.value,
|
|
108
|
+
syncStatus: m.syncStatus,
|
|
109
|
+
lastSyncedAt: m.lastSyncedAt.toISO(),
|
|
110
|
+
localModifiedAt: m.localModifiedAt.toISO(),
|
|
111
|
+
azureModifiedAt: m.azureModifiedAt.toISO(),
|
|
112
|
+
}));
|
|
113
|
+
// Find local cards not yet mapped
|
|
114
|
+
const cardsResult = await this.deps.cardUseCases.listCards({
|
|
115
|
+
workspace: req.workspace,
|
|
116
|
+
});
|
|
117
|
+
const localCards = cardsResult.success ? cardsResult.data : [];
|
|
118
|
+
const mappedLocalIds = new Set(mappings.map((m) => m.localId));
|
|
119
|
+
const unmappedLocal = localCards
|
|
120
|
+
.filter((c) => !mappedLocalIds.has(c.id))
|
|
121
|
+
.map((c) => ({
|
|
122
|
+
localId: c.id,
|
|
123
|
+
localTitle: c.title,
|
|
124
|
+
entityType: "card",
|
|
125
|
+
}));
|
|
126
|
+
const summary = `${mappingItems.length} synced, ${unmappedLocal.length} local-only`;
|
|
127
|
+
return ok({
|
|
128
|
+
mappings: mappingItems,
|
|
129
|
+
unmappedLocal,
|
|
130
|
+
unmappedAzure: [],
|
|
131
|
+
summary,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// ── Config ────────────────────────────────────────────────────────
|
|
135
|
+
/** Show current config and test connectivity. */
|
|
136
|
+
async configStatus() {
|
|
137
|
+
const config = this.deps.configService.getAzureSyncConfig();
|
|
138
|
+
const connResult = await this.deps.azureClient.testConnection();
|
|
139
|
+
return ok({
|
|
140
|
+
organization: config.organization,
|
|
141
|
+
project: config.project,
|
|
142
|
+
repository: config.repository,
|
|
143
|
+
authMethod: config.authMethod,
|
|
144
|
+
defaultSyncDirection: config.defaultSyncDirection,
|
|
145
|
+
autoDetectTemplate: config.autoDetectTemplate,
|
|
146
|
+
connectionStatus: connResult.success
|
|
147
|
+
? "Connected"
|
|
148
|
+
: `Failed: ${connResult.error}`,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
// ── Private: Push Epics ─────────────────────────────────────────
|
|
152
|
+
async pushEpics(req, template, pushed, _skipped, errors) {
|
|
153
|
+
const epicsResult = await this.deps.epicUseCases.listEpics({
|
|
154
|
+
workspace: req.workspace,
|
|
155
|
+
});
|
|
156
|
+
if (!epicsResult.success) {
|
|
157
|
+
errors.push({ localId: "epics", error: epicsResult.error });
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const epics = req.entityId
|
|
161
|
+
? epicsResult.data.filter((e) => e.id === req.entityId)
|
|
162
|
+
: epicsResult.data;
|
|
163
|
+
for (const epic of epics) {
|
|
164
|
+
try {
|
|
165
|
+
const result = await this.pushSingleEntity(req, template, epic.id, "epic", epic.title, this.fieldBuilder.buildEpicFields(epic, template));
|
|
166
|
+
if (result.success) {
|
|
167
|
+
pushed.push(result.data);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
errors.push({ localId: epic.id, error: result.error });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
errors.push({
|
|
175
|
+
localId: epic.id,
|
|
176
|
+
error: err instanceof Error ? err.message : String(err),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// ── Private: Push Cards ─────────────────────────────────────────
|
|
182
|
+
async pushCards(req, template, pushed, _skipped, errors) {
|
|
183
|
+
const cardsResult = await this.deps.cardUseCases.listCards({
|
|
184
|
+
workspace: req.workspace,
|
|
185
|
+
});
|
|
186
|
+
if (!cardsResult.success) {
|
|
187
|
+
errors.push({ localId: "cards", error: cardsResult.error });
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// Build sprint -> iteration path map for card assignment
|
|
191
|
+
const iterationPathMap = await this.buildIterationPathMap(req);
|
|
192
|
+
const cards = req.entityId
|
|
193
|
+
? cardsResult.data.filter((c) => c.id === req.entityId)
|
|
194
|
+
: cardsResult.data;
|
|
195
|
+
for (const card of cards) {
|
|
196
|
+
try {
|
|
197
|
+
const iterationPath = card.sprintId
|
|
198
|
+
? iterationPathMap.get(card.sprintId)
|
|
199
|
+
: undefined;
|
|
200
|
+
const fields = this.fieldBuilder.buildCardFields({ ...card, iterationPath }, template);
|
|
201
|
+
const result = await this.pushSingleEntity(req, template, card.id, "card", card.title, fields);
|
|
202
|
+
if (result.success) {
|
|
203
|
+
pushed.push(result.data);
|
|
204
|
+
// Link to parent epic if mapped
|
|
205
|
+
if (card.epicId) {
|
|
206
|
+
await this.linkToParentEpic(req, result.data.azureWorkItemId, card.epicId);
|
|
207
|
+
}
|
|
208
|
+
// Push AC as child Tasks
|
|
209
|
+
if (card.acceptanceCriteria.length > 0) {
|
|
210
|
+
const taskResult = await this.taskPush.pushCardTasks(req.org, req.project, template, card, result.data.azureWorkItemId, iterationPath);
|
|
211
|
+
pushed.push(...taskResult.pushed);
|
|
212
|
+
errors.push(...taskResult.errors);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
errors.push({ localId: card.id, error: result.error });
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
errors.push({
|
|
221
|
+
localId: card.id,
|
|
222
|
+
error: err instanceof Error ? err.message : String(err),
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// ── Private: Push Sprints ───────────────────────────────────────
|
|
228
|
+
async pushSprints(req, _template, pushed, skipped, errors) {
|
|
229
|
+
const sprintsResult = await this.deps.sprintUseCases.listSprints({
|
|
230
|
+
workspace: req.workspace,
|
|
231
|
+
});
|
|
232
|
+
if (!sprintsResult.success) {
|
|
233
|
+
errors.push({ localId: "sprints", error: sprintsResult.error });
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const sprints = req.entityId
|
|
237
|
+
? sprintsResult.data.filter((s) => s.id === req.entityId)
|
|
238
|
+
: sprintsResult.data;
|
|
239
|
+
for (const sprint of sprints) {
|
|
240
|
+
try {
|
|
241
|
+
const sanitizedName = sanitizeIterationName(sprint.name);
|
|
242
|
+
const iterResult = await this.deps.azureClient.createIteration(req.org, req.project, sanitizedName, sprint.startDate, sprint.endDate);
|
|
243
|
+
if (iterResult.success) {
|
|
244
|
+
// Register iteration with the default team so it appears in sprint views
|
|
245
|
+
await this.deps.azureClient.addIterationToTeam(req.org, req.project, iterResult.data.id);
|
|
246
|
+
pushed.push({
|
|
247
|
+
localId: sprint.id,
|
|
248
|
+
localTitle: sprint.name,
|
|
249
|
+
azureWorkItemId: 0,
|
|
250
|
+
action: "created",
|
|
251
|
+
url: iterResult.data.path,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
// Iteration may already exist — treat as skip
|
|
256
|
+
skipped.push({
|
|
257
|
+
localId: sprint.id,
|
|
258
|
+
reason: `Iteration may already exist: ${iterResult.error}`,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
catch (err) {
|
|
263
|
+
errors.push({
|
|
264
|
+
localId: sprint.id,
|
|
265
|
+
error: err instanceof Error ? err.message : String(err),
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/** Build a map of local sprint ID -> Azure iteration path. */
|
|
271
|
+
async buildIterationPathMap(req) {
|
|
272
|
+
const map = new Map();
|
|
273
|
+
const sprintsResult = await this.deps.sprintUseCases.listSprints({
|
|
274
|
+
workspace: req.workspace,
|
|
275
|
+
});
|
|
276
|
+
if (!sprintsResult.success)
|
|
277
|
+
return map;
|
|
278
|
+
for (const sprint of sprintsResult.data) {
|
|
279
|
+
const sanitizedName = sanitizeIterationName(sprint.name);
|
|
280
|
+
map.set(sprint.id, `${req.project}\\${sanitizedName}`);
|
|
281
|
+
}
|
|
282
|
+
return map;
|
|
283
|
+
}
|
|
284
|
+
async pushSingleEntity(req, template, localId, entityType, title, fields) {
|
|
285
|
+
const existing = await this.deps.syncMappingRepo.findByLocalId(localId, entityType);
|
|
286
|
+
const wiType = this.fieldMapper.mapWorkItemType(template, entityType);
|
|
287
|
+
if (!wiType) {
|
|
288
|
+
return fail(`No work item type mapping for ${entityType} on ${template}`);
|
|
289
|
+
}
|
|
290
|
+
let action;
|
|
291
|
+
let azureId, azureRev, url;
|
|
292
|
+
let mappingId;
|
|
293
|
+
if (existing) {
|
|
294
|
+
const res = await this.deps.azureClient.updateWorkItem(req.org, req.project, existing.azureWorkItemId.value, fields);
|
|
295
|
+
if (!res.success)
|
|
296
|
+
return res;
|
|
297
|
+
action = "updated";
|
|
298
|
+
azureId = res.data.id;
|
|
299
|
+
azureRev = res.data.rev;
|
|
300
|
+
url = res.data.url;
|
|
301
|
+
mappingId = existing.id;
|
|
302
|
+
const now = Timestamp.now();
|
|
303
|
+
existing.markSynced(now, azureRev);
|
|
304
|
+
await this.deps.syncMappingRepo.save(existing);
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
const res = await this.deps.azureClient.createWorkItem(req.org, req.project, wiType, fields);
|
|
308
|
+
if (!res.success)
|
|
309
|
+
return res;
|
|
310
|
+
action = "created";
|
|
311
|
+
azureId = res.data.id;
|
|
312
|
+
azureRev = res.data.rev;
|
|
313
|
+
url = res.data.url;
|
|
314
|
+
const now = Timestamp.now();
|
|
315
|
+
const seq = await this.deps.syncMappingRepo.nextMappingSequence();
|
|
316
|
+
mappingId = SyncMappingId.create(seq);
|
|
317
|
+
const mapping = SyncMapping.create({
|
|
318
|
+
id: mappingId, localId, localEntityType: entityType,
|
|
319
|
+
azureWorkItemId: WorkItemId.create(azureId),
|
|
320
|
+
azureProject: req.project, azureOrg: req.org,
|
|
321
|
+
processTemplate: template, syncDirection: "push", now, azureRevision: azureRev,
|
|
322
|
+
});
|
|
323
|
+
await this.deps.syncMappingRepo.save(mapping);
|
|
324
|
+
}
|
|
325
|
+
const logSeq = await this.deps.syncMappingRepo.nextLogSequence();
|
|
326
|
+
await this.deps.syncLogRepo.append(SyncLog.create({
|
|
327
|
+
id: SyncLogId.create(logSeq), mappingId, direction: "push",
|
|
328
|
+
status: "success",
|
|
329
|
+
detail: `${action} ${entityType} ${localId} as work item #${azureId}`,
|
|
330
|
+
timestamp: Timestamp.now(),
|
|
331
|
+
}));
|
|
332
|
+
return ok({ localId, localTitle: title, azureWorkItemId: azureId, action, url });
|
|
333
|
+
}
|
|
334
|
+
async linkToParentEpic(req, childWorkItemId, epicLocalId) {
|
|
335
|
+
const epicMapping = await this.deps.syncMappingRepo.findByLocalId(epicLocalId, "epic");
|
|
336
|
+
if (!epicMapping)
|
|
337
|
+
return;
|
|
338
|
+
await this.deps.azureClient.addParentLink(req.org, req.project, childWorkItemId, epicMapping.azureWorkItemId.value);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
//# sourceMappingURL=push-use-cases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push-use-cases.js","sourceRoot":"","sources":["../../../src/application/azure-sync/push-use-cases.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Azure Sync Application — Reverse Field Builder
|
|
3
|
+
*
|
|
4
|
+
* Extracts local entity data from Azure DevOps work item fields.
|
|
5
|
+
* Template-aware: handles field placement differences across
|
|
6
|
+
* Basic, Agile, Scrum, and CMMI process templates.
|
|
7
|
+
*
|
|
8
|
+
* SOLID: SRP — reverse field extraction only
|
|
9
|
+
* DDD: Application-layer transformation from Azure to local representation
|
|
10
|
+
*/
|
|
11
|
+
import type { AzureWorkItem } from "../../domain/azure-sync/ports.js";
|
|
12
|
+
import type { ProcessTemplate, LocalKanbanState } from "../../domain/azure-sync/value-objects.js";
|
|
13
|
+
import { FieldMapper } from "../../domain/azure-sync/services.js";
|
|
14
|
+
/** Data extracted from an Azure work item for creating a local card. */
|
|
15
|
+
export interface ExtractedCardData {
|
|
16
|
+
readonly title: string;
|
|
17
|
+
readonly description: string | undefined;
|
|
18
|
+
readonly priority: string;
|
|
19
|
+
readonly status: LocalKanbanState | undefined;
|
|
20
|
+
readonly storyPoints: number | undefined;
|
|
21
|
+
readonly acceptanceCriteria: readonly string[];
|
|
22
|
+
}
|
|
23
|
+
/** Data extracted from an Azure work item for creating a local epic. */
|
|
24
|
+
export interface ExtractedEpicData {
|
|
25
|
+
readonly title: string;
|
|
26
|
+
readonly description: string | undefined;
|
|
27
|
+
readonly priority: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extracts local entity properties from Azure DevOps work item fields.
|
|
31
|
+
* Template-aware: adapts extraction based on process template capabilities.
|
|
32
|
+
*/
|
|
33
|
+
export declare class ReverseFieldBuilder {
|
|
34
|
+
private readonly fieldMapper;
|
|
35
|
+
constructor(fieldMapper: FieldMapper);
|
|
36
|
+
/** Extract card data from an Azure work item. */
|
|
37
|
+
extractCardData(workItem: AzureWorkItem, template: ProcessTemplate): ExtractedCardData;
|
|
38
|
+
/** Extract epic data from an Azure work item. */
|
|
39
|
+
extractEpicData(workItem: AzureWorkItem): ExtractedEpicData;
|
|
40
|
+
/** Compute a list of changes between current local state and Azure data. */
|
|
41
|
+
diffCardChanges(local: {
|
|
42
|
+
title: string;
|
|
43
|
+
description: string | undefined;
|
|
44
|
+
priority: string;
|
|
45
|
+
status: string;
|
|
46
|
+
}, extracted: ExtractedCardData): readonly string[];
|
|
47
|
+
private extractPriority;
|
|
48
|
+
private extractString;
|
|
49
|
+
private extractTemplateFields;
|
|
50
|
+
private extractListItems;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=reverse-field-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reverse-field-builder.d.ts","sourceRoot":"","sources":["../../../src/application/azure-sync/reverse-field-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAClG,OAAO,EAAE,WAAW,EAAgB,MAAM,qCAAqC,CAAC;AAIhF,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;CAChD;AAED,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAaD;;;GAGG;AACH,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,WAAW;IAErD,iDAAiD;IACjD,eAAe,CACb,QAAQ,EAAE,aAAa,EACvB,QAAQ,EAAE,eAAe,GACxB,iBAAiB;IAapB,iDAAiD;IACjD,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,iBAAiB;IAS3D,4EAA4E;IAC5E,eAAe,CACb,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAC3F,SAAS,EAAE,iBAAiB,GAC3B,SAAS,MAAM,EAAE;IAmBpB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,gBAAgB;CAazB"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Azure Sync Application — Reverse Field Builder
|
|
3
|
+
*
|
|
4
|
+
* Extracts local entity data from Azure DevOps work item fields.
|
|
5
|
+
* Template-aware: handles field placement differences across
|
|
6
|
+
* Basic, Agile, Scrum, and CMMI process templates.
|
|
7
|
+
*
|
|
8
|
+
* SOLID: SRP — reverse field extraction only
|
|
9
|
+
* DDD: Application-layer transformation from Azure to local representation
|
|
10
|
+
*/
|
|
11
|
+
import { FieldMapper, AZURE_FIELDS } from "../../domain/azure-sync/services.js";
|
|
12
|
+
// ─── Priority Reverse Map ─────────────────────────────────────────────────────
|
|
13
|
+
const AZURE_PRIORITY_TO_LOCAL = {
|
|
14
|
+
1: "high",
|
|
15
|
+
2: "medium",
|
|
16
|
+
3: "low",
|
|
17
|
+
4: "low",
|
|
18
|
+
};
|
|
19
|
+
// ─── Reverse Field Builder ────────────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Extracts local entity properties from Azure DevOps work item fields.
|
|
22
|
+
* Template-aware: adapts extraction based on process template capabilities.
|
|
23
|
+
*/
|
|
24
|
+
export class ReverseFieldBuilder {
|
|
25
|
+
fieldMapper;
|
|
26
|
+
constructor(fieldMapper) {
|
|
27
|
+
this.fieldMapper = fieldMapper;
|
|
28
|
+
}
|
|
29
|
+
/** Extract card data from an Azure work item. */
|
|
30
|
+
extractCardData(workItem, template) {
|
|
31
|
+
const fields = workItem.fields;
|
|
32
|
+
const title = String(fields[AZURE_FIELDS.TITLE] ?? "");
|
|
33
|
+
const azureState = String(fields[AZURE_FIELDS.STATE] ?? "");
|
|
34
|
+
const status = this.fieldMapper.mapStateFromAzure(template, azureState);
|
|
35
|
+
const priority = this.extractPriority(fields);
|
|
36
|
+
const { description, storyPoints, acceptanceCriteria } = this.extractTemplateFields(fields, template);
|
|
37
|
+
return { title, description, priority, status, storyPoints, acceptanceCriteria };
|
|
38
|
+
}
|
|
39
|
+
/** Extract epic data from an Azure work item. */
|
|
40
|
+
extractEpicData(workItem) {
|
|
41
|
+
const fields = workItem.fields;
|
|
42
|
+
return {
|
|
43
|
+
title: String(fields[AZURE_FIELDS.TITLE] ?? ""),
|
|
44
|
+
description: this.extractString(fields, AZURE_FIELDS.DESCRIPTION),
|
|
45
|
+
priority: this.extractPriority(fields),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** Compute a list of changes between current local state and Azure data. */
|
|
49
|
+
diffCardChanges(local, extracted) {
|
|
50
|
+
const changes = [];
|
|
51
|
+
if (local.title !== extracted.title) {
|
|
52
|
+
changes.push(`title: "${local.title}" -> "${extracted.title}"`);
|
|
53
|
+
}
|
|
54
|
+
if (local.description !== extracted.description) {
|
|
55
|
+
changes.push("description changed");
|
|
56
|
+
}
|
|
57
|
+
if (local.priority !== extracted.priority) {
|
|
58
|
+
changes.push(`priority: ${local.priority} -> ${extracted.priority}`);
|
|
59
|
+
}
|
|
60
|
+
if (extracted.status !== undefined && local.status !== extracted.status) {
|
|
61
|
+
changes.push(`status: ${local.status} -> ${extracted.status}`);
|
|
62
|
+
}
|
|
63
|
+
return changes;
|
|
64
|
+
}
|
|
65
|
+
// ── Private ─────────────────────────────────────────────────────
|
|
66
|
+
extractPriority(fields) {
|
|
67
|
+
const raw = fields[AZURE_FIELDS.PRIORITY];
|
|
68
|
+
if (typeof raw === "number") {
|
|
69
|
+
return AZURE_PRIORITY_TO_LOCAL[raw] ?? "medium";
|
|
70
|
+
}
|
|
71
|
+
return "medium";
|
|
72
|
+
}
|
|
73
|
+
extractString(fields, key) {
|
|
74
|
+
const val = fields[key];
|
|
75
|
+
if (typeof val === "string" && val.trim().length > 0)
|
|
76
|
+
return val.trim();
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
extractTemplateFields(fields, template) {
|
|
80
|
+
const mappings = this.fieldMapper.getFieldMappings(template);
|
|
81
|
+
const acMapping = mappings.find((m) => m.localField === "acceptanceCriteria");
|
|
82
|
+
const spMapping = mappings.find((m) => m.localField === "storyPoints");
|
|
83
|
+
let description;
|
|
84
|
+
let acceptanceCriteria = [];
|
|
85
|
+
let storyPoints;
|
|
86
|
+
if (acMapping && acMapping.fallback === "description") {
|
|
87
|
+
// Basic/CMMI: AC embedded in description HTML
|
|
88
|
+
const rawDesc = this.extractString(fields, AZURE_FIELDS.DESCRIPTION) ?? "";
|
|
89
|
+
const extracted = this.fieldMapper.extractAcceptanceCriteriaFromHtml(rawDesc);
|
|
90
|
+
description = extracted.description || undefined;
|
|
91
|
+
acceptanceCriteria = extracted.criteria;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
// Agile/Scrum: separate fields
|
|
95
|
+
description = this.extractString(fields, AZURE_FIELDS.DESCRIPTION);
|
|
96
|
+
if (acMapping) {
|
|
97
|
+
const acHtml = this.extractString(fields, acMapping.azureField);
|
|
98
|
+
if (acHtml) {
|
|
99
|
+
acceptanceCriteria = this.extractListItems(acHtml);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (spMapping && spMapping.fallback === "tag") {
|
|
104
|
+
// Basic/CMMI: SP in tags
|
|
105
|
+
const tags = String(fields[AZURE_FIELDS.TAGS] ?? "");
|
|
106
|
+
storyPoints = this.fieldMapper.extractStoryPointsFromTags(tags);
|
|
107
|
+
}
|
|
108
|
+
else if (spMapping) {
|
|
109
|
+
// Agile/Scrum: native field
|
|
110
|
+
const raw = fields[spMapping.azureField];
|
|
111
|
+
if (typeof raw === "number")
|
|
112
|
+
storyPoints = raw;
|
|
113
|
+
}
|
|
114
|
+
return { description, storyPoints, acceptanceCriteria };
|
|
115
|
+
}
|
|
116
|
+
extractListItems(html) {
|
|
117
|
+
const liRegex = /<li>\s*(.*?)\s*<\/li>/gi;
|
|
118
|
+
const items = [];
|
|
119
|
+
let match = liRegex.exec(html);
|
|
120
|
+
while (match !== null) {
|
|
121
|
+
const content = match[1];
|
|
122
|
+
if (content !== undefined && content.trim().length > 0) {
|
|
123
|
+
items.push(content.trim());
|
|
124
|
+
}
|
|
125
|
+
match = liRegex.exec(html);
|
|
126
|
+
}
|
|
127
|
+
return items;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=reverse-field-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reverse-field-builder.js","sourceRoot":"","sources":["../../../src/application/azure-sync/reverse-field-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Azure Sync Application — Task Push Use Cases
|
|
3
|
+
*
|
|
4
|
+
* Pushes card acceptance criteria as Azure DevOps Task work items.
|
|
5
|
+
* Each AC becomes a child Task linked to the parent card work item.
|
|
6
|
+
* Tracks AC-Task mappings with local_entity_type 'task' and composite
|
|
7
|
+
* local IDs (e.g. "CD-005:AC-0", "CD-005:AC-1").
|
|
8
|
+
*
|
|
9
|
+
* SOLID: SRP — task push orchestration only (split from push-use-cases.ts)
|
|
10
|
+
* SOLID: DIP — depends on interfaces (ports, repositories)
|
|
11
|
+
* DDD: Application service coordinating bounded contexts
|
|
12
|
+
*/
|
|
13
|
+
import type { AzureDevOpsPort } from "../../domain/azure-sync/ports.js";
|
|
14
|
+
import type { SyncMappingRepository, SyncLogRepository } from "../../domain/azure-sync/repositories.js";
|
|
15
|
+
import type { ProcessTemplate } from "../../domain/azure-sync/value-objects.js";
|
|
16
|
+
import type { PushResultItem, PushErrorItem } from "./dtos.js";
|
|
17
|
+
/** Card data needed for task push. */
|
|
18
|
+
export interface CardForTaskPush {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly title: string;
|
|
21
|
+
readonly acceptanceCriteria: readonly {
|
|
22
|
+
description: string;
|
|
23
|
+
met: boolean;
|
|
24
|
+
}[];
|
|
25
|
+
readonly sprintId: string | undefined;
|
|
26
|
+
}
|
|
27
|
+
/** Dependencies for TaskPushUseCases. */
|
|
28
|
+
export interface TaskPushDeps {
|
|
29
|
+
readonly azureClient: AzureDevOpsPort;
|
|
30
|
+
readonly syncMappingRepo: SyncMappingRepository;
|
|
31
|
+
readonly syncLogRepo: SyncLogRepository;
|
|
32
|
+
}
|
|
33
|
+
/** Result of pushing tasks for a single card. */
|
|
34
|
+
export interface TaskPushResult {
|
|
35
|
+
readonly pushed: readonly PushResultItem[];
|
|
36
|
+
readonly errors: readonly PushErrorItem[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Build a composite local ID for an AC-derived task.
|
|
40
|
+
* Format: "{cardId}:AC-{index}" (e.g. "CD-005:AC-0").
|
|
41
|
+
*/
|
|
42
|
+
export declare function buildTaskLocalId(cardId: string, acIndex: number): string;
|
|
43
|
+
/**
|
|
44
|
+
* Parse a composite task local ID back into card ID and AC index.
|
|
45
|
+
* Returns undefined if the format is invalid.
|
|
46
|
+
*/
|
|
47
|
+
export declare function parseTaskLocalId(localId: string): {
|
|
48
|
+
cardId: string;
|
|
49
|
+
acIndex: number;
|
|
50
|
+
} | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Pushes card acceptance criteria as Azure DevOps Task work items.
|
|
53
|
+
* Each AC maps to one Task, linked as child of the parent card work item.
|
|
54
|
+
*/
|
|
55
|
+
export declare class TaskPushUseCases {
|
|
56
|
+
private readonly deps;
|
|
57
|
+
private readonly fieldMapper;
|
|
58
|
+
private readonly fieldBuilder;
|
|
59
|
+
constructor(deps: TaskPushDeps);
|
|
60
|
+
/**
|
|
61
|
+
* Push all acceptance criteria for a card as Tasks in Azure DevOps.
|
|
62
|
+
* Creates new Tasks for unmapped AC, updates existing Tasks for mapped AC.
|
|
63
|
+
* Links each Task as child of the parent card work item.
|
|
64
|
+
*/
|
|
65
|
+
pushCardTasks(org: string, project: string, template: ProcessTemplate, card: CardForTaskPush, parentWorkItemId: number, iterationPath: string | undefined): Promise<TaskPushResult>;
|
|
66
|
+
private pushSingleTask;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=task-push-use-cases.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-push-use-cases.d.ts","sourceRoot":"","sources":["../../../src/application/azure-sync/task-push-use-cases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kCAAkC,CAAC;AACzF,OAAO,KAAK,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAIxG,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,0CAA0C,CAAC;AAGjG,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAI/D,sCAAsC;AACtC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,kBAAkB,EAAE,SAAS;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;IAC9E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,yCAAyC;AACzC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC;IACtC,QAAQ,CAAC,eAAe,EAAE,qBAAqB,CAAC;IAChD,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;CACzC;AAED,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAExE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,GACd;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAOjD;AAID;;;GAGG;AACH,qBAAa,gBAAgB;IAIf,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA2C;gBAE3C,IAAI,EAAE,YAAY;IAE/C;;;;OAIG;IACG,aAAa,CACjB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE,eAAe,EACrB,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,OAAO,CAAC,cAAc,CAAC;YA0CZ,cAAc;CA0G7B"}
|