@mgsoftwarebv/mcp-server-bridge 3.5.19 → 3.5.20
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/index.js +877 -206
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -154,8 +154,8 @@ var init_util = __esm({
|
|
|
154
154
|
"set"
|
|
155
155
|
]);
|
|
156
156
|
getParsedType3 = (data) => {
|
|
157
|
-
const
|
|
158
|
-
switch (
|
|
157
|
+
const t9 = typeof data;
|
|
158
|
+
switch (t9) {
|
|
159
159
|
case "undefined":
|
|
160
160
|
return ZodParsedType2.undefined;
|
|
161
161
|
case "string":
|
|
@@ -5501,7 +5501,7 @@ var require_dataType = __commonJS({
|
|
|
5501
5501
|
exports2.coerceAndCheckDataType = coerceAndCheckDataType;
|
|
5502
5502
|
var COERCIBLE = /* @__PURE__ */ new Set(["string", "number", "integer", "boolean", "null"]);
|
|
5503
5503
|
function coerceToTypes(types5, coerceTypes) {
|
|
5504
|
-
return coerceTypes ? types5.filter((
|
|
5504
|
+
return coerceTypes ? types5.filter((t9) => COERCIBLE.has(t9) || coerceTypes === "array" && t9 === "array") : [];
|
|
5505
5505
|
}
|
|
5506
5506
|
function coerceData(it, types5, coerceTo) {
|
|
5507
5507
|
const { gen, data, opts } = it;
|
|
@@ -5511,9 +5511,9 @@ var require_dataType = __commonJS({
|
|
|
5511
5511
|
gen.if((0, codegen_1._)`${dataType} == 'object' && Array.isArray(${data}) && ${data}.length == 1`, () => gen.assign(data, (0, codegen_1._)`${data}[0]`).assign(dataType, (0, codegen_1._)`typeof ${data}`).if(checkDataTypes(types5, data, opts.strictNumbers), () => gen.assign(coerced, data)));
|
|
5512
5512
|
}
|
|
5513
5513
|
gen.if((0, codegen_1._)`${coerced} !== undefined`);
|
|
5514
|
-
for (const
|
|
5515
|
-
if (COERCIBLE.has(
|
|
5516
|
-
coerceSpecificType(
|
|
5514
|
+
for (const t9 of coerceTo) {
|
|
5515
|
+
if (COERCIBLE.has(t9) || t9 === "array" && opts.coerceTypes === "array") {
|
|
5516
|
+
coerceSpecificType(t9);
|
|
5517
5517
|
}
|
|
5518
5518
|
}
|
|
5519
5519
|
gen.else();
|
|
@@ -5523,8 +5523,8 @@ var require_dataType = __commonJS({
|
|
|
5523
5523
|
gen.assign(data, coerced);
|
|
5524
5524
|
assignParentData(it, coerced);
|
|
5525
5525
|
});
|
|
5526
|
-
function coerceSpecificType(
|
|
5527
|
-
switch (
|
|
5526
|
+
function coerceSpecificType(t9) {
|
|
5527
|
+
switch (t9) {
|
|
5528
5528
|
case "string":
|
|
5529
5529
|
gen.elseIf((0, codegen_1._)`${dataType} == "number" || ${dataType} == "boolean"`).assign(coerced, (0, codegen_1._)`"" + ${data}`).elseIf((0, codegen_1._)`${data} === null`).assign(coerced, (0, codegen_1._)`""`);
|
|
5530
5530
|
return;
|
|
@@ -5596,8 +5596,8 @@ var require_dataType = __commonJS({
|
|
|
5596
5596
|
}
|
|
5597
5597
|
if (types5.number)
|
|
5598
5598
|
delete types5.integer;
|
|
5599
|
-
for (const
|
|
5600
|
-
cond = (0, codegen_1.and)(cond, checkDataType(
|
|
5599
|
+
for (const t9 in types5)
|
|
5600
|
+
cond = (0, codegen_1.and)(cond, checkDataType(t9, data, strictNums, correct));
|
|
5601
5601
|
return cond;
|
|
5602
5602
|
}
|
|
5603
5603
|
exports2.checkDataTypes = checkDataTypes;
|
|
@@ -6504,9 +6504,9 @@ var require_validate = __commonJS({
|
|
|
6504
6504
|
it.dataTypes = types5;
|
|
6505
6505
|
return;
|
|
6506
6506
|
}
|
|
6507
|
-
types5.forEach((
|
|
6508
|
-
if (!includesType(it.dataTypes,
|
|
6509
|
-
strictTypesError(it, `type "${
|
|
6507
|
+
types5.forEach((t9) => {
|
|
6508
|
+
if (!includesType(it.dataTypes, t9)) {
|
|
6509
|
+
strictTypesError(it, `type "${t9}" not allowed by context "${it.dataTypes.join(",")}"`);
|
|
6510
6510
|
}
|
|
6511
6511
|
});
|
|
6512
6512
|
narrowSchemaTypes(it, types5);
|
|
@@ -6522,7 +6522,7 @@ var require_validate = __commonJS({
|
|
|
6522
6522
|
const rule = rules[keyword];
|
|
6523
6523
|
if (typeof rule == "object" && (0, applicability_1.shouldUseRule)(it.schema, rule)) {
|
|
6524
6524
|
const { type } = rule.definition;
|
|
6525
|
-
if (type.length && !type.some((
|
|
6525
|
+
if (type.length && !type.some((t9) => hasApplicableType(ts, t9))) {
|
|
6526
6526
|
strictTypesError(it, `missing type "${type.join(",")}" for keyword "${keyword}"`);
|
|
6527
6527
|
}
|
|
6528
6528
|
}
|
|
@@ -6531,15 +6531,15 @@ var require_validate = __commonJS({
|
|
|
6531
6531
|
function hasApplicableType(schTs, kwdT) {
|
|
6532
6532
|
return schTs.includes(kwdT) || kwdT === "number" && schTs.includes("integer");
|
|
6533
6533
|
}
|
|
6534
|
-
function includesType(ts,
|
|
6535
|
-
return ts.includes(
|
|
6534
|
+
function includesType(ts, t9) {
|
|
6535
|
+
return ts.includes(t9) || t9 === "integer" && ts.includes("number");
|
|
6536
6536
|
}
|
|
6537
6537
|
function narrowSchemaTypes(it, withTypes) {
|
|
6538
6538
|
const ts = [];
|
|
6539
|
-
for (const
|
|
6540
|
-
if (includesType(withTypes,
|
|
6541
|
-
ts.push(
|
|
6542
|
-
else if (withTypes.includes("integer") &&
|
|
6539
|
+
for (const t9 of it.dataTypes) {
|
|
6540
|
+
if (includesType(withTypes, t9))
|
|
6541
|
+
ts.push(t9);
|
|
6542
|
+
else if (withTypes.includes("integer") && t9 === "number")
|
|
6543
6543
|
ts.push("integer");
|
|
6544
6544
|
}
|
|
6545
6545
|
it.dataTypes = ts;
|
|
@@ -8141,7 +8141,7 @@ var require_core = __commonJS({
|
|
|
8141
8141
|
type: (0, dataType_1.getJSONTypes)(def.type),
|
|
8142
8142
|
schemaType: (0, dataType_1.getJSONTypes)(def.schemaType)
|
|
8143
8143
|
};
|
|
8144
|
-
(0, util_1.eachItem)(keyword, definition.type.length === 0 ? (k6) => addRule.call(this, k6, definition) : (k6) => definition.type.forEach((
|
|
8144
|
+
(0, util_1.eachItem)(keyword, definition.type.length === 0 ? (k6) => addRule.call(this, k6, definition) : (k6) => definition.type.forEach((t9) => addRule.call(this, k6, definition, t9)));
|
|
8145
8145
|
return this;
|
|
8146
8146
|
}
|
|
8147
8147
|
getKeyword(keyword) {
|
|
@@ -8340,7 +8340,7 @@ var require_core = __commonJS({
|
|
|
8340
8340
|
if (dataType && post)
|
|
8341
8341
|
throw new Error('keyword with "post" flag cannot have "type"');
|
|
8342
8342
|
const { RULES } = this;
|
|
8343
|
-
let ruleGroup = post ? RULES.post : RULES.rules.find(({ type:
|
|
8343
|
+
let ruleGroup = post ? RULES.post : RULES.rules.find(({ type: t9 }) => t9 === dataType);
|
|
8344
8344
|
if (!ruleGroup) {
|
|
8345
8345
|
ruleGroup = { type: dataType, rules: [] };
|
|
8346
8346
|
RULES.rules.push(ruleGroup);
|
|
@@ -8866,7 +8866,7 @@ var require_uniqueItems = __commonJS({
|
|
|
8866
8866
|
gen.if((0, codegen_1._)`${i6} > 1`, () => (canOptimize() ? loopN : loopN2)(i6, j6));
|
|
8867
8867
|
}
|
|
8868
8868
|
function canOptimize() {
|
|
8869
|
-
return itemTypes.length > 0 && !itemTypes.some((
|
|
8869
|
+
return itemTypes.length > 0 && !itemTypes.some((t9) => t9 === "object" || t9 === "array");
|
|
8870
8870
|
}
|
|
8871
8871
|
function loopN(i6, j6) {
|
|
8872
8872
|
const item = gen.name("item");
|
|
@@ -11643,8 +11643,8 @@ function getLengthableOrigin2(input) {
|
|
|
11643
11643
|
return "unknown";
|
|
11644
11644
|
}
|
|
11645
11645
|
function parsedType2(data) {
|
|
11646
|
-
const
|
|
11647
|
-
switch (
|
|
11646
|
+
const t9 = typeof data;
|
|
11647
|
+
switch (t9) {
|
|
11648
11648
|
case "number": {
|
|
11649
11649
|
return Number.isNaN(data) ? "nan" : "number";
|
|
11650
11650
|
}
|
|
@@ -11661,7 +11661,7 @@ function parsedType2(data) {
|
|
|
11661
11661
|
}
|
|
11662
11662
|
}
|
|
11663
11663
|
}
|
|
11664
|
-
return
|
|
11664
|
+
return t9;
|
|
11665
11665
|
}
|
|
11666
11666
|
function issue2(...args2) {
|
|
11667
11667
|
const [iss, input, inst] = args2;
|
|
@@ -11736,8 +11736,8 @@ var init_util2 = __esm({
|
|
|
11736
11736
|
}
|
|
11737
11737
|
});
|
|
11738
11738
|
getParsedType4 = (data) => {
|
|
11739
|
-
const
|
|
11740
|
-
switch (
|
|
11739
|
+
const t9 = typeof data;
|
|
11740
|
+
switch (t9) {
|
|
11741
11741
|
case "undefined":
|
|
11742
11742
|
return "undefined";
|
|
11743
11743
|
case "string":
|
|
@@ -11776,7 +11776,7 @@ var init_util2 = __esm({
|
|
|
11776
11776
|
}
|
|
11777
11777
|
return "object";
|
|
11778
11778
|
default:
|
|
11779
|
-
throw new Error(`Unknown data type: ${
|
|
11779
|
+
throw new Error(`Unknown data type: ${t9}`);
|
|
11780
11780
|
}
|
|
11781
11781
|
};
|
|
11782
11782
|
propertyKeyTypes2 = /* @__PURE__ */ new Set(["string", "number", "symbol"]);
|
|
@@ -12891,12 +12891,12 @@ function handleCatchall2(proms, input, payload, ctx, def, inst) {
|
|
|
12891
12891
|
const unrecognized = [];
|
|
12892
12892
|
const keySet = def.keySet;
|
|
12893
12893
|
const _catchall = def.catchall._zod;
|
|
12894
|
-
const
|
|
12894
|
+
const t9 = _catchall.def.type;
|
|
12895
12895
|
const isOptionalOut = _catchall.optout === "optional";
|
|
12896
12896
|
for (const key in input) {
|
|
12897
12897
|
if (keySet.has(key))
|
|
12898
12898
|
continue;
|
|
12899
|
-
if (
|
|
12899
|
+
if (t9 === "never") {
|
|
12900
12900
|
unrecognized.push(key);
|
|
12901
12901
|
continue;
|
|
12902
12902
|
}
|
|
@@ -16657,16 +16657,16 @@ var init_he = __esm({
|
|
|
16657
16657
|
number: { unit: "", shortLabel: "\u05E7\u05D8\u05DF", longLabel: "\u05D2\u05D3\u05D5\u05DC" }
|
|
16658
16658
|
// no unit
|
|
16659
16659
|
};
|
|
16660
|
-
const typeEntry = (
|
|
16661
|
-
const typeLabel = (
|
|
16662
|
-
const e6 = typeEntry(
|
|
16660
|
+
const typeEntry = (t9) => t9 ? TypeNames[t9] : void 0;
|
|
16661
|
+
const typeLabel = (t9) => {
|
|
16662
|
+
const e6 = typeEntry(t9);
|
|
16663
16663
|
if (e6)
|
|
16664
16664
|
return e6.label;
|
|
16665
|
-
return
|
|
16665
|
+
return t9 ?? TypeNames.unknown.label;
|
|
16666
16666
|
};
|
|
16667
|
-
const withDefinite = (
|
|
16668
|
-
const verbFor = (
|
|
16669
|
-
const e6 = typeEntry(
|
|
16667
|
+
const withDefinite = (t9) => `\u05D4${typeLabel(t9)}`;
|
|
16668
|
+
const verbFor = (t9) => {
|
|
16669
|
+
const e6 = typeEntry(t9);
|
|
16670
16670
|
const gender = e6?.gender ?? "m";
|
|
16671
16671
|
return gender === "f" ? "\u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D4\u05D9\u05D5\u05EA" : "\u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA";
|
|
16672
16672
|
};
|
|
@@ -24658,8 +24658,8 @@ function convertBaseSchema(schema, ctx) {
|
|
|
24658
24658
|
}
|
|
24659
24659
|
const type = schema.type;
|
|
24660
24660
|
if (Array.isArray(type)) {
|
|
24661
|
-
const typeSchemas = type.map((
|
|
24662
|
-
const typeSchema = { ...schema, type:
|
|
24661
|
+
const typeSchemas = type.map((t9) => {
|
|
24662
|
+
const typeSchema = { ...schema, type: t9 };
|
|
24663
24663
|
return convertBaseSchema(typeSchema, ctx);
|
|
24664
24664
|
});
|
|
24665
24665
|
if (typeSchemas.length === 0) {
|
|
@@ -53092,9 +53092,9 @@ var init_schemaDeserializationMiddleware = __esm({
|
|
|
53092
53092
|
schemaDeserializationMiddleware = (config3) => (next, context2) => async (args2) => {
|
|
53093
53093
|
const { response } = await next(args2);
|
|
53094
53094
|
const { operationSchema } = getSmithyContext(context2);
|
|
53095
|
-
const [, ns, n3,
|
|
53095
|
+
const [, ns, n3, t9, i6, o3] = operationSchema ?? [];
|
|
53096
53096
|
try {
|
|
53097
|
-
const parsed = await config3.protocol.deserializeResponse(operation(ns, n3,
|
|
53097
|
+
const parsed = await config3.protocol.deserializeResponse(operation(ns, n3, t9, i6, o3), {
|
|
53098
53098
|
...config3,
|
|
53099
53099
|
...context2
|
|
53100
53100
|
}, response);
|
|
@@ -53159,9 +53159,9 @@ var init_schemaSerializationMiddleware = __esm({
|
|
|
53159
53159
|
init_operation();
|
|
53160
53160
|
schemaSerializationMiddleware = (config3) => (next, context2) => async (args2) => {
|
|
53161
53161
|
const { operationSchema } = getSmithyContext(context2);
|
|
53162
|
-
const [, ns, n3,
|
|
53162
|
+
const [, ns, n3, t9, i6, o3] = operationSchema ?? [];
|
|
53163
53163
|
const endpoint2 = context2.endpointV2 ? async () => toEndpointV1(context2.endpointV2) : config3.endpoint;
|
|
53164
|
-
const request3 = await config3.protocol.serializeRequest(operation(ns, n3,
|
|
53164
|
+
const request3 = await config3.protocol.serializeRequest(operation(ns, n3, t9, i6, o3), args2.input, {
|
|
53165
53165
|
...config3,
|
|
53166
53166
|
...context2,
|
|
53167
53167
|
endpoint: endpoint2
|
|
@@ -56495,9 +56495,9 @@ function __awaiter(thisArg, _arguments, P2, generator) {
|
|
|
56495
56495
|
}
|
|
56496
56496
|
function __generator(thisArg, body) {
|
|
56497
56497
|
var _ = { label: 0, sent: function() {
|
|
56498
|
-
if (
|
|
56499
|
-
return
|
|
56500
|
-
}, trys: [], ops: [] }, f6, y2,
|
|
56498
|
+
if (t9[0] & 1) throw t9[1];
|
|
56499
|
+
return t9[1];
|
|
56500
|
+
}, trys: [], ops: [] }, f6, y2, t9, g6 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
56501
56501
|
return g6.next = verb(0), g6["throw"] = verb(1), g6["return"] = verb(2), typeof Symbol === "function" && (g6[Symbol.iterator] = function() {
|
|
56502
56502
|
return this;
|
|
56503
56503
|
}), g6;
|
|
@@ -56509,12 +56509,12 @@ function __generator(thisArg, body) {
|
|
|
56509
56509
|
function step(op) {
|
|
56510
56510
|
if (f6) throw new TypeError("Generator is already executing.");
|
|
56511
56511
|
while (g6 && (g6 = 0, op[0] && (_ = 0)), _) try {
|
|
56512
|
-
if (f6 = 1, y2 && (
|
|
56513
|
-
if (y2 = 0,
|
|
56512
|
+
if (f6 = 1, y2 && (t9 = op[0] & 2 ? y2["return"] : op[0] ? y2["throw"] || ((t9 = y2["return"]) && t9.call(y2), 0) : y2.next) && !(t9 = t9.call(y2, op[1])).done) return t9;
|
|
56513
|
+
if (y2 = 0, t9) op = [op[0] & 2, t9.value];
|
|
56514
56514
|
switch (op[0]) {
|
|
56515
56515
|
case 0:
|
|
56516
56516
|
case 1:
|
|
56517
|
-
|
|
56517
|
+
t9 = op;
|
|
56518
56518
|
break;
|
|
56519
56519
|
case 4:
|
|
56520
56520
|
_.label++;
|
|
@@ -56529,25 +56529,25 @@ function __generator(thisArg, body) {
|
|
|
56529
56529
|
_.trys.pop();
|
|
56530
56530
|
continue;
|
|
56531
56531
|
default:
|
|
56532
|
-
if (!(
|
|
56532
|
+
if (!(t9 = _.trys, t9 = t9.length > 0 && t9[t9.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
56533
56533
|
_ = 0;
|
|
56534
56534
|
continue;
|
|
56535
56535
|
}
|
|
56536
|
-
if (op[0] === 3 && (!
|
|
56536
|
+
if (op[0] === 3 && (!t9 || op[1] > t9[0] && op[1] < t9[3])) {
|
|
56537
56537
|
_.label = op[1];
|
|
56538
56538
|
break;
|
|
56539
56539
|
}
|
|
56540
|
-
if (op[0] === 6 && _.label <
|
|
56541
|
-
_.label =
|
|
56542
|
-
|
|
56540
|
+
if (op[0] === 6 && _.label < t9[1]) {
|
|
56541
|
+
_.label = t9[1];
|
|
56542
|
+
t9 = op;
|
|
56543
56543
|
break;
|
|
56544
56544
|
}
|
|
56545
|
-
if (
|
|
56546
|
-
_.label =
|
|
56545
|
+
if (t9 && _.label < t9[2]) {
|
|
56546
|
+
_.label = t9[2];
|
|
56547
56547
|
_.ops.push(op);
|
|
56548
56548
|
break;
|
|
56549
56549
|
}
|
|
56550
|
-
if (
|
|
56550
|
+
if (t9[2]) _.ops.pop();
|
|
56551
56551
|
_.trys.pop();
|
|
56552
56552
|
continue;
|
|
56553
56553
|
}
|
|
@@ -56556,7 +56556,7 @@ function __generator(thisArg, body) {
|
|
|
56556
56556
|
op = [6, e6];
|
|
56557
56557
|
y2 = 0;
|
|
56558
56558
|
} finally {
|
|
56559
|
-
f6 =
|
|
56559
|
+
f6 = t9 = 0;
|
|
56560
56560
|
}
|
|
56561
56561
|
if (op[0] & 5) throw op[1];
|
|
56562
56562
|
return { value: op[0] ? op[1] : void 0, done: true };
|
|
@@ -59404,8 +59404,8 @@ var init_DefaultRateLimiter = __esm({
|
|
|
59404
59404
|
this.availableTokens = Math.min(this.availableTokens, this.maxCapacity);
|
|
59405
59405
|
}
|
|
59406
59406
|
updateMeasuredRate() {
|
|
59407
|
-
const
|
|
59408
|
-
const timeBucket = Math.floor(
|
|
59407
|
+
const t9 = this.getCurrentTimeInSeconds();
|
|
59408
|
+
const timeBucket = Math.floor(t9 * 2) / 2;
|
|
59409
59409
|
this.requestCount++;
|
|
59410
59410
|
if (timeBucket > this.lastTxRateBucket) {
|
|
59411
59411
|
const currentRate = this.requestCount / (timeBucket - this.lastTxRateBucket);
|
|
@@ -61489,9 +61489,9 @@ var init_JsonShapeDeserializer = __esm({
|
|
|
61489
61489
|
} else if (typeof record3.__type === "string") {
|
|
61490
61490
|
for (const k6 in record3) {
|
|
61491
61491
|
const v2 = record3[k6];
|
|
61492
|
-
const
|
|
61493
|
-
if (!(
|
|
61494
|
-
out[
|
|
61492
|
+
const t9 = jsonName ? nameMap[k6] ?? k6 : k6;
|
|
61493
|
+
if (!(t9 in out)) {
|
|
61494
|
+
out[t9] = v2;
|
|
61495
61495
|
}
|
|
61496
61496
|
}
|
|
61497
61497
|
}
|
|
@@ -62293,7 +62293,7 @@ function validate2(xmlData, options) {
|
|
|
62293
62293
|
} else if (tags2.length == 1) {
|
|
62294
62294
|
return getErrorObject("InvalidTag", "Unclosed tag '" + tags2[0].tagName + "'.", getLineNumberForPosition(xmlData, tags2[0].tagStartPos));
|
|
62295
62295
|
} else if (tags2.length > 0) {
|
|
62296
|
-
return getErrorObject("InvalidXml", "Invalid '" + JSON.stringify(tags2.map((
|
|
62296
|
+
return getErrorObject("InvalidXml", "Invalid '" + JSON.stringify(tags2.map((t9) => t9.tagName), null, 4).replace(/\r?\n/g, "") + "' found.", { line: 1, col: 1 });
|
|
62297
62297
|
}
|
|
62298
62298
|
return true;
|
|
62299
62299
|
}
|
|
@@ -75087,8 +75087,8 @@ function numKeys(data) {
|
|
|
75087
75087
|
return keyCount;
|
|
75088
75088
|
}
|
|
75089
75089
|
var getParsedType = (data) => {
|
|
75090
|
-
const
|
|
75091
|
-
switch (
|
|
75090
|
+
const t9 = typeof data;
|
|
75091
|
+
switch (t9) {
|
|
75092
75092
|
case "undefined":
|
|
75093
75093
|
return "undefined";
|
|
75094
75094
|
case "string":
|
|
@@ -75127,7 +75127,7 @@ var getParsedType = (data) => {
|
|
|
75127
75127
|
}
|
|
75128
75128
|
return "object";
|
|
75129
75129
|
default:
|
|
75130
|
-
throw new Error(`Unknown data type: ${
|
|
75130
|
+
throw new Error(`Unknown data type: ${t9}`);
|
|
75131
75131
|
}
|
|
75132
75132
|
};
|
|
75133
75133
|
var propertyKeyTypes = /* @__PURE__ */ new Set(["string", "number", "symbol"]);
|
|
@@ -75434,8 +75434,8 @@ function getLengthableOrigin(input) {
|
|
|
75434
75434
|
return "unknown";
|
|
75435
75435
|
}
|
|
75436
75436
|
function parsedType(data) {
|
|
75437
|
-
const
|
|
75438
|
-
switch (
|
|
75437
|
+
const t9 = typeof data;
|
|
75438
|
+
switch (t9) {
|
|
75439
75439
|
case "number": {
|
|
75440
75440
|
return Number.isNaN(data) ? "nan" : "number";
|
|
75441
75441
|
}
|
|
@@ -75452,7 +75452,7 @@ function parsedType(data) {
|
|
|
75452
75452
|
}
|
|
75453
75453
|
}
|
|
75454
75454
|
}
|
|
75455
|
-
return
|
|
75455
|
+
return t9;
|
|
75456
75456
|
}
|
|
75457
75457
|
function issue(...args2) {
|
|
75458
75458
|
const [iss, input, inst] = args2;
|
|
@@ -77084,12 +77084,12 @@ function handleCatchall(proms, input, payload, ctx, def, inst) {
|
|
|
77084
77084
|
const unrecognized = [];
|
|
77085
77085
|
const keySet = def.keySet;
|
|
77086
77086
|
const _catchall = def.catchall._zod;
|
|
77087
|
-
const
|
|
77087
|
+
const t9 = _catchall.def.type;
|
|
77088
77088
|
const isOptionalOut = _catchall.optout === "optional";
|
|
77089
77089
|
for (const key in input) {
|
|
77090
77090
|
if (keySet.has(key))
|
|
77091
77091
|
continue;
|
|
77092
|
-
if (
|
|
77092
|
+
if (t9 === "never") {
|
|
77093
77093
|
unrecognized.push(key);
|
|
77094
77094
|
continue;
|
|
77095
77095
|
}
|
|
@@ -92511,6 +92511,7 @@ __export(schema_exports, {
|
|
|
92511
92511
|
ticketComments: () => ticketComments,
|
|
92512
92512
|
ticketCommentsRelations: () => ticketCommentsRelations,
|
|
92513
92513
|
ticketEmbeddings: () => ticketEmbeddings,
|
|
92514
|
+
ticketFocusStateEnum: () => ticketFocusStateEnum,
|
|
92514
92515
|
ticketOriginEnum: () => ticketOriginEnum,
|
|
92515
92516
|
ticketPriorityEnum: () => ticketPriorityEnum,
|
|
92516
92517
|
ticketRelations: () => ticketRelations,
|
|
@@ -92676,6 +92677,10 @@ var ticketPriorityEnum = pgEnum("ticket_priority", [
|
|
|
92676
92677
|
"high",
|
|
92677
92678
|
"critical"
|
|
92678
92679
|
]);
|
|
92680
|
+
var ticketFocusStateEnum = pgEnum("ticket_focus_state", [
|
|
92681
|
+
"today",
|
|
92682
|
+
"week"
|
|
92683
|
+
]);
|
|
92679
92684
|
var ticketTypeEnum = pgEnum("ticket_type", [
|
|
92680
92685
|
"task",
|
|
92681
92686
|
"bug",
|
|
@@ -93087,6 +93092,16 @@ var tickets = pgTable(
|
|
|
93087
93092
|
type: ticketTypeEnum().default("task").notNull(),
|
|
93088
93093
|
// Manual sort order within status columns (for kanban board)
|
|
93089
93094
|
sequence: numeric({ mode: "number" }),
|
|
93095
|
+
// Cross-project personal work queue: manual rank within the current
|
|
93096
|
+
// assignee's queue (midpoint ordering, reset to null on reassignment).
|
|
93097
|
+
queueRank: doublePrecision("queue_rank"),
|
|
93098
|
+
// Teamlead "focus list" marker (today/week). null = not on a focus list.
|
|
93099
|
+
focusState: ticketFocusStateEnum("focus_state"),
|
|
93100
|
+
focusSetBy: uuid3("focus_set_by"),
|
|
93101
|
+
focusSetAt: timestamp("focus_set_at", {
|
|
93102
|
+
withTimezone: true,
|
|
93103
|
+
mode: "string"
|
|
93104
|
+
}),
|
|
93090
93105
|
// Relationships
|
|
93091
93106
|
teamId: uuid3("team_id").notNull(),
|
|
93092
93107
|
projectId: uuid3("project_id"),
|
|
@@ -93190,6 +93205,11 @@ var tickets = pgTable(
|
|
|
93190
93205
|
index("idx_tickets_priority").on(table.priority),
|
|
93191
93206
|
index("idx_tickets_created_at").using("btree", table.createdAt.desc()),
|
|
93192
93207
|
index("idx_tickets_due_date").on(table.teamId, table.dueDate),
|
|
93208
|
+
index("idx_tickets_assignee_queue_rank").on(
|
|
93209
|
+
table.assigneeId,
|
|
93210
|
+
table.queueRank
|
|
93211
|
+
),
|
|
93212
|
+
index("idx_tickets_assignee_focus").on(table.assigneeId, table.focusState),
|
|
93193
93213
|
index("idx_tickets_fts").using(
|
|
93194
93214
|
"gin",
|
|
93195
93215
|
table.fts.asc().nullsLast().op("tsvector_ops")
|
|
@@ -93237,6 +93257,11 @@ var tickets = pgTable(
|
|
|
93237
93257
|
foreignColumns: [users.id],
|
|
93238
93258
|
name: "tickets_updated_by_fkey"
|
|
93239
93259
|
}).onDelete("set null"),
|
|
93260
|
+
foreignKey({
|
|
93261
|
+
columns: [table.focusSetBy],
|
|
93262
|
+
foreignColumns: [users.id],
|
|
93263
|
+
name: "tickets_focus_set_by_fkey"
|
|
93264
|
+
}).onDelete("set null"),
|
|
93240
93265
|
foreignKey({
|
|
93241
93266
|
columns: [table.versionTagId],
|
|
93242
93267
|
foreignColumns: [versionTags.id],
|
|
@@ -105793,15 +105818,36 @@ var TOOLS = [
|
|
|
105793
105818
|
"review",
|
|
105794
105819
|
"resolved",
|
|
105795
105820
|
"closed",
|
|
105796
|
-
"backlog"
|
|
105821
|
+
"backlog",
|
|
105822
|
+
"blocked"
|
|
105797
105823
|
]
|
|
105798
105824
|
},
|
|
105825
|
+
statuses: {
|
|
105826
|
+
type: "array",
|
|
105827
|
+
items: {
|
|
105828
|
+
type: "string",
|
|
105829
|
+
enum: [
|
|
105830
|
+
"open",
|
|
105831
|
+
"in_progress",
|
|
105832
|
+
"review",
|
|
105833
|
+
"resolved",
|
|
105834
|
+
"closed",
|
|
105835
|
+
"backlog",
|
|
105836
|
+
"blocked"
|
|
105837
|
+
]
|
|
105838
|
+
},
|
|
105839
|
+
description: "Filter by multiple statuses (OR). Takes precedence over the single `status`."
|
|
105840
|
+
},
|
|
105799
105841
|
priority: {
|
|
105800
105842
|
type: "string",
|
|
105801
105843
|
enum: ["low", "medium", "high", "critical"]
|
|
105802
105844
|
},
|
|
105803
105845
|
projectId: { type: "string" },
|
|
105804
105846
|
customerId: { type: "string" },
|
|
105847
|
+
assigneeId: {
|
|
105848
|
+
type: "string",
|
|
105849
|
+
description: "Filter by assignee: a user UUID, or 'me' for the API key user."
|
|
105850
|
+
},
|
|
105805
105851
|
q: {
|
|
105806
105852
|
type: "string",
|
|
105807
105853
|
description: "Search query for ticket number, title, or description"
|
|
@@ -105825,6 +105871,167 @@ var TOOLS = [
|
|
|
105825
105871
|
required: []
|
|
105826
105872
|
}
|
|
105827
105873
|
},
|
|
105874
|
+
{
|
|
105875
|
+
name: "get-my-work-queue",
|
|
105876
|
+
description: "Get the API key user's personal cross-project work queue: every ticket assigned to them across all accessible projects, in 'what should I do now?' order. Each item has a derived workState (now = open/in_progress, waiting = review, later = backlog, blocked = blocked) plus ticketNumber, title, project, customer, status, priority, deadline (dueDate), queueRank, focusState and blockedReason. Ordered by focus list (today/week first), manual queueRank, priority, deadline, then last update. Use this to answer 'what's on my plate?'.",
|
|
105877
|
+
inputSchema: {
|
|
105878
|
+
type: "object",
|
|
105879
|
+
properties: {
|
|
105880
|
+
teamId: teamIdProp,
|
|
105881
|
+
projectId: { type: "string", description: "Filter to one project UUID." },
|
|
105882
|
+
priority: {
|
|
105883
|
+
type: "string",
|
|
105884
|
+
enum: ["low", "medium", "high", "critical"]
|
|
105885
|
+
},
|
|
105886
|
+
workStates: {
|
|
105887
|
+
type: "array",
|
|
105888
|
+
items: {
|
|
105889
|
+
type: "string",
|
|
105890
|
+
enum: ["now", "waiting", "later", "blocked", "done"]
|
|
105891
|
+
},
|
|
105892
|
+
description: "Filter by derived work state(s). Omit for all active work (excludes done)."
|
|
105893
|
+
},
|
|
105894
|
+
statuses: {
|
|
105895
|
+
type: "array",
|
|
105896
|
+
items: { type: "string" },
|
|
105897
|
+
description: "Explicit ticket status filter (wins over workStates)."
|
|
105898
|
+
},
|
|
105899
|
+
pageSize: { type: "number", default: 200, maximum: 500 }
|
|
105900
|
+
},
|
|
105901
|
+
required: []
|
|
105902
|
+
}
|
|
105903
|
+
},
|
|
105904
|
+
{
|
|
105905
|
+
name: "get-assignee-work-queue",
|
|
105906
|
+
description: "Get the cross-project work queue for a specific assignee, or for everyone. Teamlead-oriented: pass assigneeId as a user UUID, 'me' (default), or 'all' for the whole team. With assigneeId='all' and groupByAssignee=true the result is grouped per developer. Same item shape and ordering as get-my-work-queue. Use get-team-workload-overview first for high-level counts.",
|
|
105907
|
+
inputSchema: {
|
|
105908
|
+
type: "object",
|
|
105909
|
+
properties: {
|
|
105910
|
+
teamId: teamIdProp,
|
|
105911
|
+
assigneeId: {
|
|
105912
|
+
type: "string",
|
|
105913
|
+
description: "Whose queue: a user UUID, 'me' (default), or 'all' for every assignee."
|
|
105914
|
+
},
|
|
105915
|
+
groupByAssignee: {
|
|
105916
|
+
type: "boolean",
|
|
105917
|
+
description: "When assigneeId='all', group the items per assignee."
|
|
105918
|
+
},
|
|
105919
|
+
projectId: { type: "string" },
|
|
105920
|
+
priority: {
|
|
105921
|
+
type: "string",
|
|
105922
|
+
enum: ["low", "medium", "high", "critical"]
|
|
105923
|
+
},
|
|
105924
|
+
workStates: {
|
|
105925
|
+
type: "array",
|
|
105926
|
+
items: {
|
|
105927
|
+
type: "string",
|
|
105928
|
+
enum: ["now", "waiting", "later", "blocked", "done"]
|
|
105929
|
+
}
|
|
105930
|
+
},
|
|
105931
|
+
statuses: { type: "array", items: { type: "string" } },
|
|
105932
|
+
pageSize: { type: "number", default: 200, maximum: 500 }
|
|
105933
|
+
},
|
|
105934
|
+
required: []
|
|
105935
|
+
}
|
|
105936
|
+
},
|
|
105937
|
+
{
|
|
105938
|
+
name: "get-team-workload-overview",
|
|
105939
|
+
description: "Teamlead overview of open work per assignee across all accessible projects: for each developer (and optionally the unassigned bucket) the counts of total/now/waiting/later/blocked tickets, plus high-priority, stale (not updated within staleDays) and upcoming-deadline (within upcomingDays) counts. Use this to see who is overloaded or has stale/at-risk work, then drill in with get-assignee-work-queue.",
|
|
105940
|
+
inputSchema: {
|
|
105941
|
+
type: "object",
|
|
105942
|
+
properties: {
|
|
105943
|
+
teamId: teamIdProp,
|
|
105944
|
+
staleDays: {
|
|
105945
|
+
type: "number",
|
|
105946
|
+
default: 7,
|
|
105947
|
+
description: "Tickets not updated within this many days count as stale."
|
|
105948
|
+
},
|
|
105949
|
+
upcomingDays: {
|
|
105950
|
+
type: "number",
|
|
105951
|
+
default: 7,
|
|
105952
|
+
description: "Deadlines within this many days count as upcoming."
|
|
105953
|
+
},
|
|
105954
|
+
includeUnassigned: {
|
|
105955
|
+
type: "boolean",
|
|
105956
|
+
default: true,
|
|
105957
|
+
description: "Include the unassigned bucket in the overview."
|
|
105958
|
+
}
|
|
105959
|
+
},
|
|
105960
|
+
required: []
|
|
105961
|
+
}
|
|
105962
|
+
},
|
|
105963
|
+
{
|
|
105964
|
+
name: "set-assignee-queue-order",
|
|
105965
|
+
description: "Reorder a ticket within its assignee's personal cross-project work queue (manual prioritisation / drag-and-drop equivalent). Provide the ticketId and the target position (0 = top of the queue). Recomputes the ticket's queueRank via midpoint ordering. Permission: the API key user must be the ticket's assignee or an owner of the ticket's team. Alias: update-ticket-rank.",
|
|
105966
|
+
inputSchema: {
|
|
105967
|
+
type: "object",
|
|
105968
|
+
properties: {
|
|
105969
|
+
teamId: teamIdProp,
|
|
105970
|
+
ticketId: ticketIdentifierProp,
|
|
105971
|
+
position: {
|
|
105972
|
+
type: "number",
|
|
105973
|
+
description: "Target index in the assignee's ordered queue (0 = top)."
|
|
105974
|
+
}
|
|
105975
|
+
},
|
|
105976
|
+
required: ["ticketId", "position"]
|
|
105977
|
+
}
|
|
105978
|
+
},
|
|
105979
|
+
{
|
|
105980
|
+
name: "update-ticket-rank",
|
|
105981
|
+
description: "Alias of set-assignee-queue-order: reorder a ticket within its assignee's personal cross-project work queue by setting its target position (0 = top). Recomputes queueRank via midpoint ordering. Permission: assignee or team owner.",
|
|
105982
|
+
inputSchema: {
|
|
105983
|
+
type: "object",
|
|
105984
|
+
properties: {
|
|
105985
|
+
teamId: teamIdProp,
|
|
105986
|
+
ticketId: ticketIdentifierProp,
|
|
105987
|
+
position: {
|
|
105988
|
+
type: "number",
|
|
105989
|
+
description: "Target index in the assignee's ordered queue (0 = top)."
|
|
105990
|
+
}
|
|
105991
|
+
},
|
|
105992
|
+
required: ["ticketId", "position"]
|
|
105993
|
+
}
|
|
105994
|
+
},
|
|
105995
|
+
{
|
|
105996
|
+
name: "update-ticket-work-state",
|
|
105997
|
+
description: "Set a ticket's work state, which maps to its status: now -> in_progress, waiting -> review, later -> backlog, blocked -> blocked. When moving to blocked you may pass a blockedReason (stored on the ticket metadata). Permission: the API key user must be the ticket's assignee or an owner of the ticket's team.",
|
|
105998
|
+
inputSchema: {
|
|
105999
|
+
type: "object",
|
|
106000
|
+
properties: {
|
|
106001
|
+
teamId: teamIdProp,
|
|
106002
|
+
ticketId: ticketIdentifierProp,
|
|
106003
|
+
workState: {
|
|
106004
|
+
type: "string",
|
|
106005
|
+
enum: ["now", "waiting", "later", "blocked"]
|
|
106006
|
+
},
|
|
106007
|
+
blockedReason: {
|
|
106008
|
+
type: "string",
|
|
106009
|
+
description: "Reason stored when workState is 'blocked'."
|
|
106010
|
+
}
|
|
106011
|
+
},
|
|
106012
|
+
required: ["ticketId", "workState"]
|
|
106013
|
+
}
|
|
106014
|
+
},
|
|
106015
|
+
{
|
|
106016
|
+
name: "mark-ticket-blocked",
|
|
106017
|
+
description: "Mark a ticket as blocked / waiting on input (sets status=blocked and stores the reason on the ticket metadata), or clear it with unblock=true (sets status=in_progress). Permission: the API key user must be the ticket's assignee or an owner of the ticket's team.",
|
|
106018
|
+
inputSchema: {
|
|
106019
|
+
type: "object",
|
|
106020
|
+
properties: {
|
|
106021
|
+
teamId: teamIdProp,
|
|
106022
|
+
ticketId: ticketIdentifierProp,
|
|
106023
|
+
reason: {
|
|
106024
|
+
type: "string",
|
|
106025
|
+
description: "Why the ticket is blocked / what it is waiting on."
|
|
106026
|
+
},
|
|
106027
|
+
unblock: {
|
|
106028
|
+
type: "boolean",
|
|
106029
|
+
description: "When true, clears the blocked state back to in_progress."
|
|
106030
|
+
}
|
|
106031
|
+
},
|
|
106032
|
+
required: ["ticketId"]
|
|
106033
|
+
}
|
|
106034
|
+
},
|
|
105828
106035
|
{
|
|
105829
106036
|
name: "get-ticket-by-id",
|
|
105830
106037
|
description: "Get a specific ticket by its ID or ticket number, including tags, comment text and a full attachment listing (with ids). Images from ticket and comment attachments are downloaded and returned inline as base64. For non-image attachments, call get-ticket-attachment with the listed id to get a download URL.",
|
|
@@ -107921,7 +108128,7 @@ var RESOURCES = [
|
|
|
107921
108128
|
|
|
107922
108129
|
// src/tools/team-resolution.ts
|
|
107923
108130
|
function teamSelectionResponse(teams2) {
|
|
107924
|
-
const list = teams2.map((
|
|
108131
|
+
const list = teams2.map((t9) => `- ${t9.name ?? "(unnamed provider)"} (teamId: ${t9.id})`).join("\n");
|
|
107925
108132
|
return {
|
|
107926
108133
|
content: [
|
|
107927
108134
|
{
|
|
@@ -108002,7 +108209,7 @@ function notFoundResponse(identifier) {
|
|
|
108002
108209
|
};
|
|
108003
108210
|
}
|
|
108004
108211
|
function multipleMatchesResponse(identifier, matches) {
|
|
108005
|
-
const list = matches.map((
|
|
108212
|
+
const list = matches.map((t9) => `- **${t9.ticketNumber}** (ID: ${t9.id}): ${t9.title}`).join("\n");
|
|
108006
108213
|
return {
|
|
108007
108214
|
content: [
|
|
108008
108215
|
{
|
|
@@ -110277,7 +110484,7 @@ function blockTypeSummary(blocks) {
|
|
|
110277
110484
|
for (const block of blocks) {
|
|
110278
110485
|
counts.set(block.type, (counts.get(block.type) ?? 0) + 1);
|
|
110279
110486
|
}
|
|
110280
|
-
return [...counts.entries()].map(([
|
|
110487
|
+
return [...counts.entries()].map(([t9, n3]) => `${t9}\xD7${n3}`).join(", ");
|
|
110281
110488
|
}
|
|
110282
110489
|
async function findAccessibleDocument(id, teamIds) {
|
|
110283
110490
|
if (teamIds.length === 0) return null;
|
|
@@ -115845,17 +116052,17 @@ function computeInvoiceTotals(items, defaults, discount = 0) {
|
|
|
115845
116052
|
};
|
|
115846
116053
|
}
|
|
115847
116054
|
function templateDefaultsFromInvoice(template, currency) {
|
|
115848
|
-
const
|
|
116055
|
+
const t9 = template ?? {};
|
|
115849
116056
|
return {
|
|
115850
|
-
currency:
|
|
115851
|
-
vatRate:
|
|
115852
|
-
taxRate:
|
|
115853
|
-
includeVat:
|
|
115854
|
-
includeTax:
|
|
115855
|
-
includeDiscount:
|
|
115856
|
-
includeDecimals:
|
|
115857
|
-
includeUnits:
|
|
115858
|
-
raw:
|
|
116057
|
+
currency: t9.currency || currency || "EUR",
|
|
116058
|
+
vatRate: t9.vatRate ?? 21,
|
|
116059
|
+
taxRate: t9.taxRate ?? 0,
|
|
116060
|
+
includeVat: t9.includeVat ?? true,
|
|
116061
|
+
includeTax: t9.includeTax ?? false,
|
|
116062
|
+
includeDiscount: t9.includeDiscount ?? false,
|
|
116063
|
+
includeDecimals: t9.includeDecimals ?? true,
|
|
116064
|
+
includeUnits: t9.includeUnits ?? true,
|
|
116065
|
+
raw: t9
|
|
115859
116066
|
};
|
|
115860
116067
|
}
|
|
115861
116068
|
function plainTextFromLineItemName(name21) {
|
|
@@ -124108,7 +124315,7 @@ function quoteBlockId() {
|
|
|
124108
124315
|
function paragraphsDoc(...texts) {
|
|
124109
124316
|
return {
|
|
124110
124317
|
type: "doc",
|
|
124111
|
-
content: texts.filter((
|
|
124318
|
+
content: texts.filter((t9) => t9.trim().length > 0).map((text3) => ({
|
|
124112
124319
|
type: "paragraph",
|
|
124113
124320
|
content: [{ type: "text", text: text3 }]
|
|
124114
124321
|
}))
|
|
@@ -124223,21 +124430,21 @@ function applyLineItemsToBlocks(blocks, items, defaults, opts) {
|
|
|
124223
124430
|
return next;
|
|
124224
124431
|
}
|
|
124225
124432
|
function templateDefaultsFromStored(template, currency) {
|
|
124226
|
-
const
|
|
124433
|
+
const t9 = template ?? {};
|
|
124227
124434
|
return {
|
|
124228
|
-
currency:
|
|
124229
|
-
vatRate:
|
|
124230
|
-
taxRate:
|
|
124231
|
-
includeVat:
|
|
124232
|
-
includeTax:
|
|
124233
|
-
includeDiscount:
|
|
124234
|
-
includeDecimals:
|
|
124235
|
-
includeUnits:
|
|
124236
|
-
includeQr:
|
|
124237
|
-
size:
|
|
124435
|
+
currency: t9.currency || currency || "EUR",
|
|
124436
|
+
vatRate: t9.vatRate ?? 21,
|
|
124437
|
+
taxRate: t9.taxRate ?? 0,
|
|
124438
|
+
includeVat: t9.includeVat ?? true,
|
|
124439
|
+
includeTax: t9.includeTax ?? false,
|
|
124440
|
+
includeDiscount: t9.includeDiscount ?? false,
|
|
124441
|
+
includeDecimals: t9.includeDecimals ?? true,
|
|
124442
|
+
includeUnits: t9.includeUnits ?? true,
|
|
124443
|
+
includeQr: t9.includeQr ?? false,
|
|
124444
|
+
size: t9.size || "a4",
|
|
124238
124445
|
fromDetails: null,
|
|
124239
124446
|
paymentDetails: null,
|
|
124240
|
-
raw:
|
|
124447
|
+
raw: t9
|
|
124241
124448
|
};
|
|
124242
124449
|
}
|
|
124243
124450
|
|
|
@@ -124259,25 +124466,25 @@ function textResponse9(text3) {
|
|
|
124259
124466
|
}
|
|
124260
124467
|
async function loadTemplateDefaults(teamId) {
|
|
124261
124468
|
const rows = await db.select().from(schema_exports.quotationTemplates).where(eq(schema_exports.quotationTemplates.teamId, teamId)).orderBy(desc(schema_exports.quotationTemplates.isDefault)).limit(1);
|
|
124262
|
-
const
|
|
124469
|
+
const t9 = rows[0];
|
|
124263
124470
|
return {
|
|
124264
|
-
currency:
|
|
124265
|
-
vatRate:
|
|
124266
|
-
taxRate:
|
|
124267
|
-
includeVat:
|
|
124268
|
-
includeTax:
|
|
124269
|
-
includeDiscount:
|
|
124270
|
-
includeDecimals:
|
|
124271
|
-
includeUnits:
|
|
124272
|
-
includeQr:
|
|
124273
|
-
size:
|
|
124274
|
-
fromDetails:
|
|
124275
|
-
paymentDetails:
|
|
124276
|
-
raw:
|
|
124471
|
+
currency: t9?.currency || "EUR",
|
|
124472
|
+
vatRate: t9?.vatRate ?? 21,
|
|
124473
|
+
taxRate: t9?.taxRate ?? 0,
|
|
124474
|
+
includeVat: t9?.includeVat ?? true,
|
|
124475
|
+
includeTax: t9?.includeTax ?? false,
|
|
124476
|
+
includeDiscount: t9?.includeDiscount ?? false,
|
|
124477
|
+
includeDecimals: t9?.includeDecimals ?? true,
|
|
124478
|
+
includeUnits: t9?.includeUnits ?? true,
|
|
124479
|
+
includeQr: t9?.includeQr ?? false,
|
|
124480
|
+
size: t9?.size || "a4",
|
|
124481
|
+
fromDetails: t9?.fromDetails ?? null,
|
|
124482
|
+
paymentDetails: t9?.paymentDetails ?? null,
|
|
124483
|
+
raw: t9 ?? {}
|
|
124277
124484
|
};
|
|
124278
124485
|
}
|
|
124279
124486
|
function buildQuoteTemplate(defaults, titleOverride) {
|
|
124280
|
-
const
|
|
124487
|
+
const t9 = defaults.raw;
|
|
124281
124488
|
return {
|
|
124282
124489
|
currency: defaults.currency,
|
|
124283
124490
|
includeVat: defaults.includeVat,
|
|
@@ -124289,27 +124496,27 @@ function buildQuoteTemplate(defaults, titleOverride) {
|
|
|
124289
124496
|
vatRate: defaults.vatRate,
|
|
124290
124497
|
taxRate: defaults.taxRate,
|
|
124291
124498
|
size: defaults.size,
|
|
124292
|
-
locale:
|
|
124499
|
+
locale: t9.locale || "nl",
|
|
124293
124500
|
timezone: "Europe/Amsterdam",
|
|
124294
|
-
customerLabel:
|
|
124295
|
-
title: titleOverride ||
|
|
124296
|
-
fromLabel:
|
|
124297
|
-
quotationNoLabel:
|
|
124298
|
-
issueDateLabel:
|
|
124299
|
-
validUntilLabel:
|
|
124300
|
-
descriptionLabel:
|
|
124301
|
-
priceLabel:
|
|
124302
|
-
quantityLabel:
|
|
124303
|
-
totalLabel:
|
|
124304
|
-
totalSummaryLabel:
|
|
124305
|
-
vatLabel:
|
|
124306
|
-
subtotalLabel:
|
|
124307
|
-
taxLabel:
|
|
124308
|
-
discountLabel:
|
|
124309
|
-
paymentLabel:
|
|
124310
|
-
noteLabel:
|
|
124311
|
-
logoUrl:
|
|
124312
|
-
dateFormat:
|
|
124501
|
+
customerLabel: t9.customerLabel || "Klant",
|
|
124502
|
+
title: titleOverride || t9.title || "Offerte",
|
|
124503
|
+
fromLabel: t9.fromLabel || "Van",
|
|
124504
|
+
quotationNoLabel: t9.quotationNoLabel || "Offerte nr.",
|
|
124505
|
+
issueDateLabel: t9.issueDateLabel || "Datum",
|
|
124506
|
+
validUntilLabel: t9.validUntilLabel || "Geldig tot",
|
|
124507
|
+
descriptionLabel: t9.descriptionLabel || "Omschrijving",
|
|
124508
|
+
priceLabel: t9.priceLabel || "Prijs",
|
|
124509
|
+
quantityLabel: t9.quantityLabel || "Aantal",
|
|
124510
|
+
totalLabel: t9.totalLabel || "Totaal",
|
|
124511
|
+
totalSummaryLabel: t9.totalSummaryLabel || "Totaal",
|
|
124512
|
+
vatLabel: t9.vatLabel || "BTW",
|
|
124513
|
+
subtotalLabel: t9.subtotalLabel || "Subtotaal",
|
|
124514
|
+
taxLabel: t9.taxLabel || "Belasting",
|
|
124515
|
+
discountLabel: t9.discountLabel || "Korting",
|
|
124516
|
+
paymentLabel: t9.paymentLabel || "Betaling",
|
|
124517
|
+
noteLabel: t9.noteLabel || "Notitie",
|
|
124518
|
+
logoUrl: t9.logoUrl ?? null,
|
|
124519
|
+
dateFormat: t9.dateFormat || "dd/MM/yyyy"
|
|
124313
124520
|
};
|
|
124314
124521
|
}
|
|
124315
124522
|
async function nextQuotationNumber(teamId) {
|
|
@@ -124732,7 +124939,7 @@ async function handleGetTeams() {
|
|
|
124732
124939
|
]
|
|
124733
124940
|
};
|
|
124734
124941
|
}
|
|
124735
|
-
const list = teams2.map((
|
|
124942
|
+
const list = teams2.map((t9) => `- ${t9.name ?? "(unnamed provider)"} (teamId: ${t9.id})`).join("\n");
|
|
124736
124943
|
return {
|
|
124737
124944
|
content: [
|
|
124738
124945
|
{
|
|
@@ -125354,7 +125561,7 @@ function normalizeTagName(name21) {
|
|
|
125354
125561
|
}
|
|
125355
125562
|
function formatTagList(tags2) {
|
|
125356
125563
|
if (tags2.length === 0) return "";
|
|
125357
|
-
return tags2.map((
|
|
125564
|
+
return tags2.map((t9) => t9.name).join(", ");
|
|
125358
125565
|
}
|
|
125359
125566
|
async function getTagsForTickets(ticketIds) {
|
|
125360
125567
|
const result = /* @__PURE__ */ new Map();
|
|
@@ -125790,7 +125997,7 @@ async function resolveMergeTarget(teamId, input) {
|
|
|
125790
125997
|
)
|
|
125791
125998
|
);
|
|
125792
125999
|
if (matches.length > 0) {
|
|
125793
|
-
const general = matches.find((
|
|
126000
|
+
const general = matches.find((t9) => t9.projectId === null);
|
|
125794
126001
|
return { ok: true, tag: general ?? matches[0], created: false };
|
|
125795
126002
|
}
|
|
125796
126003
|
const [created] = await db.insert(schema_exports.tags).values({ teamId, name: input.targetName.trim(), projectId: null }).returning(TAG_COLUMNS);
|
|
@@ -125813,7 +126020,7 @@ async function handleMergeTags(input) {
|
|
|
125813
126020
|
inArray(schema_exports.tags.teamId, accessibleTeamIds)
|
|
125814
126021
|
)
|
|
125815
126022
|
);
|
|
125816
|
-
const foundIds = new Set(sourceTags.map((
|
|
126023
|
+
const foundIds = new Set(sourceTags.map((t9) => t9.id));
|
|
125817
126024
|
const missing = rawSourceIds.filter((id) => !foundIds.has(id));
|
|
125818
126025
|
if (missing.length > 0) {
|
|
125819
126026
|
return textResponse11(
|
|
@@ -125822,13 +126029,13 @@ async function handleMergeTags(input) {
|
|
|
125822
126029
|
}
|
|
125823
126030
|
const target = await resolveMergeTarget(resolved.teamId, input);
|
|
125824
126031
|
if (!target.ok) return target.response;
|
|
125825
|
-
const sourcesToMerge = sourceTags.filter((
|
|
126032
|
+
const sourcesToMerge = sourceTags.filter((t9) => t9.id !== target.tag.id);
|
|
125826
126033
|
if (sourcesToMerge.length === 0) {
|
|
125827
126034
|
return textResponse11(
|
|
125828
126035
|
"Error: nothing to merge \u2014 the only source tag is the same as the target tag."
|
|
125829
126036
|
);
|
|
125830
126037
|
}
|
|
125831
|
-
const sourceIds = sourcesToMerge.map((
|
|
126038
|
+
const sourceIds = sourcesToMerge.map((t9) => t9.id);
|
|
125832
126039
|
const targetId = target.tag.id;
|
|
125833
126040
|
const deleteSources = input.deleteSources ?? true;
|
|
125834
126041
|
const results = await db.transaction(async (tx) => {
|
|
@@ -125924,7 +126131,7 @@ async function handleMergeTags(input) {
|
|
|
125924
126131
|
return textResponse11(
|
|
125925
126132
|
`\u2705 **Tags merged** into ${describeTag(target.tag)}${target.created ? " (newly created)" : ""}
|
|
125926
126133
|
|
|
125927
|
-
Sources (${sourcesToMerge.length}): ${sourcesToMerge.map((
|
|
126134
|
+
Sources (${sourcesToMerge.length}): ${sourcesToMerge.map((t9) => `${t9.name} (${t9.id})`).join(", ")}
|
|
125928
126135
|
|
|
125929
126136
|
Relations moved (duplicates skipped to keep a single tag per entity):
|
|
125930
126137
|
${line2("Tickets", results.tickets)}
|
|
@@ -125933,7 +126140,7 @@ ${line2("Projects", results.projects)}
|
|
|
125933
126140
|
${line2("Transactions", results.transactions)}
|
|
125934
126141
|
|
|
125935
126142
|
Totals: ${movedTotal} relation(s) moved, ${skippedTotal} duplicate(s) skipped.
|
|
125936
|
-
Source tags ${deleteSources ? "deleted" : "kept (now empty)"}: ${sourcesToMerge.map((
|
|
126143
|
+
Source tags ${deleteSources ? "deleted" : "kept (now empty)"}: ${sourcesToMerge.map((t9) => t9.id).join(", ")}.`
|
|
125937
126144
|
);
|
|
125938
126145
|
}
|
|
125939
126146
|
function planToResult(plan) {
|
|
@@ -126214,7 +126421,7 @@ async function handleUpdateTicket(input) {
|
|
|
126214
126421
|
const { added, removed } = await syncTicketTags(
|
|
126215
126422
|
ticket.id,
|
|
126216
126423
|
ticket.teamId,
|
|
126217
|
-
resolvedTags.tags.map((
|
|
126424
|
+
resolvedTags.tags.map((t9) => t9.id),
|
|
126218
126425
|
tagMode
|
|
126219
126426
|
);
|
|
126220
126427
|
if (added.length > 0) {
|
|
@@ -126321,37 +126528,37 @@ function toNumber3(value) {
|
|
|
126321
126528
|
const parsed = Number.parseFloat(String(value));
|
|
126322
126529
|
return Number.isFinite(parsed) ? parsed : 0;
|
|
126323
126530
|
}
|
|
126324
|
-
function formatTrip(
|
|
126531
|
+
function formatTrip(t9) {
|
|
126325
126532
|
return {
|
|
126326
|
-
id:
|
|
126327
|
-
date:
|
|
126328
|
-
startLocation:
|
|
126329
|
-
endLocation:
|
|
126330
|
-
tripType:
|
|
126331
|
-
distance:
|
|
126332
|
-
odometerStart:
|
|
126333
|
-
odometerEnd:
|
|
126334
|
-
billingType:
|
|
126335
|
-
rate:
|
|
126336
|
-
amount:
|
|
126337
|
-
isInvoiced:
|
|
126338
|
-
invoiceId:
|
|
126339
|
-
notes:
|
|
126340
|
-
user:
|
|
126341
|
-
project:
|
|
126342
|
-
customer:
|
|
126343
|
-
invoice:
|
|
126344
|
-
id:
|
|
126345
|
-
invoiceNumber:
|
|
126346
|
-
status:
|
|
126533
|
+
id: t9.id,
|
|
126534
|
+
date: t9.date,
|
|
126535
|
+
startLocation: t9.startLocation,
|
|
126536
|
+
endLocation: t9.endLocation,
|
|
126537
|
+
tripType: t9.tripType,
|
|
126538
|
+
distance: t9.distance != null ? toNumber3(t9.distance) : null,
|
|
126539
|
+
odometerStart: t9.odometerStart != null ? toNumber3(t9.odometerStart) : null,
|
|
126540
|
+
odometerEnd: t9.odometerEnd != null ? toNumber3(t9.odometerEnd) : null,
|
|
126541
|
+
billingType: t9.billingType,
|
|
126542
|
+
rate: t9.rate,
|
|
126543
|
+
amount: t9.amount,
|
|
126544
|
+
isInvoiced: t9.isInvoiced,
|
|
126545
|
+
invoiceId: t9.invoiceId,
|
|
126546
|
+
notes: t9.notes,
|
|
126547
|
+
user: t9.user ? { id: t9.user.id, name: t9.user.fullName } : null,
|
|
126548
|
+
project: t9.project ? { id: t9.project.id, name: t9.project.name } : null,
|
|
126549
|
+
customer: t9.customer ? { id: t9.customer.id, name: t9.customer.name } : null,
|
|
126550
|
+
invoice: t9.invoice ? {
|
|
126551
|
+
id: t9.invoice.id,
|
|
126552
|
+
invoiceNumber: t9.invoice.invoiceNumber,
|
|
126553
|
+
status: t9.invoice.status
|
|
126347
126554
|
} : null,
|
|
126348
|
-
vehicle:
|
|
126349
|
-
id:
|
|
126350
|
-
name:
|
|
126351
|
-
licensePlate:
|
|
126555
|
+
vehicle: t9.vehicle ? {
|
|
126556
|
+
id: t9.vehicle.id,
|
|
126557
|
+
name: t9.vehicle.name,
|
|
126558
|
+
licensePlate: t9.vehicle.licensePlate
|
|
126352
126559
|
} : null,
|
|
126353
|
-
snapshotId:
|
|
126354
|
-
linkedTripId:
|
|
126560
|
+
snapshotId: t9.snapshotId,
|
|
126561
|
+
linkedTripId: t9.linkedTripId
|
|
126355
126562
|
};
|
|
126356
126563
|
}
|
|
126357
126564
|
var TRIP_RELATIONS = {
|
|
@@ -126406,10 +126613,10 @@ async function handleGetTrips(input) {
|
|
|
126406
126613
|
limit: pageSize
|
|
126407
126614
|
});
|
|
126408
126615
|
const totals = rows.reduce(
|
|
126409
|
-
(acc,
|
|
126410
|
-
const distance = toNumber3(
|
|
126411
|
-
const amount =
|
|
126412
|
-
if (
|
|
126616
|
+
(acc, t9) => {
|
|
126617
|
+
const distance = toNumber3(t9.distance);
|
|
126618
|
+
const amount = t9.amount ?? 0;
|
|
126619
|
+
if (t9.tripType === "business") acc.businessKm += distance;
|
|
126413
126620
|
else acc.privateKm += distance;
|
|
126414
126621
|
acc.totalKm += distance;
|
|
126415
126622
|
acc.totalAmount += amount;
|
|
@@ -126731,10 +126938,10 @@ async function handleGetTripTemplates(input) {
|
|
|
126731
126938
|
}).from(schema_exports.tripTemplates).where(and(...filters)).orderBy(asc(schema_exports.tripTemplates.name)).limit(Math.min(input.pageSize ?? 50, 200));
|
|
126732
126939
|
return jsonResponse2({
|
|
126733
126940
|
count: rows.length,
|
|
126734
|
-
templates: rows.map((
|
|
126735
|
-
...
|
|
126736
|
-
distance:
|
|
126737
|
-
returnDistance:
|
|
126941
|
+
templates: rows.map((t9) => ({
|
|
126942
|
+
...t9,
|
|
126943
|
+
distance: t9.distance != null ? toNumber3(t9.distance) : null,
|
|
126944
|
+
returnDistance: t9.returnDistance != null ? toNumber3(t9.returnDistance) : null
|
|
126738
126945
|
}))
|
|
126739
126946
|
});
|
|
126740
126947
|
}
|
|
@@ -126827,9 +127034,11 @@ async function handleGetTickets(input) {
|
|
|
126827
127034
|
const ctx = getAuthContext();
|
|
126828
127035
|
const {
|
|
126829
127036
|
status,
|
|
127037
|
+
statuses,
|
|
126830
127038
|
priority,
|
|
126831
127039
|
projectId,
|
|
126832
127040
|
customerId,
|
|
127041
|
+
assigneeId,
|
|
126833
127042
|
q: q3,
|
|
126834
127043
|
tag: tag2,
|
|
126835
127044
|
tags: tags2,
|
|
@@ -126848,10 +127057,18 @@ async function handleGetTickets(input) {
|
|
|
126848
127057
|
customerIds
|
|
126849
127058
|
);
|
|
126850
127059
|
const filters = [accessPredicate, eq(schema_exports.tickets.isDeleted, false)];
|
|
126851
|
-
if (
|
|
127060
|
+
if (statuses && statuses.length > 0) {
|
|
127061
|
+
filters.push(inArray(schema_exports.tickets.status, statuses));
|
|
127062
|
+
} else if (status) {
|
|
127063
|
+
filters.push(eq(schema_exports.tickets.status, status));
|
|
127064
|
+
}
|
|
126852
127065
|
if (priority) filters.push(eq(schema_exports.tickets.priority, priority));
|
|
126853
127066
|
if (projectId) filters.push(eq(schema_exports.tickets.projectId, projectId));
|
|
126854
127067
|
if (customerId) filters.push(eq(schema_exports.tickets.customerId, customerId));
|
|
127068
|
+
if (assigneeId) {
|
|
127069
|
+
const resolvedAssignee = assigneeId === "me" ? ctx.userId : assigneeId;
|
|
127070
|
+
filters.push(eq(schema_exports.tickets.assigneeId, resolvedAssignee));
|
|
127071
|
+
}
|
|
126855
127072
|
if (q3) {
|
|
126856
127073
|
const pattern = `%${q3}%`;
|
|
126857
127074
|
filters.push(
|
|
@@ -126894,30 +127111,35 @@ async function handleGetTickets(input) {
|
|
|
126894
127111
|
priority: schema_exports.tickets.priority,
|
|
126895
127112
|
type: schema_exports.tickets.type,
|
|
126896
127113
|
createdAt: schema_exports.tickets.createdAt,
|
|
127114
|
+
dueDate: schema_exports.tickets.dueDate,
|
|
126897
127115
|
projectId: schema_exports.tickets.projectId,
|
|
126898
127116
|
customerId: schema_exports.tickets.customerId,
|
|
126899
127117
|
projectName: schema_exports.projects.name,
|
|
126900
|
-
customerName: schema_exports.customers.name
|
|
127118
|
+
customerName: schema_exports.customers.name,
|
|
127119
|
+
assigneeId: schema_exports.tickets.assigneeId,
|
|
127120
|
+
assigneeName: schema_exports.users.fullName
|
|
126901
127121
|
}).from(schema_exports.tickets).leftJoin(schema_exports.projects, eq(schema_exports.projects.id, schema_exports.tickets.projectId)).leftJoin(
|
|
126902
127122
|
schema_exports.customers,
|
|
126903
127123
|
eq(schema_exports.customers.id, schema_exports.tickets.customerId)
|
|
126904
|
-
).where(and(...filters)).orderBy(desc(schema_exports.tickets.createdAt)).limit(Math.min(pageSize, 100));
|
|
126905
|
-
const tagsByTicket = await getTagsForTickets(rows.map((
|
|
127124
|
+
).leftJoin(schema_exports.users, eq(schema_exports.users.id, schema_exports.tickets.assigneeId)).where(and(...filters)).orderBy(desc(schema_exports.tickets.createdAt)).limit(Math.min(pageSize, 100));
|
|
127125
|
+
const tagsByTicket = await getTagsForTickets(rows.map((t9) => t9.id));
|
|
126906
127126
|
return {
|
|
126907
127127
|
content: [
|
|
126908
127128
|
{
|
|
126909
127129
|
type: "text",
|
|
126910
127130
|
text: `Found ${rows.length} tickets:
|
|
126911
127131
|
|
|
126912
|
-
${rows.map((
|
|
126913
|
-
const ticketTags2 = tagsByTicket.get(
|
|
126914
|
-
return `**${
|
|
126915
|
-
ID: ${
|
|
126916
|
-
Status: ${
|
|
127132
|
+
${rows.map((t9) => {
|
|
127133
|
+
const ticketTags2 = tagsByTicket.get(t9.id) ?? [];
|
|
127134
|
+
return `**${t9.ticketNumber}**: ${t9.title}
|
|
127135
|
+
ID: ${t9.id}
|
|
127136
|
+
Status: ${t9.status} | Priority: ${t9.priority}
|
|
126917
127137
|
${ticketTags2.length > 0 ? `Tags: ${formatTagList(ticketTags2)}
|
|
126918
|
-
` : ""}${
|
|
126919
|
-
` : ""}${
|
|
126920
|
-
` : ""}
|
|
127138
|
+
` : ""}${t9.projectName ? `Project: ${t9.projectName}
|
|
127139
|
+
` : ""}${t9.customerName ? `Customer: ${t9.customerName}
|
|
127140
|
+
` : ""}${t9.assigneeName ? `Assignee: ${t9.assigneeName} [id: ${t9.assigneeId}]
|
|
127141
|
+
` : ""}${t9.dueDate ? `Deadline: ${new Date(t9.dueDate).toLocaleDateString()}
|
|
127142
|
+
` : ""}Created: ${new Date(t9.createdAt).toLocaleDateString()}
|
|
126921
127143
|
`;
|
|
126922
127144
|
}).join("\n") || "No tickets found."}`
|
|
126923
127145
|
}
|
|
@@ -127193,7 +127415,7 @@ async function handleCreateTicket(input) {
|
|
|
127193
127415
|
await syncTicketTags(
|
|
127194
127416
|
created.id,
|
|
127195
127417
|
resolvedTeamId,
|
|
127196
|
-
resolvedTags.tags.map((
|
|
127418
|
+
resolvedTags.tags.map((t9) => t9.id),
|
|
127197
127419
|
"replace"
|
|
127198
127420
|
);
|
|
127199
127421
|
appliedTags = resolvedTags.tags;
|
|
@@ -127222,6 +127444,430 @@ ${tagErrors.map((e6) => ` \u2022 ${e6}`).join("\n")}
|
|
|
127222
127444
|
};
|
|
127223
127445
|
}
|
|
127224
127446
|
|
|
127447
|
+
// src/tools/work-queue.ts
|
|
127448
|
+
var t8 = schema_exports.tickets;
|
|
127449
|
+
var ACTIVE_STATUSES = [
|
|
127450
|
+
"open",
|
|
127451
|
+
"in_progress",
|
|
127452
|
+
"review",
|
|
127453
|
+
"blocked",
|
|
127454
|
+
"backlog"
|
|
127455
|
+
];
|
|
127456
|
+
var RANK_BASE = 1e3;
|
|
127457
|
+
var RANK_MIN = 100;
|
|
127458
|
+
var RANK_APPEND_SPACING = 100;
|
|
127459
|
+
var workStateExpr = sql`
|
|
127460
|
+
CASE
|
|
127461
|
+
WHEN ${t8.status} IN ('open', 'in_progress') THEN 'now'
|
|
127462
|
+
WHEN ${t8.status} = 'review' THEN 'waiting'
|
|
127463
|
+
WHEN ${t8.status} = 'backlog' THEN 'later'
|
|
127464
|
+
WHEN ${t8.status} = 'blocked' THEN 'blocked'
|
|
127465
|
+
ELSE 'done'
|
|
127466
|
+
END
|
|
127467
|
+
`;
|
|
127468
|
+
function textResponse13(text3) {
|
|
127469
|
+
return { content: [{ type: "text", text: text3 }] };
|
|
127470
|
+
}
|
|
127471
|
+
function jsonResponse3(payload) {
|
|
127472
|
+
return {
|
|
127473
|
+
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }]
|
|
127474
|
+
};
|
|
127475
|
+
}
|
|
127476
|
+
function workStateToStatus(workState) {
|
|
127477
|
+
switch (workState) {
|
|
127478
|
+
case "now":
|
|
127479
|
+
return "in_progress";
|
|
127480
|
+
case "waiting":
|
|
127481
|
+
return "review";
|
|
127482
|
+
case "later":
|
|
127483
|
+
return "backlog";
|
|
127484
|
+
case "blocked":
|
|
127485
|
+
return "blocked";
|
|
127486
|
+
case "done":
|
|
127487
|
+
return "resolved";
|
|
127488
|
+
default:
|
|
127489
|
+
return null;
|
|
127490
|
+
}
|
|
127491
|
+
}
|
|
127492
|
+
function workStatesToStatuses(workStates) {
|
|
127493
|
+
const set3 = /* @__PURE__ */ new Set();
|
|
127494
|
+
for (const ws of workStates) {
|
|
127495
|
+
switch (ws) {
|
|
127496
|
+
case "now":
|
|
127497
|
+
set3.add("open");
|
|
127498
|
+
set3.add("in_progress");
|
|
127499
|
+
break;
|
|
127500
|
+
case "waiting":
|
|
127501
|
+
set3.add("review");
|
|
127502
|
+
break;
|
|
127503
|
+
case "later":
|
|
127504
|
+
set3.add("backlog");
|
|
127505
|
+
break;
|
|
127506
|
+
case "blocked":
|
|
127507
|
+
set3.add("blocked");
|
|
127508
|
+
break;
|
|
127509
|
+
case "done":
|
|
127510
|
+
set3.add("resolved");
|
|
127511
|
+
set3.add("closed");
|
|
127512
|
+
break;
|
|
127513
|
+
}
|
|
127514
|
+
}
|
|
127515
|
+
return [...set3];
|
|
127516
|
+
}
|
|
127517
|
+
async function loadWorkQueue(scope, assignee, filters) {
|
|
127518
|
+
const conditions = [
|
|
127519
|
+
buildTicketAccessPredicate(
|
|
127520
|
+
scope.teamIds,
|
|
127521
|
+
scope.projectIds,
|
|
127522
|
+
scope.customerIds
|
|
127523
|
+
),
|
|
127524
|
+
eq(t8.isDeleted, false)
|
|
127525
|
+
];
|
|
127526
|
+
if (assignee.mode === "one") {
|
|
127527
|
+
conditions.push(eq(t8.assigneeId, assignee.userId));
|
|
127528
|
+
} else {
|
|
127529
|
+
conditions.push(sql`${t8.assigneeId} IS NOT NULL`);
|
|
127530
|
+
}
|
|
127531
|
+
let statuses;
|
|
127532
|
+
if (filters.statuses && filters.statuses.length > 0) {
|
|
127533
|
+
statuses = filters.statuses;
|
|
127534
|
+
} else if (filters.workStates && filters.workStates.length > 0) {
|
|
127535
|
+
statuses = workStatesToStatuses(filters.workStates);
|
|
127536
|
+
} else {
|
|
127537
|
+
statuses = [...ACTIVE_STATUSES];
|
|
127538
|
+
}
|
|
127539
|
+
if (statuses.length > 0) {
|
|
127540
|
+
conditions.push(inArray(t8.status, statuses));
|
|
127541
|
+
}
|
|
127542
|
+
if (filters.priority) {
|
|
127543
|
+
conditions.push(eq(t8.priority, filters.priority));
|
|
127544
|
+
}
|
|
127545
|
+
if (filters.projectId) {
|
|
127546
|
+
conditions.push(eq(t8.projectId, filters.projectId));
|
|
127547
|
+
}
|
|
127548
|
+
const rows = await db.select({
|
|
127549
|
+
id: t8.id,
|
|
127550
|
+
ticketNumber: t8.ticketNumber,
|
|
127551
|
+
title: t8.title,
|
|
127552
|
+
status: t8.status,
|
|
127553
|
+
priority: t8.priority,
|
|
127554
|
+
type: t8.type,
|
|
127555
|
+
workState: workStateExpr,
|
|
127556
|
+
queueRank: t8.queueRank,
|
|
127557
|
+
focusState: t8.focusState,
|
|
127558
|
+
dueDate: t8.dueDate,
|
|
127559
|
+
updatedAt: t8.updatedAt,
|
|
127560
|
+
teamId: t8.teamId,
|
|
127561
|
+
assigneeId: t8.assigneeId,
|
|
127562
|
+
assigneeName: schema_exports.users.fullName,
|
|
127563
|
+
projectId: t8.projectId,
|
|
127564
|
+
projectName: schema_exports.projects.name,
|
|
127565
|
+
customerId: t8.customerId,
|
|
127566
|
+
customerName: schema_exports.customers.name,
|
|
127567
|
+
blockedReason: sql`(${t8.metadata} ->> 'blockedReason')`
|
|
127568
|
+
}).from(t8).leftJoin(schema_exports.projects, eq(schema_exports.projects.id, t8.projectId)).leftJoin(schema_exports.customers, eq(schema_exports.customers.id, t8.customerId)).leftJoin(schema_exports.users, eq(schema_exports.users.id, t8.assigneeId)).where(and(...conditions)).orderBy(
|
|
127569
|
+
sql`CASE ${t8.focusState} WHEN 'today' THEN 0 WHEN 'week' THEN 1 ELSE 2 END ASC`,
|
|
127570
|
+
sql`${t8.queueRank} ASC NULLS LAST`,
|
|
127571
|
+
desc(t8.priority),
|
|
127572
|
+
sql`${t8.dueDate} ASC NULLS LAST`,
|
|
127573
|
+
desc(t8.updatedAt)
|
|
127574
|
+
).limit(Math.min(filters.pageSize ?? 200, 500));
|
|
127575
|
+
return rows;
|
|
127576
|
+
}
|
|
127577
|
+
function serializeItem(row) {
|
|
127578
|
+
return {
|
|
127579
|
+
id: row.id,
|
|
127580
|
+
ticketNumber: row.ticketNumber,
|
|
127581
|
+
title: row.title,
|
|
127582
|
+
status: row.status,
|
|
127583
|
+
workState: row.workState,
|
|
127584
|
+
priority: row.priority,
|
|
127585
|
+
type: row.type,
|
|
127586
|
+
dueDate: row.dueDate,
|
|
127587
|
+
queueRank: row.queueRank,
|
|
127588
|
+
focusState: row.focusState,
|
|
127589
|
+
project: row.projectId ? { id: row.projectId, name: row.projectName } : null,
|
|
127590
|
+
customer: row.customerId ? { id: row.customerId, name: row.customerName } : null,
|
|
127591
|
+
assignee: row.assigneeId ? { id: row.assigneeId, name: row.assigneeName } : null,
|
|
127592
|
+
blockedReason: row.blockedReason,
|
|
127593
|
+
updatedAt: row.updatedAt
|
|
127594
|
+
};
|
|
127595
|
+
}
|
|
127596
|
+
async function handleGetMyWorkQueue(input) {
|
|
127597
|
+
const ctx = getAuthContext();
|
|
127598
|
+
const scope = await resolveTeamScope(input.teamId);
|
|
127599
|
+
if (!scope.ok) return scope.response;
|
|
127600
|
+
const rows = await loadWorkQueue(
|
|
127601
|
+
scope,
|
|
127602
|
+
{ mode: "one", userId: ctx.userId },
|
|
127603
|
+
input
|
|
127604
|
+
);
|
|
127605
|
+
const items = rows.map(serializeItem);
|
|
127606
|
+
return jsonResponse3({
|
|
127607
|
+
assigneeId: ctx.userId,
|
|
127608
|
+
teamScope: scope.teamIds,
|
|
127609
|
+
totals: {
|
|
127610
|
+
total: items.length,
|
|
127611
|
+
now: items.filter((i6) => i6.workState === "now").length,
|
|
127612
|
+
waiting: items.filter((i6) => i6.workState === "waiting").length,
|
|
127613
|
+
later: items.filter((i6) => i6.workState === "later").length,
|
|
127614
|
+
blocked: items.filter((i6) => i6.workState === "blocked").length
|
|
127615
|
+
},
|
|
127616
|
+
items
|
|
127617
|
+
});
|
|
127618
|
+
}
|
|
127619
|
+
async function handleGetAssigneeWorkQueue(input) {
|
|
127620
|
+
const ctx = getAuthContext();
|
|
127621
|
+
const scope = await resolveTeamScope(input.teamId);
|
|
127622
|
+
if (!scope.ok) return scope.response;
|
|
127623
|
+
const rawAssignee = input.assigneeId?.trim();
|
|
127624
|
+
const isAll = rawAssignee === "all";
|
|
127625
|
+
const targetUserId = !rawAssignee || rawAssignee === "me" ? ctx.userId : rawAssignee;
|
|
127626
|
+
const rows = await loadWorkQueue(
|
|
127627
|
+
scope,
|
|
127628
|
+
isAll ? { mode: "all" } : { mode: "one", userId: targetUserId },
|
|
127629
|
+
input
|
|
127630
|
+
);
|
|
127631
|
+
const items = rows.map(serializeItem);
|
|
127632
|
+
if (isAll && input.groupByAssignee) {
|
|
127633
|
+
const groups = /* @__PURE__ */ new Map();
|
|
127634
|
+
for (const item of items) {
|
|
127635
|
+
if (!item.assignee) continue;
|
|
127636
|
+
const existing = groups.get(item.assignee.id);
|
|
127637
|
+
if (existing) {
|
|
127638
|
+
existing.items.push(item);
|
|
127639
|
+
} else {
|
|
127640
|
+
groups.set(item.assignee.id, {
|
|
127641
|
+
assignee: item.assignee,
|
|
127642
|
+
items: [item]
|
|
127643
|
+
});
|
|
127644
|
+
}
|
|
127645
|
+
}
|
|
127646
|
+
return jsonResponse3({
|
|
127647
|
+
assigneeId: "all",
|
|
127648
|
+
teamScope: scope.teamIds,
|
|
127649
|
+
grouped: true,
|
|
127650
|
+
groups: [...groups.values()].map((g6) => ({
|
|
127651
|
+
assignee: g6.assignee,
|
|
127652
|
+
total: g6.items.length,
|
|
127653
|
+
items: g6.items
|
|
127654
|
+
}))
|
|
127655
|
+
});
|
|
127656
|
+
}
|
|
127657
|
+
return jsonResponse3({
|
|
127658
|
+
assigneeId: isAll ? "all" : targetUserId,
|
|
127659
|
+
teamScope: scope.teamIds,
|
|
127660
|
+
total: items.length,
|
|
127661
|
+
items
|
|
127662
|
+
});
|
|
127663
|
+
}
|
|
127664
|
+
async function handleGetTeamWorkloadOverview(input) {
|
|
127665
|
+
const scope = await resolveTeamScope(input.teamId);
|
|
127666
|
+
if (!scope.ok) return scope.response;
|
|
127667
|
+
const staleDays = input.staleDays ?? 7;
|
|
127668
|
+
const upcomingDays = input.upcomingDays ?? 7;
|
|
127669
|
+
const includeUnassigned = input.includeUnassigned ?? true;
|
|
127670
|
+
const conditions = [
|
|
127671
|
+
buildTicketAccessPredicate(
|
|
127672
|
+
scope.teamIds,
|
|
127673
|
+
scope.projectIds,
|
|
127674
|
+
scope.customerIds
|
|
127675
|
+
),
|
|
127676
|
+
eq(t8.isDeleted, false),
|
|
127677
|
+
inArray(t8.status, [...ACTIVE_STATUSES])
|
|
127678
|
+
];
|
|
127679
|
+
if (!includeUnassigned) {
|
|
127680
|
+
conditions.push(sql`${t8.assigneeId} IS NOT NULL`);
|
|
127681
|
+
}
|
|
127682
|
+
const rows = await db.select({
|
|
127683
|
+
assigneeId: t8.assigneeId,
|
|
127684
|
+
assigneeName: schema_exports.users.fullName,
|
|
127685
|
+
total: sql`count(*)::int`,
|
|
127686
|
+
now: sql`(count(*) filter (where ${t8.status} in ('open', 'in_progress')))::int`,
|
|
127687
|
+
waiting: sql`(count(*) filter (where ${t8.status} = 'review'))::int`,
|
|
127688
|
+
later: sql`(count(*) filter (where ${t8.status} = 'backlog'))::int`,
|
|
127689
|
+
blocked: sql`(count(*) filter (where ${t8.status} = 'blocked'))::int`,
|
|
127690
|
+
highPriority: sql`(count(*) filter (where ${t8.priority} in ('high', 'critical')))::int`,
|
|
127691
|
+
stale: sql`(count(*) filter (where ${t8.updatedAt} < now() - make_interval(days => ${staleDays})))::int`,
|
|
127692
|
+
upcoming: sql`(count(*) filter (where ${t8.dueDate} is not null and ${t8.dueDate} >= now() and ${t8.dueDate} <= now() + make_interval(days => ${upcomingDays})))::int`
|
|
127693
|
+
}).from(t8).leftJoin(schema_exports.users, eq(schema_exports.users.id, t8.assigneeId)).where(and(...conditions)).groupBy(t8.assigneeId, schema_exports.users.fullName).orderBy(desc(sql`count(*)`));
|
|
127694
|
+
return jsonResponse3({
|
|
127695
|
+
teamScope: scope.teamIds,
|
|
127696
|
+
config: { staleDays, upcomingDays, includeUnassigned },
|
|
127697
|
+
assignees: rows.map((r6) => ({
|
|
127698
|
+
assignee: r6.assigneeId ? { id: r6.assigneeId, name: r6.assigneeName } : null,
|
|
127699
|
+
total: r6.total,
|
|
127700
|
+
now: r6.now,
|
|
127701
|
+
waiting: r6.waiting,
|
|
127702
|
+
later: r6.later,
|
|
127703
|
+
blocked: r6.blocked,
|
|
127704
|
+
highPriority: r6.highPriority,
|
|
127705
|
+
stale: r6.stale,
|
|
127706
|
+
upcoming: r6.upcoming
|
|
127707
|
+
}))
|
|
127708
|
+
});
|
|
127709
|
+
}
|
|
127710
|
+
async function resolveManageableTicket(ticketId, scope) {
|
|
127711
|
+
const ctx = getAuthContext();
|
|
127712
|
+
const [ticket] = await db.select({
|
|
127713
|
+
id: t8.id,
|
|
127714
|
+
teamId: t8.teamId,
|
|
127715
|
+
status: t8.status,
|
|
127716
|
+
assigneeId: t8.assigneeId,
|
|
127717
|
+
projectId: t8.projectId,
|
|
127718
|
+
customerId: t8.customerId,
|
|
127719
|
+
metadata: t8.metadata
|
|
127720
|
+
}).from(t8).where(eq(t8.id, ticketId)).limit(1);
|
|
127721
|
+
if (!ticket) {
|
|
127722
|
+
return {
|
|
127723
|
+
ok: false,
|
|
127724
|
+
response: textResponse13(
|
|
127725
|
+
`Ticket not found: ${ticketId}. Call get-tickets first to find the correct ticket.`
|
|
127726
|
+
)
|
|
127727
|
+
};
|
|
127728
|
+
}
|
|
127729
|
+
let hasAccess = scope.teamIds.includes(ticket.teamId);
|
|
127730
|
+
if (!hasAccess && ticket.projectId)
|
|
127731
|
+
hasAccess = scope.projectIds.includes(ticket.projectId);
|
|
127732
|
+
if (!hasAccess && ticket.customerId)
|
|
127733
|
+
hasAccess = scope.customerIds.includes(ticket.customerId);
|
|
127734
|
+
if (!hasAccess) {
|
|
127735
|
+
return {
|
|
127736
|
+
ok: false,
|
|
127737
|
+
response: textResponse13(`No access to ticket: ${ticketId}.`)
|
|
127738
|
+
};
|
|
127739
|
+
}
|
|
127740
|
+
if (ticket.assigneeId !== ctx.userId) {
|
|
127741
|
+
const [membership] = await db.select({ role: schema_exports.usersOnTeam.role }).from(schema_exports.usersOnTeam).where(
|
|
127742
|
+
and(
|
|
127743
|
+
eq(schema_exports.usersOnTeam.userId, ctx.userId),
|
|
127744
|
+
eq(schema_exports.usersOnTeam.teamId, ticket.teamId)
|
|
127745
|
+
)
|
|
127746
|
+
).limit(1);
|
|
127747
|
+
if (membership?.role !== "owner") {
|
|
127748
|
+
return {
|
|
127749
|
+
ok: false,
|
|
127750
|
+
response: textResponse13(
|
|
127751
|
+
"Permission denied: only the assignee or a team owner can manage this ticket's work queue."
|
|
127752
|
+
)
|
|
127753
|
+
};
|
|
127754
|
+
}
|
|
127755
|
+
}
|
|
127756
|
+
return { ok: true, ticket };
|
|
127757
|
+
}
|
|
127758
|
+
async function handleSetAssigneeQueueOrder(input) {
|
|
127759
|
+
if (!input.ticketId) return textResponse13("Error: `ticketId` is required.");
|
|
127760
|
+
if (typeof input.position !== "number" || input.position < 0) {
|
|
127761
|
+
return textResponse13("Error: `position` must be a number >= 0.");
|
|
127762
|
+
}
|
|
127763
|
+
const scope = await resolveTeamScope(input.teamId);
|
|
127764
|
+
if (!scope.ok) return scope.response;
|
|
127765
|
+
const resolved = await resolveManageableTicket(input.ticketId, scope);
|
|
127766
|
+
if (!resolved.ok) return resolved.response;
|
|
127767
|
+
const { ticket } = resolved;
|
|
127768
|
+
if (!ticket.assigneeId) {
|
|
127769
|
+
return textResponse13(
|
|
127770
|
+
"Ticket has no assignee; assign it first before ranking it in a queue."
|
|
127771
|
+
);
|
|
127772
|
+
}
|
|
127773
|
+
const queue = await db.select({ id: t8.id, queueRank: t8.queueRank }).from(t8).where(
|
|
127774
|
+
and(
|
|
127775
|
+
eq(t8.isDeleted, false),
|
|
127776
|
+
eq(t8.assigneeId, ticket.assigneeId),
|
|
127777
|
+
eq(t8.teamId, ticket.teamId),
|
|
127778
|
+
inArray(t8.status, [...ACTIVE_STATUSES]),
|
|
127779
|
+
ne(t8.id, ticket.id)
|
|
127780
|
+
)
|
|
127781
|
+
).orderBy(
|
|
127782
|
+
sql`${t8.queueRank} ASC NULLS LAST`,
|
|
127783
|
+
desc(t8.priority),
|
|
127784
|
+
desc(t8.createdAt)
|
|
127785
|
+
);
|
|
127786
|
+
let newRank;
|
|
127787
|
+
if (queue.length === 0) {
|
|
127788
|
+
newRank = RANK_BASE;
|
|
127789
|
+
} else if (input.position <= 0) {
|
|
127790
|
+
const first = Number(queue[0]?.queueRank ?? RANK_BASE);
|
|
127791
|
+
newRank = Math.max(RANK_MIN, first - RANK_BASE / 2);
|
|
127792
|
+
} else if (input.position >= queue.length) {
|
|
127793
|
+
const last = Number(queue[queue.length - 1]?.queueRank ?? RANK_BASE);
|
|
127794
|
+
newRank = last + RANK_APPEND_SPACING;
|
|
127795
|
+
} else {
|
|
127796
|
+
const prev = Number(queue[input.position - 1]?.queueRank ?? RANK_BASE / 2);
|
|
127797
|
+
const next = Number(queue[input.position]?.queueRank ?? RANK_BASE * 1.5);
|
|
127798
|
+
newRank = (prev + next) / 2;
|
|
127799
|
+
}
|
|
127800
|
+
await db.update(t8).set({ queueRank: newRank }).where(eq(t8.id, ticket.id));
|
|
127801
|
+
return jsonResponse3({
|
|
127802
|
+
ticketId: ticket.id,
|
|
127803
|
+
assigneeId: ticket.assigneeId,
|
|
127804
|
+
position: input.position,
|
|
127805
|
+
queueRank: newRank
|
|
127806
|
+
});
|
|
127807
|
+
}
|
|
127808
|
+
async function handleUpdateTicketWorkState(input) {
|
|
127809
|
+
if (!input.ticketId) return textResponse13("Error: `ticketId` is required.");
|
|
127810
|
+
const newStatus = workStateToStatus(input.workState);
|
|
127811
|
+
if (!newStatus) {
|
|
127812
|
+
return textResponse13(
|
|
127813
|
+
`Error: invalid workState "${input.workState}". Allowed: now, waiting, later, blocked.`
|
|
127814
|
+
);
|
|
127815
|
+
}
|
|
127816
|
+
const scope = await resolveTeamScope(input.teamId);
|
|
127817
|
+
if (!scope.ok) return scope.response;
|
|
127818
|
+
const resolved = await resolveManageableTicket(input.ticketId, scope);
|
|
127819
|
+
if (!resolved.ok) return resolved.response;
|
|
127820
|
+
const { ticket } = resolved;
|
|
127821
|
+
const updateSet = {
|
|
127822
|
+
status: newStatus,
|
|
127823
|
+
updatedAt: sql`NOW()`
|
|
127824
|
+
};
|
|
127825
|
+
if (input.workState === "blocked") {
|
|
127826
|
+
const blockedMeta = JSON.stringify({
|
|
127827
|
+
blockedReason: input.blockedReason ?? null,
|
|
127828
|
+
blockedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
127829
|
+
});
|
|
127830
|
+
updateSet.metadata = sql`coalesce(${t8.metadata}, '{}'::jsonb) || ${blockedMeta}::jsonb`;
|
|
127831
|
+
}
|
|
127832
|
+
await db.update(t8).set(updateSet).where(eq(t8.id, ticket.id));
|
|
127833
|
+
return jsonResponse3({
|
|
127834
|
+
ticketId: ticket.id,
|
|
127835
|
+
workState: input.workState,
|
|
127836
|
+
status: newStatus,
|
|
127837
|
+
previousStatus: ticket.status
|
|
127838
|
+
});
|
|
127839
|
+
}
|
|
127840
|
+
async function handleMarkTicketBlocked(input) {
|
|
127841
|
+
if (!input.ticketId) return textResponse13("Error: `ticketId` is required.");
|
|
127842
|
+
const scope = await resolveTeamScope(input.teamId);
|
|
127843
|
+
if (!scope.ok) return scope.response;
|
|
127844
|
+
const resolved = await resolveManageableTicket(input.ticketId, scope);
|
|
127845
|
+
if (!resolved.ok) return resolved.response;
|
|
127846
|
+
const { ticket } = resolved;
|
|
127847
|
+
if (input.unblock) {
|
|
127848
|
+
await db.update(t8).set({ status: "in_progress", updatedAt: sql`NOW()` }).where(eq(t8.id, ticket.id));
|
|
127849
|
+
return jsonResponse3({
|
|
127850
|
+
ticketId: ticket.id,
|
|
127851
|
+
status: "in_progress",
|
|
127852
|
+
unblocked: true
|
|
127853
|
+
});
|
|
127854
|
+
}
|
|
127855
|
+
const blockedMeta = JSON.stringify({
|
|
127856
|
+
blockedReason: input.reason ?? null,
|
|
127857
|
+
blockedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
127858
|
+
});
|
|
127859
|
+
await db.update(t8).set({
|
|
127860
|
+
status: "blocked",
|
|
127861
|
+
updatedAt: sql`NOW()`,
|
|
127862
|
+
metadata: sql`coalesce(${t8.metadata}, '{}'::jsonb) || ${blockedMeta}::jsonb`
|
|
127863
|
+
}).where(eq(t8.id, ticket.id));
|
|
127864
|
+
return jsonResponse3({
|
|
127865
|
+
ticketId: ticket.id,
|
|
127866
|
+
status: "blocked",
|
|
127867
|
+
blockedReason: input.reason ?? null
|
|
127868
|
+
});
|
|
127869
|
+
}
|
|
127870
|
+
|
|
127225
127871
|
// src/tools/user-activity-report.ts
|
|
127226
127872
|
var DEFAULT_TIMEZONE = "Europe/Amsterdam";
|
|
127227
127873
|
var DEFAULT_PAGE_SIZE = 200;
|
|
@@ -127392,10 +128038,10 @@ function formatIsoWithOffset(date10, timeZone) {
|
|
|
127392
128038
|
const local = `${parts.year}-${parts.month}-${parts.day}T${hour2}:${parts.minute}:${parts.second}`;
|
|
127393
128039
|
return `${local}${timeZoneOffset(date10, timeZone)}`;
|
|
127394
128040
|
}
|
|
127395
|
-
function
|
|
128041
|
+
function textResponse14(text3) {
|
|
127396
128042
|
return { content: [{ type: "text", text: text3 }] };
|
|
127397
128043
|
}
|
|
127398
|
-
function
|
|
128044
|
+
function jsonResponse4(payload) {
|
|
127399
128045
|
return {
|
|
127400
128046
|
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }]
|
|
127401
128047
|
};
|
|
@@ -127420,7 +128066,7 @@ async function handleGetUserActivityReport(input) {
|
|
|
127420
128066
|
limitations.push(`Ignored unknown include value "${value}".`);
|
|
127421
128067
|
}
|
|
127422
128068
|
if (includes.size === 0) {
|
|
127423
|
-
return
|
|
128069
|
+
return textResponse14(
|
|
127424
128070
|
`Error: \`include\` contained no valid categories. Allowed: ${ACTIVITY_INCLUDE_VALUES.join(", ")}.`
|
|
127425
128071
|
);
|
|
127426
128072
|
}
|
|
@@ -127432,12 +128078,12 @@ async function handleGetUserActivityReport(input) {
|
|
|
127432
128078
|
timezone = DEFAULT_TIMEZONE;
|
|
127433
128079
|
}
|
|
127434
128080
|
if (input.dateFrom && !isValidIsoDate2(input.dateFrom)) {
|
|
127435
|
-
return
|
|
128081
|
+
return textResponse14(
|
|
127436
128082
|
`Error: invalid dateFrom "${input.dateFrom}". Use YYYY-MM-DD.`
|
|
127437
128083
|
);
|
|
127438
128084
|
}
|
|
127439
128085
|
if (input.dateTo && !isValidIsoDate2(input.dateTo)) {
|
|
127440
|
-
return
|
|
128086
|
+
return textResponse14(
|
|
127441
128087
|
`Error: invalid dateTo "${input.dateTo}". Use YYYY-MM-DD.`
|
|
127442
128088
|
);
|
|
127443
128089
|
}
|
|
@@ -127447,17 +128093,17 @@ async function handleGetUserActivityReport(input) {
|
|
|
127447
128093
|
timezone
|
|
127448
128094
|
});
|
|
127449
128095
|
if (window2.from > window2.to) {
|
|
127450
|
-
return
|
|
128096
|
+
return textResponse14(
|
|
127451
128097
|
`Error: dateFrom (${window2.from}) is after dateTo (${window2.to}).`
|
|
127452
128098
|
);
|
|
127453
128099
|
}
|
|
127454
128100
|
const scope = await resolveTeamScope(input.teamId);
|
|
127455
128101
|
if (!scope.ok) return scope.response;
|
|
127456
128102
|
if (scope.teamIds.length === 0) {
|
|
127457
|
-
return
|
|
128103
|
+
return textResponse14("No accessible teams found.");
|
|
127458
128104
|
}
|
|
127459
128105
|
if (input.projectId && !scope.projectIds.includes(input.projectId)) {
|
|
127460
|
-
return
|
|
128106
|
+
return textResponse14(
|
|
127461
128107
|
`Project not found or no access: ${input.projectId}. Call get-projects first.`
|
|
127462
128108
|
);
|
|
127463
128109
|
}
|
|
@@ -127687,7 +128333,7 @@ async function handleGetUserActivityReport(input) {
|
|
|
127687
128333
|
timeEntrySeconds += seconds;
|
|
127688
128334
|
const hours = hoursFrom2(seconds);
|
|
127689
128335
|
const linked = ticketsByEvent.get(r6.id) ?? [];
|
|
127690
|
-
for (const
|
|
128336
|
+
for (const t9 of linked) ticketsTouched.add(t9.id);
|
|
127691
128337
|
const primary = linked[0] ?? null;
|
|
127692
128338
|
const projectLabel = r6.projectName ? ` on ${r6.projectName}` : "";
|
|
127693
128339
|
const titleLabel = r6.title ? ` \u2014 ${r6.title}` : "";
|
|
@@ -127705,9 +128351,9 @@ async function handleGetUserActivityReport(input) {
|
|
|
127705
128351
|
hours,
|
|
127706
128352
|
eventType: r6.type,
|
|
127707
128353
|
billingStatus: r6.billingStatus,
|
|
127708
|
-
linkedTickets: linked.map((
|
|
127709
|
-
id:
|
|
127710
|
-
ticketNumber:
|
|
128354
|
+
linkedTickets: linked.map((t9) => ({
|
|
128355
|
+
id: t9.id,
|
|
128356
|
+
ticketNumber: t9.ticketNumber
|
|
127711
128357
|
}))
|
|
127712
128358
|
}
|
|
127713
128359
|
});
|
|
@@ -127755,7 +128401,7 @@ async function handleGetUserActivityReport(input) {
|
|
|
127755
128401
|
MAX_PAGE_SIZE
|
|
127756
128402
|
);
|
|
127757
128403
|
const pagedActivities = activities2.slice(0, pageSize);
|
|
127758
|
-
return
|
|
128404
|
+
return jsonResponse4({
|
|
127759
128405
|
user,
|
|
127760
128406
|
period: { from: window2.from, to: window2.to, timezone },
|
|
127761
128407
|
filters: {
|
|
@@ -127817,6 +128463,31 @@ function createMcpServer() {
|
|
|
127817
128463
|
return await handleGetTeams();
|
|
127818
128464
|
case "get-tickets":
|
|
127819
128465
|
return await handleGetTickets(asToolArgs(toolArgs));
|
|
128466
|
+
case "get-my-work-queue":
|
|
128467
|
+
return await handleGetMyWorkQueue(
|
|
128468
|
+
asToolArgs(toolArgs)
|
|
128469
|
+
);
|
|
128470
|
+
case "get-assignee-work-queue":
|
|
128471
|
+
return await handleGetAssigneeWorkQueue(
|
|
128472
|
+
asToolArgs(toolArgs)
|
|
128473
|
+
);
|
|
128474
|
+
case "get-team-workload-overview":
|
|
128475
|
+
return await handleGetTeamWorkloadOverview(
|
|
128476
|
+
asToolArgs(toolArgs)
|
|
128477
|
+
);
|
|
128478
|
+
case "set-assignee-queue-order":
|
|
128479
|
+
case "update-ticket-rank":
|
|
128480
|
+
return await handleSetAssigneeQueueOrder(
|
|
128481
|
+
asToolArgs(toolArgs)
|
|
128482
|
+
);
|
|
128483
|
+
case "update-ticket-work-state":
|
|
128484
|
+
return await handleUpdateTicketWorkState(
|
|
128485
|
+
asToolArgs(toolArgs)
|
|
128486
|
+
);
|
|
128487
|
+
case "mark-ticket-blocked":
|
|
128488
|
+
return await handleMarkTicketBlocked(
|
|
128489
|
+
asToolArgs(toolArgs)
|
|
128490
|
+
);
|
|
127820
128491
|
case "get-ticket-by-id":
|
|
127821
128492
|
return await handleGetTicketById(asToolArgs(toolArgs));
|
|
127822
128493
|
case "create-ticket":
|