Mirror of https://github.com/roostorg/coop
github.com/roostorg/coop
1import _ from 'lodash';
2import { type ReadonlyDeep } from 'type-fest';
3
4import { type Dependencies } from '../../iocContainer/index.js';
5import { inject } from '../../iocContainer/utils.js';
6import {
7 isFullSubmission,
8 type RuleInput,
9} from '../../rule_engine/RuleEvaluator.js';
10import { type ManualReviewJobKind } from '../../services/manualReviewToolService/index.js';
11import { type ConditionSetWithResult } from '../../services/moderationConfigService/index.js';
12import { fromCorrelationId } from '../../utils/correlationIds.js';
13import { jsonStringifyUnstable } from '../../utils/encoding.js';
14import { getUtcDateOnlyString } from '../../utils/time.js';
15import { type ActionExecutionCorrelationId } from './ActionExecutionLogger.js';
16import {
17 pickConditionPropsToLog,
18 type RuleExecutionCorrelationId,
19} from './ruleExecutionLoggingUtils.js';
20
21type RoutingRuleExecutionData = {
22 orgId: string;
23 routingRule: ReadonlyDeep<{
24 id: string;
25 name: string;
26 version: string;
27 destinationQueueId: string;
28 }>;
29 ruleInput: RuleInput;
30 result: ReadonlyDeep<ConditionSetWithResult>;
31 passed: boolean;
32 correlationId: RuleExecutionCorrelationId | ActionExecutionCorrelationId;
33 manualReviewJobKind: ManualReviewJobKind;
34};
35
36// TODO: should this live within the MRT service?
37class RoutingRuleExecutionLogger {
38 constructor(
39 private readonly analytics: Dependencies['DataWarehouseAnalytics'],
40 ) {}
41 async logRoutingRuleExecutions(
42 executions: readonly RoutingRuleExecutionData[],
43 ) {
44 const now = new Date();
45 await this.analytics.bulkWrite(
46 'MANUAL_REVIEW_TOOL.ROUTING_RULE_EXECUTIONS' as any,
47 executions.map((data) => ({
48 ds: getUtcDateOnlyString(now),
49 ts: now.valueOf(),
50 org_id: data.orgId,
51 item_id: data.ruleInput.itemId,
52 item_type_id: data.ruleInput.itemType.id,
53 item_type_kind: data.ruleInput.itemType.kind,
54 destination_queue_id: data.routingRule.destinationQueueId,
55 ...(isFullSubmission(data.ruleInput)
56 ? {
57 item_submission_id: data.ruleInput.submissionId,
58 item_data: jsonStringifyUnstable(data.ruleInput.data),
59 item_type_name: data.ruleInput.itemType.name,
60 item_creator_id: data.ruleInput.creator?.id,
61 item_creator_type_id: data.ruleInput.creator?.typeId,
62 item_type_schema: jsonStringifyUnstable(
63 data.ruleInput.itemType.schema,
64 ),
65 item_type_schema_field_roles:
66 data.ruleInput.itemType.schemaFieldRoles,
67 item_type_schema_variant: data.ruleInput.itemType.schemaVariant,
68 item_type_version: data.ruleInput.itemType.version,
69 }
70 : {}),
71 rule: data.routingRule.name,
72 rule_id: data.routingRule.id,
73 rule_version: data.routingRule.version,
74 correlation_id: fromCorrelationId(data.correlationId),
75 result: pickConditionPropsToLog(data.result),
76 passed: data.passed,
77 job_kind: data.manualReviewJobKind,
78 })),
79 );
80 }
81}
82
83export default inject(['DataWarehouseAnalytics'], RoutingRuleExecutionLogger);
84export { type RoutingRuleExecutionLogger };