@open-mercato/core 0.7.1-develop.7173.1.a901520d0f → 0.7.1-develop.7176.1.d229567a50
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/.turbo/turbo-build.log +2 -2
- package/dist/generated/entities/phone_call/index.js +53 -0
- package/dist/generated/entities/phone_call/index.js.map +7 -0
- package/dist/generated/entities/phone_call_participant/index.js +27 -0
- package/dist/generated/entities/phone_call_participant/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +5 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +41 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/configs/lib/upgrade-actions.js +20 -0
- package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
- package/dist/modules/entities/cli.js +46 -3
- package/dist/modules/entities/cli.js.map +2 -2
- package/dist/modules/entities/migrations/Migration20260822120000.js +44 -0
- package/dist/modules/entities/migrations/Migration20260822120000.js.map +7 -0
- package/dist/modules/phone_calls/acl.js +15 -0
- package/dist/modules/phone_calls/acl.js.map +7 -0
- package/dist/modules/phone_calls/api/calls/route.js +132 -0
- package/dist/modules/phone_calls/api/calls/route.js.map +7 -0
- package/dist/modules/phone_calls/api/openapi.js +23 -0
- package/dist/modules/phone_calls/api/openapi.js.map +7 -0
- package/dist/modules/phone_calls/backend/page.js +261 -0
- package/dist/modules/phone_calls/backend/page.js.map +7 -0
- package/dist/modules/phone_calls/backend/page.meta.js +16 -0
- package/dist/modules/phone_calls/backend/page.meta.js.map +7 -0
- package/dist/modules/phone_calls/commands/calls.js +125 -0
- package/dist/modules/phone_calls/commands/calls.js.map +7 -0
- package/dist/modules/phone_calls/commands/index.js +2 -0
- package/dist/modules/phone_calls/commands/index.js.map +7 -0
- package/dist/modules/phone_calls/data/entities.js +162 -0
- package/dist/modules/phone_calls/data/entities.js.map +7 -0
- package/dist/modules/phone_calls/data/validators.js +68 -0
- package/dist/modules/phone_calls/data/validators.js.map +7 -0
- package/dist/modules/phone_calls/di.js +12 -0
- package/dist/modules/phone_calls/di.js.map +7 -0
- package/dist/modules/phone_calls/encryption.js +28 -0
- package/dist/modules/phone_calls/encryption.js.map +7 -0
- package/dist/modules/phone_calls/events.js +18 -0
- package/dist/modules/phone_calls/events.js.map +7 -0
- package/dist/modules/phone_calls/index.js +15 -0
- package/dist/modules/phone_calls/index.js.map +7 -0
- package/dist/modules/phone_calls/migrations/Migration20260706124120_phone_calls.js +22 -0
- package/dist/modules/phone_calls/migrations/Migration20260706124120_phone_calls.js.map +7 -0
- package/dist/modules/phone_calls/migrations/Migration20260814124333_phone_calls.js +13 -0
- package/dist/modules/phone_calls/migrations/Migration20260814124333_phone_calls.js.map +7 -0
- package/dist/modules/phone_calls/setup.js +16 -0
- package/dist/modules/phone_calls/setup.js.map +7 -0
- package/generated/entities/phone_call/index.ts +25 -0
- package/generated/entities/phone_call_participant/index.ts +12 -0
- package/generated/entities.ids.generated.ts +5 -0
- package/generated/entity-fields-registry.ts +41 -0
- package/package.json +7 -7
- package/src/modules/auth/i18n/de.json +3 -0
- package/src/modules/auth/i18n/en.json +3 -0
- package/src/modules/auth/i18n/es.json +3 -0
- package/src/modules/auth/i18n/ko.json +3 -0
- package/src/modules/auth/i18n/pl.json +3 -0
- package/src/modules/configs/lib/upgrade-actions.ts +20 -0
- package/src/modules/entities/cli.ts +61 -1
- package/src/modules/entities/migrations/Migration20260822120000.ts +56 -0
- package/src/modules/phone_calls/acl.ts +11 -0
- package/src/modules/phone_calls/api/calls/route.ts +150 -0
- package/src/modules/phone_calls/api/openapi.ts +25 -0
- package/src/modules/phone_calls/backend/page.meta.ts +12 -0
- package/src/modules/phone_calls/backend/page.tsx +303 -0
- package/src/modules/phone_calls/commands/calls.ts +156 -0
- package/src/modules/phone_calls/commands/index.ts +1 -0
- package/src/modules/phone_calls/data/entities.ts +144 -0
- package/src/modules/phone_calls/data/validators.ts +69 -0
- package/src/modules/phone_calls/di.ts +10 -0
- package/src/modules/phone_calls/encryption.ts +26 -0
- package/src/modules/phone_calls/events.ts +25 -0
- package/src/modules/phone_calls/i18n/de.json +42 -0
- package/src/modules/phone_calls/i18n/en.json +42 -0
- package/src/modules/phone_calls/i18n/es.json +42 -0
- package/src/modules/phone_calls/i18n/ko.json +42 -0
- package/src/modules/phone_calls/i18n/pl.json +42 -0
- package/src/modules/phone_calls/index.ts +13 -0
- package/src/modules/phone_calls/migrations/.snapshot-open-mercato.json +772 -0
- package/src/modules/phone_calls/migrations/Migration20260706124120_phone_calls.ts +23 -0
- package/src/modules/phone_calls/migrations/Migration20260814124333_phone_calls.ts +13 -0
- package/src/modules/phone_calls/setup.ts +14 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { registerCommand } from "@open-mercato/shared/lib/commands";
|
|
2
|
+
import { emitCrudSideEffects } from "@open-mercato/shared/lib/commands/helpers";
|
|
3
|
+
import { withAtomicFlush } from "@open-mercato/shared/lib/commands/flush";
|
|
4
|
+
import { ensureOrganizationScope, ensureTenantScope } from "@open-mercato/shared/lib/commands/scope";
|
|
5
|
+
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
|
|
6
|
+
import { PHONE_CALL_RESOURCE_KIND } from "@open-mercato/shared/modules/phone_calls/types";
|
|
7
|
+
import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
|
|
8
|
+
import { E } from "../../../generated/entities.ids.generated.js";
|
|
9
|
+
import { PhoneCall, PhoneCallParticipant } from "../data/entities.js";
|
|
10
|
+
import {
|
|
11
|
+
ingestPhoneCallSchema
|
|
12
|
+
} from "../data/validators.js";
|
|
13
|
+
import { emitPhoneCallsEvent } from "../events.js";
|
|
14
|
+
const PHONE_CALLS_CALL_INGEST_COMMAND_ID = "phone_calls.call.ingest";
|
|
15
|
+
const phoneCallCrudIndexer = {
|
|
16
|
+
entityType: E.phone_calls.phone_call
|
|
17
|
+
};
|
|
18
|
+
const PHONE_CALL_CACHE_ALIASES = [PhoneCall.name];
|
|
19
|
+
function applyScalarFields(call, input, ingestedAt) {
|
|
20
|
+
call.integrationId = input.integrationId ?? null;
|
|
21
|
+
call.externalConversationId = input.externalConversationId ?? null;
|
|
22
|
+
call.direction = input.direction;
|
|
23
|
+
call.status = input.status;
|
|
24
|
+
call.startedAt = input.startedAt ?? null;
|
|
25
|
+
call.answeredAt = input.answeredAt ?? null;
|
|
26
|
+
call.endedAt = input.endedAt ?? null;
|
|
27
|
+
call.durationSeconds = input.durationSeconds ?? null;
|
|
28
|
+
call.recordingUrl = input.recording?.url ?? null;
|
|
29
|
+
call.providerFacts = input.providerFacts ?? null;
|
|
30
|
+
call.rawSnapshot = input.rawPayload;
|
|
31
|
+
call.ingestStatus = "complete";
|
|
32
|
+
call.lastIngestedAt = ingestedAt;
|
|
33
|
+
}
|
|
34
|
+
async function syncParticipants(em, call, input) {
|
|
35
|
+
await em.nativeDelete(PhoneCallParticipant, { phoneCallId: call.id });
|
|
36
|
+
for (const participant of input.participants) {
|
|
37
|
+
em.persist(em.create(PhoneCallParticipant, {
|
|
38
|
+
organizationId: call.organizationId,
|
|
39
|
+
tenantId: call.tenantId,
|
|
40
|
+
phoneCallId: call.id,
|
|
41
|
+
providerParticipantId: participant.providerParticipantId ?? null,
|
|
42
|
+
role: participant.role,
|
|
43
|
+
phoneNumber: participant.phoneNumber ?? null,
|
|
44
|
+
displayName: participant.displayName ?? null,
|
|
45
|
+
email: participant.email ?? null,
|
|
46
|
+
metadata: participant.metadata ?? null
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const ingestPhoneCallCommand = {
|
|
51
|
+
id: PHONE_CALLS_CALL_INGEST_COMMAND_ID,
|
|
52
|
+
async execute(rawInput, ctx) {
|
|
53
|
+
const input = ingestPhoneCallSchema.parse(rawInput);
|
|
54
|
+
ensureTenantScope(ctx, input.tenantId);
|
|
55
|
+
ensureOrganizationScope(ctx, input.organizationId);
|
|
56
|
+
const em = ctx.container.resolve("em").fork();
|
|
57
|
+
const existing = await findOneWithDecryption(
|
|
58
|
+
em,
|
|
59
|
+
PhoneCall,
|
|
60
|
+
{
|
|
61
|
+
providerKey: input.providerKey,
|
|
62
|
+
externalCallId: input.externalCallId,
|
|
63
|
+
tenantId: input.tenantId,
|
|
64
|
+
organizationId: input.organizationId
|
|
65
|
+
},
|
|
66
|
+
void 0,
|
|
67
|
+
{ tenantId: input.tenantId, organizationId: input.organizationId }
|
|
68
|
+
);
|
|
69
|
+
const created = !existing;
|
|
70
|
+
const call = existing ?? em.create(PhoneCall, {
|
|
71
|
+
organizationId: input.organizationId,
|
|
72
|
+
tenantId: input.tenantId,
|
|
73
|
+
providerKey: input.providerKey,
|
|
74
|
+
externalCallId: input.externalCallId,
|
|
75
|
+
direction: input.direction,
|
|
76
|
+
status: input.status
|
|
77
|
+
});
|
|
78
|
+
if (created) em.persist(call);
|
|
79
|
+
const ingestedAt = /* @__PURE__ */ new Date();
|
|
80
|
+
await withAtomicFlush(
|
|
81
|
+
em,
|
|
82
|
+
[
|
|
83
|
+
() => applyScalarFields(call, input, ingestedAt),
|
|
84
|
+
() => syncParticipants(em, call, input)
|
|
85
|
+
],
|
|
86
|
+
{ transaction: true, label: PHONE_CALLS_CALL_INGEST_COMMAND_ID }
|
|
87
|
+
);
|
|
88
|
+
await emitCrudSideEffects({
|
|
89
|
+
dataEngine: ctx.container.resolve("dataEngine"),
|
|
90
|
+
action: created ? "created" : "updated",
|
|
91
|
+
entity: call,
|
|
92
|
+
identifiers: {
|
|
93
|
+
id: call.id,
|
|
94
|
+
organizationId: call.organizationId,
|
|
95
|
+
tenantId: call.tenantId
|
|
96
|
+
},
|
|
97
|
+
indexer: phoneCallCrudIndexer
|
|
98
|
+
});
|
|
99
|
+
await emitPhoneCallsEvent(
|
|
100
|
+
created ? "phone_calls.call.ingested" : "phone_calls.call.updated",
|
|
101
|
+
{ id: call.id, organizationId: call.organizationId, tenantId: call.tenantId }
|
|
102
|
+
).catch(() => void 0);
|
|
103
|
+
return { phoneCallId: call.id, created };
|
|
104
|
+
},
|
|
105
|
+
// Calls carry PII (numbers, names, recordings), so the audit entry stays at identifiers
|
|
106
|
+
// and the ingest outcome. No snapshot, and the command is not undoable.
|
|
107
|
+
buildLog: async ({ input, result }) => {
|
|
108
|
+
const { translate } = await resolveTranslations();
|
|
109
|
+
return {
|
|
110
|
+
actionLabel: result.created ? translate("phone_calls.audit.calls.ingested", "Ingest phone call") : translate("phone_calls.audit.calls.updated", "Update ingested phone call"),
|
|
111
|
+
resourceKind: PHONE_CALL_RESOURCE_KIND,
|
|
112
|
+
resourceId: result.phoneCallId,
|
|
113
|
+
tenantId: input.tenantId,
|
|
114
|
+
organizationId: input.organizationId,
|
|
115
|
+
context: { cacheAliases: PHONE_CALL_CACHE_ALIASES }
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
registerCommand(ingestPhoneCallCommand);
|
|
120
|
+
export {
|
|
121
|
+
PHONE_CALLS_CALL_INGEST_COMMAND_ID,
|
|
122
|
+
PHONE_CALL_RESOURCE_KIND,
|
|
123
|
+
ingestPhoneCallCommand
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=calls.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/phone_calls/commands/calls.ts"],
|
|
4
|
+
"sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { emitCrudSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport { ensureOrganizationScope, ensureTenantScope } from '@open-mercato/shared/lib/commands/scope'\nimport type { CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { PHONE_CALL_RESOURCE_KIND } from '@open-mercato/shared/modules/phone_calls/types'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { E } from '#generated/entities.ids.generated'\nimport { PhoneCall, PhoneCallParticipant } from '../data/entities'\nimport {\n ingestPhoneCallSchema,\n type IngestPhoneCallInput,\n} from '../data/validators'\nimport { emitPhoneCallsEvent } from '../events'\n\nexport const PHONE_CALLS_CALL_INGEST_COMMAND_ID = 'phone_calls.call.ingest'\nexport { PHONE_CALL_RESOURCE_KIND }\n\nconst phoneCallCrudIndexer: CrudIndexerConfig<PhoneCall> = {\n entityType: E.phone_calls.phone_call,\n}\n\n// The list route derives its cache tag from the entity class name, and the tag the bus\n// derives from this command id is a different one, so without the alias the cached list\n// pages survive an ingest.\nconst PHONE_CALL_CACHE_ALIASES = [PhoneCall.name]\n\nexport type IngestPhoneCallResult = { phoneCallId: string; created: boolean }\n\nfunction applyScalarFields(call: PhoneCall, input: IngestPhoneCallInput, ingestedAt: Date): void {\n call.integrationId = input.integrationId ?? null\n call.externalConversationId = input.externalConversationId ?? null\n call.direction = input.direction\n call.status = input.status\n call.startedAt = input.startedAt ?? null\n call.answeredAt = input.answeredAt ?? null\n call.endedAt = input.endedAt ?? null\n call.durationSeconds = input.durationSeconds ?? null\n call.recordingUrl = input.recording?.url ?? null\n call.providerFacts = input.providerFacts ?? null\n call.rawSnapshot = input.rawPayload\n call.ingestStatus = 'complete'\n call.lastIngestedAt = ingestedAt\n}\n\nasync function syncParticipants(\n em: EntityManager,\n call: PhoneCall,\n input: IngestPhoneCallInput,\n): Promise<void> {\n // Replace the whole participant set on every ingest: participants have no reliable\n // natural key (providerParticipantId/phoneNumber are often null), so a diff/upsert would\n // be guesswork. Delete-all + insert stays deterministic and idempotent. Revisit this if\n // anything starts referencing participant.id externally (re-pull rotates these ids).\n await em.nativeDelete(PhoneCallParticipant, { phoneCallId: call.id })\n for (const participant of input.participants) {\n em.persist(em.create(PhoneCallParticipant, {\n organizationId: call.organizationId,\n tenantId: call.tenantId,\n phoneCallId: call.id,\n providerParticipantId: participant.providerParticipantId ?? null,\n role: participant.role,\n phoneNumber: participant.phoneNumber ?? null,\n displayName: participant.displayName ?? null,\n email: participant.email ?? null,\n metadata: participant.metadata ?? null,\n }))\n }\n}\n\nconst ingestPhoneCallCommand: CommandHandler<IngestPhoneCallInput, IngestPhoneCallResult> = {\n id: PHONE_CALLS_CALL_INGEST_COMMAND_ID,\n async execute(rawInput, ctx) {\n const input = ingestPhoneCallSchema.parse(rawInput)\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const existing = await findOneWithDecryption(\n em,\n PhoneCall,\n {\n providerKey: input.providerKey,\n externalCallId: input.externalCallId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n },\n undefined,\n { tenantId: input.tenantId, organizationId: input.organizationId },\n )\n const created = !existing\n const call = existing ?? em.create(PhoneCall, {\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n providerKey: input.providerKey,\n externalCallId: input.externalCallId,\n direction: input.direction,\n status: input.status,\n })\n if (created) em.persist(call)\n const ingestedAt = new Date()\n\n await withAtomicFlush(\n em,\n [\n () => applyScalarFields(call, input, ingestedAt),\n () => syncParticipants(em, call, input),\n ],\n { transaction: true, label: PHONE_CALLS_CALL_INGEST_COMMAND_ID },\n )\n\n // The module emits its own declared events, so only the indexer is handed to the\n // shared side effects: the query index and the read caches have to see the write.\n await emitCrudSideEffects({\n dataEngine: ctx.container.resolve('dataEngine') as DataEngine,\n action: created ? 'created' : 'updated',\n entity: call,\n identifiers: {\n id: call.id,\n organizationId: call.organizationId,\n tenantId: call.tenantId,\n },\n indexer: phoneCallCrudIndexer,\n })\n\n await emitPhoneCallsEvent(\n created ? 'phone_calls.call.ingested' : 'phone_calls.call.updated',\n { id: call.id, organizationId: call.organizationId, tenantId: call.tenantId },\n ).catch(() => undefined)\n\n return { phoneCallId: call.id, created }\n },\n // Calls carry PII (numbers, names, recordings), so the audit entry stays at identifiers\n // and the ingest outcome. No snapshot, and the command is not undoable.\n buildLog: async ({ input, result }) => {\n const { translate } = await resolveTranslations()\n return {\n actionLabel: result.created\n ? translate('phone_calls.audit.calls.ingested', 'Ingest phone call')\n : translate('phone_calls.audit.calls.updated', 'Update ingested phone call'),\n resourceKind: PHONE_CALL_RESOURCE_KIND,\n resourceId: result.phoneCallId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n context: { cacheAliases: PHONE_CALL_CACHE_ALIASES },\n }\n },\n}\n\nregisterCommand(ingestPhoneCallCommand)\n\nexport { ingestPhoneCallCommand }\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
import { OptionalProps } from "@mikro-orm/core";
|
|
12
|
+
import { Entity, Index, ManyToOne, PrimaryKey, Property, Unique } from "@mikro-orm/decorators/legacy";
|
|
13
|
+
OptionalProps;
|
|
14
|
+
let PhoneCall = class {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.ingestStatus = "pending";
|
|
17
|
+
this.createdAt = /* @__PURE__ */ new Date();
|
|
18
|
+
this.updatedAt = /* @__PURE__ */ new Date();
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
__decorateClass([
|
|
22
|
+
PrimaryKey({ type: "uuid", defaultRaw: "gen_random_uuid()" })
|
|
23
|
+
], PhoneCall.prototype, "id", 2);
|
|
24
|
+
__decorateClass([
|
|
25
|
+
Property({ name: "organization_id", type: "uuid" })
|
|
26
|
+
], PhoneCall.prototype, "organizationId", 2);
|
|
27
|
+
__decorateClass([
|
|
28
|
+
Property({ name: "tenant_id", type: "uuid" })
|
|
29
|
+
], PhoneCall.prototype, "tenantId", 2);
|
|
30
|
+
__decorateClass([
|
|
31
|
+
Property({ name: "provider_key", type: "text" })
|
|
32
|
+
], PhoneCall.prototype, "providerKey", 2);
|
|
33
|
+
__decorateClass([
|
|
34
|
+
Property({ name: "integration_id", type: "text", nullable: true })
|
|
35
|
+
], PhoneCall.prototype, "integrationId", 2);
|
|
36
|
+
__decorateClass([
|
|
37
|
+
Property({ name: "external_call_id", type: "text" })
|
|
38
|
+
], PhoneCall.prototype, "externalCallId", 2);
|
|
39
|
+
__decorateClass([
|
|
40
|
+
Property({ name: "external_conversation_id", type: "text", nullable: true })
|
|
41
|
+
], PhoneCall.prototype, "externalConversationId", 2);
|
|
42
|
+
__decorateClass([
|
|
43
|
+
Property({ name: "direction", type: "text" })
|
|
44
|
+
], PhoneCall.prototype, "direction", 2);
|
|
45
|
+
__decorateClass([
|
|
46
|
+
Property({ name: "status", type: "text" })
|
|
47
|
+
], PhoneCall.prototype, "status", 2);
|
|
48
|
+
__decorateClass([
|
|
49
|
+
Property({ name: "started_at", type: Date, nullable: true })
|
|
50
|
+
], PhoneCall.prototype, "startedAt", 2);
|
|
51
|
+
__decorateClass([
|
|
52
|
+
Property({ name: "answered_at", type: Date, nullable: true })
|
|
53
|
+
], PhoneCall.prototype, "answeredAt", 2);
|
|
54
|
+
__decorateClass([
|
|
55
|
+
Property({ name: "ended_at", type: Date, nullable: true })
|
|
56
|
+
], PhoneCall.prototype, "endedAt", 2);
|
|
57
|
+
__decorateClass([
|
|
58
|
+
Property({ name: "duration_seconds", type: "integer", nullable: true })
|
|
59
|
+
], PhoneCall.prototype, "durationSeconds", 2);
|
|
60
|
+
__decorateClass([
|
|
61
|
+
Property({ name: "recording_url", type: "text", nullable: true })
|
|
62
|
+
], PhoneCall.prototype, "recordingUrl", 2);
|
|
63
|
+
__decorateClass([
|
|
64
|
+
Property({ name: "recording_attachment_id", type: "uuid", nullable: true })
|
|
65
|
+
], PhoneCall.prototype, "recordingAttachmentId", 2);
|
|
66
|
+
__decorateClass([
|
|
67
|
+
Property({ name: "active_transcript_version_id", type: "uuid", nullable: true })
|
|
68
|
+
], PhoneCall.prototype, "activeTranscriptVersionId", 2);
|
|
69
|
+
__decorateClass([
|
|
70
|
+
Property({ name: "active_summary_version_id", type: "uuid", nullable: true })
|
|
71
|
+
], PhoneCall.prototype, "activeSummaryVersionId", 2);
|
|
72
|
+
__decorateClass([
|
|
73
|
+
Property({ name: "communication_projection_id", type: "uuid", nullable: true })
|
|
74
|
+
], PhoneCall.prototype, "communicationProjectionId", 2);
|
|
75
|
+
__decorateClass([
|
|
76
|
+
Property({ name: "provider_facts", type: "jsonb", nullable: true })
|
|
77
|
+
], PhoneCall.prototype, "providerFacts", 2);
|
|
78
|
+
__decorateClass([
|
|
79
|
+
Property({ name: "raw_snapshot", type: "jsonb", nullable: true })
|
|
80
|
+
], PhoneCall.prototype, "rawSnapshot", 2);
|
|
81
|
+
__decorateClass([
|
|
82
|
+
Property({ name: "ingest_status", type: "text", default: "pending" })
|
|
83
|
+
], PhoneCall.prototype, "ingestStatus", 2);
|
|
84
|
+
__decorateClass([
|
|
85
|
+
Property({ name: "last_ingested_at", type: Date, nullable: true })
|
|
86
|
+
], PhoneCall.prototype, "lastIngestedAt", 2);
|
|
87
|
+
__decorateClass([
|
|
88
|
+
Property({ name: "created_at", type: Date, onCreate: () => /* @__PURE__ */ new Date() })
|
|
89
|
+
], PhoneCall.prototype, "createdAt", 2);
|
|
90
|
+
__decorateClass([
|
|
91
|
+
Property({ name: "updated_at", type: Date, onUpdate: () => /* @__PURE__ */ new Date() })
|
|
92
|
+
], PhoneCall.prototype, "updatedAt", 2);
|
|
93
|
+
__decorateClass([
|
|
94
|
+
Property({ name: "deleted_at", type: Date, nullable: true })
|
|
95
|
+
], PhoneCall.prototype, "deletedAt", 2);
|
|
96
|
+
PhoneCall = __decorateClass([
|
|
97
|
+
Entity({ tableName: "phone_calls" }),
|
|
98
|
+
Index({ name: "phone_calls_org_tenant_idx", properties: ["organizationId", "tenantId"] }),
|
|
99
|
+
Unique({
|
|
100
|
+
name: "phone_calls_provider_external_scope_uq",
|
|
101
|
+
properties: ["providerKey", "externalCallId", "tenantId", "organizationId"]
|
|
102
|
+
}),
|
|
103
|
+
Index({ name: "phone_calls_org_started_at_idx", properties: ["organizationId", "startedAt"] }),
|
|
104
|
+
Index({ name: "phone_calls_org_status_idx", properties: ["organizationId", "status"] }),
|
|
105
|
+
Index({
|
|
106
|
+
name: "phone_calls_communication_projection_id_idx",
|
|
107
|
+
expression: 'create index "phone_calls_communication_projection_id_idx" on "phone_calls" ("communication_projection_id") where "communication_projection_id" is not null'
|
|
108
|
+
})
|
|
109
|
+
], PhoneCall);
|
|
110
|
+
OptionalProps;
|
|
111
|
+
let PhoneCallParticipant = class {
|
|
112
|
+
constructor() {
|
|
113
|
+
this.createdAt = /* @__PURE__ */ new Date();
|
|
114
|
+
this.updatedAt = /* @__PURE__ */ new Date();
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
__decorateClass([
|
|
118
|
+
PrimaryKey({ type: "uuid", defaultRaw: "gen_random_uuid()" })
|
|
119
|
+
], PhoneCallParticipant.prototype, "id", 2);
|
|
120
|
+
__decorateClass([
|
|
121
|
+
Property({ name: "organization_id", type: "uuid" })
|
|
122
|
+
], PhoneCallParticipant.prototype, "organizationId", 2);
|
|
123
|
+
__decorateClass([
|
|
124
|
+
Property({ name: "tenant_id", type: "uuid" })
|
|
125
|
+
], PhoneCallParticipant.prototype, "tenantId", 2);
|
|
126
|
+
__decorateClass([
|
|
127
|
+
ManyToOne(() => PhoneCall, { fieldName: "phone_call_id", deleteRule: "cascade", mapToPk: true })
|
|
128
|
+
], PhoneCallParticipant.prototype, "phoneCallId", 2);
|
|
129
|
+
__decorateClass([
|
|
130
|
+
Property({ name: "provider_participant_id", type: "text", nullable: true })
|
|
131
|
+
], PhoneCallParticipant.prototype, "providerParticipantId", 2);
|
|
132
|
+
__decorateClass([
|
|
133
|
+
Property({ name: "role", type: "text" })
|
|
134
|
+
], PhoneCallParticipant.prototype, "role", 2);
|
|
135
|
+
__decorateClass([
|
|
136
|
+
Property({ name: "phone_number", type: "text", nullable: true })
|
|
137
|
+
], PhoneCallParticipant.prototype, "phoneNumber", 2);
|
|
138
|
+
__decorateClass([
|
|
139
|
+
Property({ name: "display_name", type: "text", nullable: true })
|
|
140
|
+
], PhoneCallParticipant.prototype, "displayName", 2);
|
|
141
|
+
__decorateClass([
|
|
142
|
+
Property({ name: "email", type: "text", nullable: true })
|
|
143
|
+
], PhoneCallParticipant.prototype, "email", 2);
|
|
144
|
+
__decorateClass([
|
|
145
|
+
Property({ name: "metadata", type: "jsonb", nullable: true })
|
|
146
|
+
], PhoneCallParticipant.prototype, "metadata", 2);
|
|
147
|
+
__decorateClass([
|
|
148
|
+
Property({ name: "created_at", type: Date, onCreate: () => /* @__PURE__ */ new Date() })
|
|
149
|
+
], PhoneCallParticipant.prototype, "createdAt", 2);
|
|
150
|
+
__decorateClass([
|
|
151
|
+
Property({ name: "updated_at", type: Date, onUpdate: () => /* @__PURE__ */ new Date() })
|
|
152
|
+
], PhoneCallParticipant.prototype, "updatedAt", 2);
|
|
153
|
+
PhoneCallParticipant = __decorateClass([
|
|
154
|
+
Entity({ tableName: "phone_call_participants" }),
|
|
155
|
+
Index({ name: "phone_call_participants_call_idx", properties: ["phoneCallId"] }),
|
|
156
|
+
Index({ name: "phone_call_participants_org_tenant_idx", properties: ["organizationId", "tenantId"] })
|
|
157
|
+
], PhoneCallParticipant);
|
|
158
|
+
export {
|
|
159
|
+
PhoneCall,
|
|
160
|
+
PhoneCallParticipant
|
|
161
|
+
};
|
|
162
|
+
//# sourceMappingURL=entities.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/phone_calls/data/entities.ts"],
|
|
4
|
+
"sourcesContent": ["import { OptionalProps } from '@mikro-orm/core'\nimport { Entity, Index, ManyToOne, PrimaryKey, Property, Unique } from '@mikro-orm/decorators/legacy'\nimport type {\n PhoneCallDirection,\n PhoneCallStatus,\n PhoneCallParticipantRole,\n} from '@open-mercato/shared/modules/phone_calls/types'\n\nexport type PhoneCallIngestStatus = 'pending' | 'complete' | 'failed'\n\n@Entity({ tableName: 'phone_calls' })\n@Index({ name: 'phone_calls_org_tenant_idx', properties: ['organizationId', 'tenantId'] })\n@Unique({\n name: 'phone_calls_provider_external_scope_uq',\n properties: ['providerKey', 'externalCallId', 'tenantId', 'organizationId'],\n})\n@Index({ name: 'phone_calls_org_started_at_idx', properties: ['organizationId', 'startedAt'] })\n@Index({ name: 'phone_calls_org_status_idx', properties: ['organizationId', 'status'] })\n@Index({\n name: 'phone_calls_communication_projection_id_idx',\n expression:\n 'create index \"phone_calls_communication_projection_id_idx\" on \"phone_calls\" (\"communication_projection_id\") where \"communication_projection_id\" is not null',\n})\nexport class PhoneCall {\n [OptionalProps]?: 'ingestStatus' | 'createdAt' | 'updatedAt' | 'deletedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'organization_id', type: 'uuid' })\n organizationId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'provider_key', type: 'text' })\n providerKey!: string\n\n @Property({ name: 'integration_id', type: 'text', nullable: true })\n integrationId?: string | null\n\n @Property({ name: 'external_call_id', type: 'text' })\n externalCallId!: string\n\n @Property({ name: 'external_conversation_id', type: 'text', nullable: true })\n externalConversationId?: string | null\n\n @Property({ name: 'direction', type: 'text' })\n direction!: PhoneCallDirection\n\n @Property({ name: 'status', type: 'text' })\n status!: PhoneCallStatus\n\n @Property({ name: 'started_at', type: Date, nullable: true })\n startedAt?: Date | null\n\n @Property({ name: 'answered_at', type: Date, nullable: true })\n answeredAt?: Date | null\n\n @Property({ name: 'ended_at', type: Date, nullable: true })\n endedAt?: Date | null\n\n @Property({ name: 'duration_seconds', type: 'integer', nullable: true })\n durationSeconds?: number | null\n\n @Property({ name: 'recording_url', type: 'text', nullable: true })\n recordingUrl?: string | null\n\n @Property({ name: 'recording_attachment_id', type: 'uuid', nullable: true })\n recordingAttachmentId?: string | null\n\n @Property({ name: 'active_transcript_version_id', type: 'uuid', nullable: true })\n activeTranscriptVersionId?: string | null\n\n @Property({ name: 'active_summary_version_id', type: 'uuid', nullable: true })\n activeSummaryVersionId?: string | null\n\n @Property({ name: 'communication_projection_id', type: 'uuid', nullable: true })\n communicationProjectionId?: string | null\n\n @Property({ name: 'provider_facts', type: 'jsonb', nullable: true })\n providerFacts?: Record<string, unknown> | null\n\n @Property({ name: 'raw_snapshot', type: 'jsonb', nullable: true })\n rawSnapshot?: Record<string, unknown> | null\n\n @Property({ name: 'ingest_status', type: 'text', default: 'pending' })\n ingestStatus: PhoneCallIngestStatus = 'pending'\n\n @Property({ name: 'last_ingested_at', type: Date, nullable: true })\n lastIngestedAt?: Date | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'phone_call_participants' })\n@Index({ name: 'phone_call_participants_call_idx', properties: ['phoneCallId'] })\n@Index({ name: 'phone_call_participants_org_tenant_idx', properties: ['organizationId', 'tenantId'] })\nexport class PhoneCallParticipant {\n [OptionalProps]?: 'createdAt' | 'updatedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'organization_id', type: 'uuid' })\n organizationId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @ManyToOne(() => PhoneCall, { fieldName: 'phone_call_id', deleteRule: 'cascade', mapToPk: true })\n phoneCallId!: string\n\n @Property({ name: 'provider_participant_id', type: 'text', nullable: true })\n providerParticipantId?: string | null\n\n @Property({ name: 'role', type: 'text' })\n role!: PhoneCallParticipantRole\n\n @Property({ name: 'phone_number', type: 'text', nullable: true })\n phoneNumber?: string | null\n\n @Property({ name: 'display_name', type: 'text', nullable: true })\n displayName?: string | null\n\n @Property({ name: 'email', type: 'text', nullable: true })\n email?: string | null\n\n @Property({ name: 'metadata', type: 'jsonb', nullable: true })\n metadata?: Record<string, unknown> | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;AAAA,SAAS,qBAAqB;AAC9B,SAAS,QAAQ,OAAO,WAAW,YAAY,UAAU,cAAc;AAuBpE;AADI,IAAM,YAAN,MAAgB;AAAA,EAAhB;AAgEL,wBAAsC;AAMtC,qBAAkB,oBAAI,KAAK;AAG3B,qBAAkB,oBAAI,KAAK;AAAA;AAI7B;AAzEE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GAHlD,UAIX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,OAAO,CAAC;AAAA,GANxC,UAOX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GATlC,UAUX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,gBAAgB,MAAM,OAAO,CAAC;AAAA,GAZrC,UAaX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,kBAAkB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAfvD,UAgBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,oBAAoB,MAAM,OAAO,CAAC;AAAA,GAlBzC,UAmBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,4BAA4B,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GArBjE,UAsBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GAxBlC,UAyBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,UAAU,MAAM,OAAO,CAAC;AAAA,GA3B/B,UA4BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GA9BjD,UA+BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,eAAe,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GAjClD,UAkCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GApC/C,UAqCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,oBAAoB,MAAM,WAAW,UAAU,KAAK,CAAC;AAAA,GAvC5D,UAwCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,iBAAiB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GA1CtD,UA2CX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,2BAA2B,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GA7ChE,UA8CX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,gCAAgC,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAhDrE,UAiDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,6BAA6B,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAnDlE,UAoDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,+BAA+B,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAtDpE,UAuDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,kBAAkB,MAAM,SAAS,UAAU,KAAK,CAAC;AAAA,GAzDxD,UA0DX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,gBAAgB,MAAM,SAAS,UAAU,KAAK,CAAC;AAAA,GA5DtD,UA6DX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,iBAAiB,MAAM,QAAQ,SAAS,UAAU,CAAC;AAAA,GA/D1D,UAgEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,oBAAoB,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GAlEvD,UAmEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GArE7D,UAsEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAxE7D,UAyEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GA3EjD,UA4EX;AA5EW,YAAN;AAAA,EAbN,OAAO,EAAE,WAAW,cAAc,CAAC;AAAA,EACnC,MAAM,EAAE,MAAM,8BAA8B,YAAY,CAAC,kBAAkB,UAAU,EAAE,CAAC;AAAA,EACxF,OAAO;AAAA,IACN,MAAM;AAAA,IACN,YAAY,CAAC,eAAe,kBAAkB,YAAY,gBAAgB;AAAA,EAC5E,CAAC;AAAA,EACA,MAAM,EAAE,MAAM,kCAAkC,YAAY,CAAC,kBAAkB,WAAW,EAAE,CAAC;AAAA,EAC7F,MAAM,EAAE,MAAM,8BAA8B,YAAY,CAAC,kBAAkB,QAAQ,EAAE,CAAC;AAAA,EACtF,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,GACY;AAmFV;AADI,IAAM,uBAAN,MAA2B;AAAA,EAA3B;AAkCL,qBAAkB,oBAAI,KAAK;AAG3B,qBAAkB,oBAAI,KAAK;AAAA;AAC7B;AAlCE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GAHlD,qBAIX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,OAAO,CAAC;AAAA,GANxC,qBAOX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GATlC,qBAUX;AAGA;AAAA,EADC,UAAU,MAAM,WAAW,EAAE,WAAW,iBAAiB,YAAY,WAAW,SAAS,KAAK,CAAC;AAAA,GAZrF,qBAaX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,2BAA2B,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAfhE,qBAgBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC;AAAA,GAlB7B,qBAmBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,gBAAgB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GArBrD,qBAsBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,gBAAgB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAxBrD,qBAyBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GA3B9C,qBA4BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,SAAS,UAAU,KAAK,CAAC;AAAA,GA9BlD,qBA+BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAjC7D,qBAkCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GApC7D,qBAqCX;AArCW,uBAAN;AAAA,EAHN,OAAO,EAAE,WAAW,0BAA0B,CAAC;AAAA,EAC/C,MAAM,EAAE,MAAM,oCAAoC,YAAY,CAAC,aAAa,EAAE,CAAC;AAAA,EAC/E,MAAM,EAAE,MAAM,0CAA0C,YAAY,CAAC,kBAAkB,UAAU,EAAE,CAAC;AAAA,GACxF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const uuid = () => z.string().uuid();
|
|
3
|
+
const scopedSchema = z.object({
|
|
4
|
+
organizationId: uuid(),
|
|
5
|
+
tenantId: uuid()
|
|
6
|
+
});
|
|
7
|
+
const phoneCallDirectionSchema = z.enum([
|
|
8
|
+
"inbound",
|
|
9
|
+
"outbound",
|
|
10
|
+
"internal",
|
|
11
|
+
"unknown"
|
|
12
|
+
]);
|
|
13
|
+
const phoneCallStatusSchema = z.enum([
|
|
14
|
+
"new",
|
|
15
|
+
"ringing",
|
|
16
|
+
"answered",
|
|
17
|
+
"missed",
|
|
18
|
+
"failed",
|
|
19
|
+
"completed",
|
|
20
|
+
"unknown"
|
|
21
|
+
]);
|
|
22
|
+
const phoneCallParticipantRoleSchema = z.enum([
|
|
23
|
+
"caller",
|
|
24
|
+
"callee",
|
|
25
|
+
"agent",
|
|
26
|
+
"unknown"
|
|
27
|
+
]);
|
|
28
|
+
const ingestParticipantSchema = z.object({
|
|
29
|
+
role: phoneCallParticipantRoleSchema,
|
|
30
|
+
providerParticipantId: z.string().nullish(),
|
|
31
|
+
phoneNumber: z.string().nullish(),
|
|
32
|
+
displayName: z.string().nullish(),
|
|
33
|
+
email: z.string().nullish(),
|
|
34
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
35
|
+
});
|
|
36
|
+
const ingestRecordingSchema = z.object({
|
|
37
|
+
url: z.string().nullish(),
|
|
38
|
+
providerRecordingId: z.string().nullish(),
|
|
39
|
+
mimeType: z.string().nullish(),
|
|
40
|
+
durationSeconds: z.number().int().nullish(),
|
|
41
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
42
|
+
});
|
|
43
|
+
const ingestPhoneCallSchema = scopedSchema.extend({
|
|
44
|
+
providerKey: z.string().min(1),
|
|
45
|
+
integrationId: z.string().nullish(),
|
|
46
|
+
externalCallId: z.string().min(1),
|
|
47
|
+
externalConversationId: z.string().nullish(),
|
|
48
|
+
direction: phoneCallDirectionSchema,
|
|
49
|
+
status: phoneCallStatusSchema,
|
|
50
|
+
participants: z.array(ingestParticipantSchema).default([]),
|
|
51
|
+
recording: ingestRecordingSchema.nullish(),
|
|
52
|
+
startedAt: z.coerce.date().nullish(),
|
|
53
|
+
answeredAt: z.coerce.date().nullish(),
|
|
54
|
+
endedAt: z.coerce.date().nullish(),
|
|
55
|
+
durationSeconds: z.number().int().nullish(),
|
|
56
|
+
providerFacts: z.record(z.string(), z.unknown()).optional(),
|
|
57
|
+
rawPayload: z.record(z.string(), z.unknown())
|
|
58
|
+
});
|
|
59
|
+
export {
|
|
60
|
+
ingestParticipantSchema,
|
|
61
|
+
ingestPhoneCallSchema,
|
|
62
|
+
ingestRecordingSchema,
|
|
63
|
+
phoneCallDirectionSchema,
|
|
64
|
+
phoneCallParticipantRoleSchema,
|
|
65
|
+
phoneCallStatusSchema,
|
|
66
|
+
scopedSchema
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/phone_calls/data/validators.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\n\nconst uuid = () => z.string().uuid()\n\nexport const scopedSchema = z.object({\n organizationId: uuid(),\n tenantId: uuid(),\n})\n\nexport const phoneCallDirectionSchema = z.enum([\n 'inbound',\n 'outbound',\n 'internal',\n 'unknown',\n])\n\nexport const phoneCallStatusSchema = z.enum([\n 'new',\n 'ringing',\n 'answered',\n 'missed',\n 'failed',\n 'completed',\n 'unknown',\n])\n\nexport const phoneCallParticipantRoleSchema = z.enum([\n 'caller',\n 'callee',\n 'agent',\n 'unknown',\n])\n\nexport const ingestParticipantSchema = z.object({\n role: phoneCallParticipantRoleSchema,\n providerParticipantId: z.string().nullish(),\n phoneNumber: z.string().nullish(),\n displayName: z.string().nullish(),\n email: z.string().nullish(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const ingestRecordingSchema = z.object({\n url: z.string().nullish(),\n providerRecordingId: z.string().nullish(),\n mimeType: z.string().nullish(),\n durationSeconds: z.number().int().nullish(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const ingestPhoneCallSchema = scopedSchema.extend({\n providerKey: z.string().min(1),\n integrationId: z.string().nullish(),\n externalCallId: z.string().min(1),\n externalConversationId: z.string().nullish(),\n direction: phoneCallDirectionSchema,\n status: phoneCallStatusSchema,\n participants: z.array(ingestParticipantSchema).default([]),\n recording: ingestRecordingSchema.nullish(),\n startedAt: z.coerce.date().nullish(),\n answeredAt: z.coerce.date().nullish(),\n endedAt: z.coerce.date().nullish(),\n durationSeconds: z.number().int().nullish(),\n providerFacts: z.record(z.string(), z.unknown()).optional(),\n rawPayload: z.record(z.string(), z.unknown()),\n})\n\nexport type IngestPhoneCallInput = z.infer<typeof ingestPhoneCallSchema>\nexport type IngestParticipantInput = z.infer<typeof ingestParticipantSchema>\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS;AAElB,MAAM,OAAO,MAAM,EAAE,OAAO,EAAE,KAAK;AAE5B,MAAM,eAAe,EAAE,OAAO;AAAA,EACnC,gBAAgB,KAAK;AAAA,EACrB,UAAU,KAAK;AACjB,CAAC;AAEM,MAAM,2BAA2B,EAAE,KAAK;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,MAAM,wBAAwB,EAAE,KAAK;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,MAAM,iCAAiC,EAAE,KAAK;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,MAAM,0BAA0B,EAAE,OAAO;AAAA,EAC9C,MAAM;AAAA,EACN,uBAAuB,EAAE,OAAO,EAAE,QAAQ;AAAA,EAC1C,aAAa,EAAE,OAAO,EAAE,QAAQ;AAAA,EAChC,aAAa,EAAE,OAAO,EAAE,QAAQ;AAAA,EAChC,OAAO,EAAE,OAAO,EAAE,QAAQ;AAAA,EAC1B,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AACvD,CAAC;AAEM,MAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,KAAK,EAAE,OAAO,EAAE,QAAQ;AAAA,EACxB,qBAAqB,EAAE,OAAO,EAAE,QAAQ;AAAA,EACxC,UAAU,EAAE,OAAO,EAAE,QAAQ;AAAA,EAC7B,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ;AAAA,EAC1C,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AACvD,CAAC;AAEM,MAAM,wBAAwB,aAAa,OAAO;AAAA,EACvD,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,eAAe,EAAE,OAAO,EAAE,QAAQ;AAAA,EAClC,gBAAgB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAChC,wBAAwB,EAAE,OAAO,EAAE,QAAQ;AAAA,EAC3C,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,cAAc,EAAE,MAAM,uBAAuB,EAAE,QAAQ,CAAC,CAAC;AAAA,EACzD,WAAW,sBAAsB,QAAQ;AAAA,EACzC,WAAW,EAAE,OAAO,KAAK,EAAE,QAAQ;AAAA,EACnC,YAAY,EAAE,OAAO,KAAK,EAAE,QAAQ;AAAA,EACpC,SAAS,EAAE,OAAO,KAAK,EAAE,QAAQ;AAAA,EACjC,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ;AAAA,EAC1C,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EAC1D,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAC9C,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { asValue } from "awilix";
|
|
2
|
+
import { PhoneCall, PhoneCallParticipant } from "./data/entities.js";
|
|
3
|
+
function register(container) {
|
|
4
|
+
container.register({
|
|
5
|
+
PhoneCall: asValue(PhoneCall),
|
|
6
|
+
PhoneCallParticipant: asValue(PhoneCallParticipant)
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
register
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=di.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/phone_calls/di.ts"],
|
|
4
|
+
"sourcesContent": ["import { asValue } from 'awilix'\nimport type { AppContainer } from '@open-mercato/shared/lib/di/container'\nimport { PhoneCall, PhoneCallParticipant } from './data/entities'\n\nexport function register(container: AppContainer) {\n container.register({\n PhoneCall: asValue(PhoneCall),\n PhoneCallParticipant: asValue(PhoneCallParticipant),\n })\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,eAAe;AAExB,SAAS,WAAW,4BAA4B;AAEzC,SAAS,SAAS,WAAyB;AAChD,YAAU,SAAS;AAAA,IACjB,WAAW,QAAQ,SAAS;AAAA,IAC5B,sBAAsB,QAAQ,oBAAoB;AAAA,EACpD,CAAC;AACH;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const defaultEncryptionMaps = [
|
|
2
|
+
{
|
|
3
|
+
entityId: "phone_calls:phone_call",
|
|
4
|
+
fields: [
|
|
5
|
+
// raw_snapshot and provider_facts hold the untouched Tillio payload, which
|
|
6
|
+
// carries caller/destination numbers (PII) that we already encrypt on the
|
|
7
|
+
// participant. recording_url points at the call recording. QueryEngine
|
|
8
|
+
// decrypts these transparently on read.
|
|
9
|
+
{ field: "raw_snapshot" },
|
|
10
|
+
{ field: "provider_facts" },
|
|
11
|
+
{ field: "recording_url" }
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
entityId: "phone_calls:phone_call_participant",
|
|
16
|
+
fields: [
|
|
17
|
+
{ field: "phone_number" },
|
|
18
|
+
{ field: "display_name" },
|
|
19
|
+
{ field: "email" }
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
];
|
|
23
|
+
var encryption_default = defaultEncryptionMaps;
|
|
24
|
+
export {
|
|
25
|
+
encryption_default as default,
|
|
26
|
+
defaultEncryptionMaps
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=encryption.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/phone_calls/encryption.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ModuleEncryptionMap } from '@open-mercato/shared/modules/encryption'\n\nexport const defaultEncryptionMaps: ModuleEncryptionMap[] = [\n {\n entityId: 'phone_calls:phone_call',\n fields: [\n // raw_snapshot and provider_facts hold the untouched Tillio payload, which\n // carries caller/destination numbers (PII) that we already encrypt on the\n // participant. recording_url points at the call recording. QueryEngine\n // decrypts these transparently on read.\n { field: 'raw_snapshot' },\n { field: 'provider_facts' },\n { field: 'recording_url' },\n ],\n },\n {\n entityId: 'phone_calls:phone_call_participant',\n fields: [\n { field: 'phone_number' },\n { field: 'display_name' },\n { field: 'email' },\n ],\n },\n]\n\nexport default defaultEncryptionMaps\n"],
|
|
5
|
+
"mappings": "AAEO,MAAM,wBAA+C;AAAA,EAC1D;AAAA,IACE,UAAU;AAAA,IACV,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,MAKN,EAAE,OAAO,eAAe;AAAA,MACxB,EAAE,OAAO,iBAAiB;AAAA,MAC1B,EAAE,OAAO,gBAAgB;AAAA,IAC3B;AAAA,EACF;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,QAAQ;AAAA,MACN,EAAE,OAAO,eAAe;AAAA,MACxB,EAAE,OAAO,eAAe;AAAA,MACxB,EAAE,OAAO,QAAQ;AAAA,IACnB;AAAA,EACF;AACF;AAEA,IAAO,qBAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createModuleEvents } from "@open-mercato/shared/modules/events";
|
|
2
|
+
const events = [
|
|
3
|
+
{ id: "phone_calls.call.ingested", label: "Phone Call Ingested", entity: "call", category: "crud" },
|
|
4
|
+
{ id: "phone_calls.call.updated", label: "Phone Call Updated", entity: "call", category: "crud" },
|
|
5
|
+
{ id: "phone_calls.call.ingest_failed", label: "Phone Call Ingest Failed", entity: "call", category: "crud" }
|
|
6
|
+
];
|
|
7
|
+
const eventsConfig = createModuleEvents({
|
|
8
|
+
moduleId: "phone_calls",
|
|
9
|
+
events
|
|
10
|
+
});
|
|
11
|
+
const emitPhoneCallsEvent = eventsConfig.emit;
|
|
12
|
+
var events_default = eventsConfig;
|
|
13
|
+
export {
|
|
14
|
+
events_default as default,
|
|
15
|
+
emitPhoneCallsEvent,
|
|
16
|
+
eventsConfig
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/phone_calls/events.ts"],
|
|
4
|
+
"sourcesContent": ["import { createModuleEvents } from '@open-mercato/shared/modules/events'\n\n/**\n * Phone Calls Module Events\n *\n * Declares all events that can be emitted by the phone_calls module.\n */\nconst events = [\n { id: 'phone_calls.call.ingested', label: 'Phone Call Ingested', entity: 'call', category: 'crud' },\n { id: 'phone_calls.call.updated', label: 'Phone Call Updated', entity: 'call', category: 'crud' },\n { id: 'phone_calls.call.ingest_failed', label: 'Phone Call Ingest Failed', entity: 'call', category: 'crud' },\n] as const\n\nexport const eventsConfig = createModuleEvents({\n moduleId: 'phone_calls',\n events,\n})\n\n/** Type-safe event emitter for phone_calls module */\nexport const emitPhoneCallsEvent = eventsConfig.emit\n\n/** Event IDs that can be emitted by the phone_calls module */\nexport type PhoneCallsEventId = typeof events[number]['id']\n\nexport default eventsConfig\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,0BAA0B;AAOnC,MAAM,SAAS;AAAA,EACb,EAAE,IAAI,6BAA6B,OAAO,uBAAuB,QAAQ,QAAQ,UAAU,OAAO;AAAA,EAClG,EAAE,IAAI,4BAA4B,OAAO,sBAAsB,QAAQ,QAAQ,UAAU,OAAO;AAAA,EAChG,EAAE,IAAI,kCAAkC,OAAO,4BAA4B,QAAQ,QAAQ,UAAU,OAAO;AAC9G;AAEO,MAAM,eAAe,mBAAmB;AAAA,EAC7C,UAAU;AAAA,EACV;AACF,CAAC;AAGM,MAAM,sBAAsB,aAAa;AAKhD,IAAO,iBAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const metadata = {
|
|
2
|
+
name: "phone_calls",
|
|
3
|
+
title: "Phone Calls",
|
|
4
|
+
version: "0.1.0",
|
|
5
|
+
description: "Provider-neutral core hub for ingesting and browsing phone calls.",
|
|
6
|
+
author: "Open Mercato Team",
|
|
7
|
+
license: "MIT",
|
|
8
|
+
ejectable: true
|
|
9
|
+
};
|
|
10
|
+
import { features } from "./acl.js";
|
|
11
|
+
export {
|
|
12
|
+
features,
|
|
13
|
+
metadata
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/phone_calls/index.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ModuleInfo } from '@open-mercato/shared/modules/registry'\n\nexport const metadata: ModuleInfo = {\n name: 'phone_calls',\n title: 'Phone Calls',\n version: '0.1.0',\n description: 'Provider-neutral core hub for ingesting and browsing phone calls.',\n author: 'Open Mercato Team',\n license: 'MIT',\n ejectable: true,\n}\n\nexport { features } from './acl'\n"],
|
|
5
|
+
"mappings": "AAEO,MAAM,WAAuB;AAAA,EAClC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EACT,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,WAAW;AACb;AAEA,SAAS,gBAAgB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Migration } from "@mikro-orm/migrations";
|
|
2
|
+
class Migration20260706124120_phone_calls extends Migration {
|
|
3
|
+
up() {
|
|
4
|
+
this.addSql(`create table "phone_calls" ("id" uuid not null default gen_random_uuid(), "organization_id" uuid not null, "tenant_id" uuid not null, "provider_key" text not null, "integration_id" text null, "external_call_id" text not null, "external_conversation_id" text null, "direction" text not null, "status" text not null, "started_at" timestamptz null, "answered_at" timestamptz null, "ended_at" timestamptz null, "duration_seconds" int null, "recording_url" text null, "recording_attachment_id" uuid null, "active_transcript_version_id" uuid null, "active_summary_version_id" uuid null, "communication_projection_id" uuid null, "provider_facts" jsonb null, "raw_snapshot" jsonb null, "ingest_status" text not null default 'pending', "last_ingested_at" timestamptz null, "created_at" timestamptz not null, "updated_at" timestamptz not null, "deleted_at" timestamptz null, primary key ("id"));`);
|
|
5
|
+
this.addSql(`create index "phone_calls_communication_projection_id_idx" on "phone_calls" ("communication_projection_id") where "communication_projection_id" is not null;`);
|
|
6
|
+
this.addSql(`create index "phone_calls_org_status_idx" on "phone_calls" ("organization_id", "status");`);
|
|
7
|
+
this.addSql(`create index "phone_calls_org_started_at_idx" on "phone_calls" ("organization_id", "started_at");`);
|
|
8
|
+
this.addSql(`create index "phone_calls_org_tenant_idx" on "phone_calls" ("organization_id", "tenant_id");`);
|
|
9
|
+
this.addSql(`alter table "phone_calls" add constraint "phone_calls_provider_external_scope_uq" unique ("provider_key", "external_call_id", "tenant_id", "organization_id");`);
|
|
10
|
+
this.addSql(`create table "phone_call_participants" ("id" uuid not null default gen_random_uuid(), "organization_id" uuid not null, "tenant_id" uuid not null, "phone_call_id" uuid not null, "provider_participant_id" text null, "role" text not null, "phone_number" text null, "display_name" text null, "email" text null, "metadata" jsonb null, "created_at" timestamptz not null, "updated_at" timestamptz not null, primary key ("id"));`);
|
|
11
|
+
this.addSql(`create index "phone_call_participants_org_tenant_idx" on "phone_call_participants" ("organization_id", "tenant_id");`);
|
|
12
|
+
this.addSql(`create index "phone_call_participants_call_idx" on "phone_call_participants" ("phone_call_id");`);
|
|
13
|
+
}
|
|
14
|
+
down() {
|
|
15
|
+
this.addSql(`drop table if exists "phone_call_participants";`);
|
|
16
|
+
this.addSql(`drop table if exists "phone_calls";`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
Migration20260706124120_phone_calls
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=Migration20260706124120_phone_calls.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/phone_calls/migrations/Migration20260706124120_phone_calls.ts"],
|
|
4
|
+
"sourcesContent": ["import { Migration } from '@mikro-orm/migrations';\n\nexport class Migration20260706124120_phone_calls extends Migration {\n\n override up(): void | Promise<void> {\n this.addSql(`create table \"phone_calls\" (\"id\" uuid not null default gen_random_uuid(), \"organization_id\" uuid not null, \"tenant_id\" uuid not null, \"provider_key\" text not null, \"integration_id\" text null, \"external_call_id\" text not null, \"external_conversation_id\" text null, \"direction\" text not null, \"status\" text not null, \"started_at\" timestamptz null, \"answered_at\" timestamptz null, \"ended_at\" timestamptz null, \"duration_seconds\" int null, \"recording_url\" text null, \"recording_attachment_id\" uuid null, \"active_transcript_version_id\" uuid null, \"active_summary_version_id\" uuid null, \"communication_projection_id\" uuid null, \"provider_facts\" jsonb null, \"raw_snapshot\" jsonb null, \"ingest_status\" text not null default 'pending', \"last_ingested_at\" timestamptz null, \"created_at\" timestamptz not null, \"updated_at\" timestamptz not null, \"deleted_at\" timestamptz null, primary key (\"id\"));`);\n this.addSql(`create index \"phone_calls_communication_projection_id_idx\" on \"phone_calls\" (\"communication_projection_id\") where \"communication_projection_id\" is not null;`);\n this.addSql(`create index \"phone_calls_org_status_idx\" on \"phone_calls\" (\"organization_id\", \"status\");`);\n this.addSql(`create index \"phone_calls_org_started_at_idx\" on \"phone_calls\" (\"organization_id\", \"started_at\");`);\n this.addSql(`create index \"phone_calls_org_tenant_idx\" on \"phone_calls\" (\"organization_id\", \"tenant_id\");`);\n this.addSql(`alter table \"phone_calls\" add constraint \"phone_calls_provider_external_scope_uq\" unique (\"provider_key\", \"external_call_id\", \"tenant_id\", \"organization_id\");`);\n\n this.addSql(`create table \"phone_call_participants\" (\"id\" uuid not null default gen_random_uuid(), \"organization_id\" uuid not null, \"tenant_id\" uuid not null, \"phone_call_id\" uuid not null, \"provider_participant_id\" text null, \"role\" text not null, \"phone_number\" text null, \"display_name\" text null, \"email\" text null, \"metadata\" jsonb null, \"created_at\" timestamptz not null, \"updated_at\" timestamptz not null, primary key (\"id\"));`);\n this.addSql(`create index \"phone_call_participants_org_tenant_idx\" on \"phone_call_participants\" (\"organization_id\", \"tenant_id\");`);\n this.addSql(`create index \"phone_call_participants_call_idx\" on \"phone_call_participants\" (\"phone_call_id\");`);\n }\n\n override down(): void | Promise<void> {\n this.addSql(`drop table if exists \"phone_call_participants\";`);\n this.addSql(`drop table if exists \"phone_calls\";`);\n }\n\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,iBAAiB;AAEnB,MAAM,4CAA4C,UAAU;AAAA,EAExD,KAA2B;AAClC,SAAK,OAAO,u3BAAu3B;AACn4B,SAAK,OAAO,8JAA8J;AAC1K,SAAK,OAAO,2FAA2F;AACvG,SAAK,OAAO,mGAAmG;AAC/G,SAAK,OAAO,8FAA8F;AAC1G,SAAK,OAAO,gKAAgK;AAE5K,SAAK,OAAO,saAAsa;AAClb,SAAK,OAAO,sHAAsH;AAClI,SAAK,OAAO,iGAAiG;AAAA,EAC/G;AAAA,EAES,OAA6B;AACpC,SAAK,OAAO,iDAAiD;AAC7D,SAAK,OAAO,qCAAqC;AAAA,EACnD;AAEF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Migration } from "@mikro-orm/migrations";
|
|
2
|
+
class Migration20260814124333_phone_calls extends Migration {
|
|
3
|
+
up() {
|
|
4
|
+
this.addSql(`alter table "phone_call_participants" add constraint "phone_call_participants_phone_call_id_foreign" foreign key ("phone_call_id") references "phone_calls" ("id") on delete cascade;`);
|
|
5
|
+
}
|
|
6
|
+
down() {
|
|
7
|
+
this.addSql(`alter table "phone_call_participants" drop constraint if exists "phone_call_participants_phone_call_id_foreign";`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
Migration20260814124333_phone_calls
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=Migration20260814124333_phone_calls.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/phone_calls/migrations/Migration20260814124333_phone_calls.ts"],
|
|
4
|
+
"sourcesContent": ["import { Migration } from '@mikro-orm/migrations';\n\nexport class Migration20260814124333_phone_calls extends Migration {\n\n override up(): void | Promise<void> {\n this.addSql(`alter table \"phone_call_participants\" add constraint \"phone_call_participants_phone_call_id_foreign\" foreign key (\"phone_call_id\") references \"phone_calls\" (\"id\") on delete cascade;`);\n }\n\n override down(): void | Promise<void> {\n this.addSql(`alter table \"phone_call_participants\" drop constraint if exists \"phone_call_participants_phone_call_id_foreign\";`);\n }\n\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,iBAAiB;AAEnB,MAAM,4CAA4C,UAAU;AAAA,EAExD,KAA2B;AAClC,SAAK,OAAO,uLAAuL;AAAA,EACrM;AAAA,EAES,OAA6B;AACpC,SAAK,OAAO,kHAAkH;AAAA,EAChI;AAEF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|