Мониторинг: в логах заявок — вид, код и название заявки
Tests / frontend-test (pull_request) Successful in 1m23s
Tests / frontend-test (pull_request) Successful in 1m23s
«Создана заявка: Заявка на прием · TNS-… · Инженер — Проект X», «Заявка отправлена на согласование: …», «Заявка согласована: TNS-… · …» — заявку видно прямо в списке логов; те же данные — в полях request.*. Отправка на согласование пишется при сохранении заявки с отправленным статусом (там известно, что за заявка), из writeRoute лог убран. Код и название для решения дочитываются, сбой чтения решение не ломает. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { log } from '@tnsu/monitoring-web';
|
||||
import { resolveRoute } from './approvalRoute.service';
|
||||
import { ApprovalListService, IApproverToWrite } from './approvalList.service';
|
||||
import { IMatrixRow } from './models/IMatrixRow';
|
||||
@@ -69,11 +68,6 @@ export async function writeApprovers(
|
||||
await approval.createSteps(requestId, approvers, rowStatus, APPROVAL_PHASE.approval, 1);
|
||||
if (submitted) {
|
||||
await approval.activateNextQueued(requestId);
|
||||
log.info('Заявка отправлена на согласование', {
|
||||
'request.id': requestId,
|
||||
'request.status': status,
|
||||
'route.approvers': approvers.length,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,11 +138,5 @@ export async function writeRoute(
|
||||
|
||||
if (submitted) {
|
||||
await approval.activateNextQueued(requestId);
|
||||
log.info('Заявка отправлена на согласование', {
|
||||
'request.id': requestId,
|
||||
'request.status': status,
|
||||
'route.approvers': approvers.length,
|
||||
'route.executors': executors.length,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,14 +345,7 @@ export class ApproverService {
|
||||
const rows = await this.approval.getForRequest(requestId);
|
||||
const requestStatus = this.computeRequestStatus(rows);
|
||||
await this.updateRequestStatus(requestId, requestStatus);
|
||||
log.info(DECISION_MESSAGE[decision], {
|
||||
'request.id': requestId,
|
||||
'request.list': this.dataListRef,
|
||||
'request.status': requestStatus,
|
||||
'approval.decision': decision,
|
||||
'approval.rowId': rowId,
|
||||
'approval.comment': comment.slice(0, 500),
|
||||
});
|
||||
await this.logDecision(requestId, rowId, decision, comment, requestStatus);
|
||||
emitRequestsChanged();
|
||||
return requestStatus;
|
||||
}
|
||||
@@ -381,6 +374,42 @@ export class ApproverService {
|
||||
return REQUEST_STATUS.execution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Решение — в логи мониторинга, с кодом и названием заявки, чтобы её было видно прямо в списке логов.
|
||||
* Код и название дочитываются отдельно; не получилось — пишем без них: решение уже применено.
|
||||
*/
|
||||
private async logDecision(
|
||||
requestId: number,
|
||||
rowId: number,
|
||||
decision: ApproverDecision,
|
||||
comment: string,
|
||||
requestStatus: string
|
||||
): Promise<void> {
|
||||
let code = '';
|
||||
let title = '';
|
||||
try {
|
||||
const item = (await this.dataList().items.getById(requestId).select('Title', 'RequestUniqueCode')()) as {
|
||||
Title?: string;
|
||||
RequestUniqueCode?: string;
|
||||
};
|
||||
code = item.RequestUniqueCode || '';
|
||||
title = item.Title || '';
|
||||
} catch {
|
||||
// без кода и названия — лог всё равно нужен
|
||||
}
|
||||
const what = [code, title].filter(Boolean).join(' · ') || `№${requestId}`;
|
||||
log.info(`${DECISION_MESSAGE[decision]}: ${what}`, {
|
||||
'request.id': requestId,
|
||||
'request.code': code,
|
||||
'request.title': title,
|
||||
'request.list': this.dataListRef,
|
||||
'request.status': requestStatus,
|
||||
'approval.decision': decision,
|
||||
'approval.rowId': rowId,
|
||||
'approval.comment': comment.slice(0, 500),
|
||||
});
|
||||
}
|
||||
|
||||
private dataList(): IList {
|
||||
return this.dataListRef.startsWith('/')
|
||||
? getSP().web.getList(this.dataListRef)
|
||||
|
||||
@@ -7,6 +7,8 @@ import { getSP } from './pnp/pnpjs';
|
||||
import { buildRequestUniqueCode } from './requestCode';
|
||||
import { dataListTitle } from './listTitles';
|
||||
import { RequestTypeId } from '../models/types';
|
||||
import { REQUEST_TYPES } from '../data/requests';
|
||||
import { isSubmittedStatus } from './approval/models/statuses';
|
||||
|
||||
/**
|
||||
* Список данных, в который фактически пишем: listId (конкретная партиция —
|
||||
@@ -51,6 +53,7 @@ export async function saveRequestItem(
|
||||
|
||||
if (existingId) {
|
||||
await list.items.getById(existingId).update(item);
|
||||
logSaved(formId, existingId, undefined, item, false);
|
||||
return { id: existingId };
|
||||
}
|
||||
|
||||
@@ -59,8 +62,34 @@ export async function saveRequestItem(
|
||||
// Код известен только после создания элемента (нужен его Id).
|
||||
const code = buildRequestUniqueCode(codePrefix, id, new Date());
|
||||
await list.items.getById(id).update({ RequestUniqueCode: code });
|
||||
// Событие для мониторинга: кто (пользователь — из токена) и какую заявку создал. Отправка на согласование
|
||||
// и решения пишутся отдельно — approvalSubmission.service.ts и approverDecision.service.ts.
|
||||
log.info('Создана заявка', { 'request.type': formId, 'request.id': id, 'request.code': code });
|
||||
logSaved(formId, id, code, item, true);
|
||||
return { id, code };
|
||||
}
|
||||
|
||||
/**
|
||||
* События для мониторинга: какая заявка создана и отправлена на согласование (пользователь — из токена).
|
||||
* В тексте — вид, код и название заявки, чтобы её было видно прямо в списке логов. Решения согласующих
|
||||
* пишет approverDecision.service.ts.
|
||||
*/
|
||||
function logSaved(
|
||||
formId: RequestTypeId,
|
||||
id: number,
|
||||
code: string | undefined,
|
||||
item: Record<string, unknown>,
|
||||
created: boolean
|
||||
): void {
|
||||
const typeTitle = REQUEST_TYPES.find((t) => t.id === formId)?.title ?? formId;
|
||||
const title = typeof item.Title === 'string' ? item.Title : '';
|
||||
const status = typeof item.RequestStatus === 'string' ? item.RequestStatus : '';
|
||||
const what = [typeTitle, code, title].filter(Boolean).join(' · ');
|
||||
const attributes = {
|
||||
'request.type': formId,
|
||||
'request.typeTitle': typeTitle,
|
||||
'request.id': id,
|
||||
'request.code': code ?? '',
|
||||
'request.title': title,
|
||||
'request.status': status,
|
||||
};
|
||||
if (created) log.info(`Создана заявка: ${what}`, attributes);
|
||||
if (isSubmittedStatus(status)) log.info(`Заявка отправлена на согласование: ${what}`, attributes);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user