eggi-ai-db-schema-2 12.54.2
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/CHANGELOG.md +750 -0
- package/README.md +655 -0
- package/dist/config/database.d.ts +28 -0
- package/dist/config/database.d.ts.map +1 -0
- package/dist/config/database.js +72 -0
- package/dist/config/database.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +199 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/database-service.d.ts +689 -0
- package/dist/lib/database-service.d.ts.map +1 -0
- package/dist/lib/database-service.js +1362 -0
- package/dist/lib/database-service.js.map +1 -0
- package/dist/lib/db-types.d.ts +167 -0
- package/dist/lib/db-types.d.ts.map +1 -0
- package/dist/lib/db-types.js +28 -0
- package/dist/lib/db-types.js.map +1 -0
- package/dist/lib/db.d.ts +58 -0
- package/dist/lib/db.d.ts.map +1 -0
- package/dist/lib/db.js +292 -0
- package/dist/lib/db.js.map +1 -0
- package/dist/lib/index.d.ts +11 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +26 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/pg-client.d.ts +50 -0
- package/dist/lib/pg-client.d.ts.map +1 -0
- package/dist/lib/pg-client.js +106 -0
- package/dist/lib/pg-client.js.map +1 -0
- package/dist/lib/schema.d.ts +298 -0
- package/dist/lib/schema.d.ts.map +1 -0
- package/dist/lib/schema.js +12 -0
- package/dist/lib/schema.js.map +1 -0
- package/dist/migration-manager.d.ts +49 -0
- package/dist/migration-manager.d.ts.map +1 -0
- package/dist/migration-manager.js +282 -0
- package/dist/migration-manager.js.map +1 -0
- package/dist/queries/minimal-connections.d.ts +31 -0
- package/dist/queries/minimal-connections.d.ts.map +1 -0
- package/dist/queries/minimal-connections.js +143 -0
- package/dist/queries/minimal-connections.js.map +1 -0
- package/dist/schema.ts +340 -0
- package/dist/seed.d.ts +8 -0
- package/dist/seed.d.ts.map +1 -0
- package/dist/seed.js +40 -0
- package/dist/seed.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +23 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/types.d.ts +77 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +3 -0
- package/dist/types/types.js.map +1 -0
- package/dist/utils/authenticated-user-operations.d.ts +110 -0
- package/dist/utils/authenticated-user-operations.d.ts.map +1 -0
- package/dist/utils/authenticated-user-operations.js +292 -0
- package/dist/utils/authenticated-user-operations.js.map +1 -0
- package/dist/utils/authentication-operations.d.ts +48 -0
- package/dist/utils/authentication-operations.d.ts.map +1 -0
- package/dist/utils/authentication-operations.js +172 -0
- package/dist/utils/authentication-operations.js.map +1 -0
- package/dist/utils/company-mapping-job-operations.d.ts +103 -0
- package/dist/utils/company-mapping-job-operations.d.ts.map +1 -0
- package/dist/utils/company-mapping-job-operations.js +413 -0
- package/dist/utils/company-mapping-job-operations.js.map +1 -0
- package/dist/utils/company-sheet-upload-operations.d.ts +53 -0
- package/dist/utils/company-sheet-upload-operations.d.ts.map +1 -0
- package/dist/utils/company-sheet-upload-operations.js +135 -0
- package/dist/utils/company-sheet-upload-operations.js.map +1 -0
- package/dist/utils/contact-operations.d.ts +70 -0
- package/dist/utils/contact-operations.d.ts.map +1 -0
- package/dist/utils/contact-operations.js +294 -0
- package/dist/utils/contact-operations.js.map +1 -0
- package/dist/utils/forager-linkedin-operations.d.ts +74 -0
- package/dist/utils/forager-linkedin-operations.d.ts.map +1 -0
- package/dist/utils/forager-linkedin-operations.js +778 -0
- package/dist/utils/forager-linkedin-operations.js.map +1 -0
- package/dist/utils/ghost-genius-linkedin-operations.d.ts +23 -0
- package/dist/utils/ghost-genius-linkedin-operations.d.ts.map +1 -0
- package/dist/utils/ghost-genius-linkedin-operations.js +282 -0
- package/dist/utils/ghost-genius-linkedin-operations.js.map +1 -0
- package/dist/utils/index.d.ts +29 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +77 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/introduction-request-operations.d.ts +159 -0
- package/dist/utils/introduction-request-operations.d.ts.map +1 -0
- package/dist/utils/introduction-request-operations.js +481 -0
- package/dist/utils/introduction-request-operations.js.map +1 -0
- package/dist/utils/invitation-operations.d.ts +141 -0
- package/dist/utils/invitation-operations.d.ts.map +1 -0
- package/dist/utils/invitation-operations.js +749 -0
- package/dist/utils/invitation-operations.js.map +1 -0
- package/dist/utils/linkedin-account-operations.d.ts +45 -0
- package/dist/utils/linkedin-account-operations.d.ts.map +1 -0
- package/dist/utils/linkedin-account-operations.js +279 -0
- package/dist/utils/linkedin-account-operations.js.map +1 -0
- package/dist/utils/linkedin-account-relationship-operations.d.ts +77 -0
- package/dist/utils/linkedin-account-relationship-operations.d.ts.map +1 -0
- package/dist/utils/linkedin-account-relationship-operations.js +274 -0
- package/dist/utils/linkedin-account-relationship-operations.js.map +1 -0
- package/dist/utils/linkedin-data-operations.d.ts +102 -0
- package/dist/utils/linkedin-data-operations.d.ts.map +1 -0
- package/dist/utils/linkedin-data-operations.js +613 -0
- package/dist/utils/linkedin-data-operations.js.map +1 -0
- package/dist/utils/linkedin-identifier-utils.d.ts +31 -0
- package/dist/utils/linkedin-identifier-utils.d.ts.map +1 -0
- package/dist/utils/linkedin-identifier-utils.js +63 -0
- package/dist/utils/linkedin-identifier-utils.js.map +1 -0
- package/dist/utils/linkedin-profile-cache.d.ts +131 -0
- package/dist/utils/linkedin-profile-cache.d.ts.map +1 -0
- package/dist/utils/linkedin-profile-cache.js +418 -0
- package/dist/utils/linkedin-profile-cache.js.map +1 -0
- package/dist/utils/llm-inference-job-operations.d.ts +116 -0
- package/dist/utils/llm-inference-job-operations.d.ts.map +1 -0
- package/dist/utils/llm-inference-job-operations.js +266 -0
- package/dist/utils/llm-inference-job-operations.js.map +1 -0
- package/dist/utils/mapping-job-operations.d.ts +272 -0
- package/dist/utils/mapping-job-operations.d.ts.map +1 -0
- package/dist/utils/mapping-job-operations.js +833 -0
- package/dist/utils/mapping-job-operations.js.map +1 -0
- package/dist/utils/mapping-operations.d.ts +80 -0
- package/dist/utils/mapping-operations.d.ts.map +1 -0
- package/dist/utils/mapping-operations.js +318 -0
- package/dist/utils/mapping-operations.js.map +1 -0
- package/dist/utils/on-demand-mapping-operations.d.ts +199 -0
- package/dist/utils/on-demand-mapping-operations.d.ts.map +1 -0
- package/dist/utils/on-demand-mapping-operations.js +728 -0
- package/dist/utils/on-demand-mapping-operations.js.map +1 -0
- package/dist/utils/onboarding-operations.d.ts +53 -0
- package/dist/utils/onboarding-operations.d.ts.map +1 -0
- package/dist/utils/onboarding-operations.js +223 -0
- package/dist/utils/onboarding-operations.js.map +1 -0
- package/dist/utils/organization-assignment-job-operations.d.ts +258 -0
- package/dist/utils/organization-assignment-job-operations.d.ts.map +1 -0
- package/dist/utils/organization-assignment-job-operations.js +881 -0
- package/dist/utils/organization-assignment-job-operations.js.map +1 -0
- package/dist/utils/organization-assignment-operations.d.ts +59 -0
- package/dist/utils/organization-assignment-operations.d.ts.map +1 -0
- package/dist/utils/organization-assignment-operations.js +130 -0
- package/dist/utils/organization-assignment-operations.js.map +1 -0
- package/dist/utils/organization-operations.d.ts +275 -0
- package/dist/utils/organization-operations.d.ts.map +1 -0
- package/dist/utils/organization-operations.js +993 -0
- package/dist/utils/organization-operations.js.map +1 -0
- package/dist/utils/organization-relationship-operations.d.ts +59 -0
- package/dist/utils/organization-relationship-operations.d.ts.map +1 -0
- package/dist/utils/organization-relationship-operations.js +240 -0
- package/dist/utils/organization-relationship-operations.js.map +1 -0
- package/dist/utils/quota-operations.d.ts +107 -0
- package/dist/utils/quota-operations.d.ts.map +1 -0
- package/dist/utils/quota-operations.js +692 -0
- package/dist/utils/quota-operations.js.map +1 -0
- package/dist/utils/recursive-mapping-job-operations.d.ts +42 -0
- package/dist/utils/recursive-mapping-job-operations.d.ts.map +1 -0
- package/dist/utils/recursive-mapping-job-operations.js +169 -0
- package/dist/utils/recursive-mapping-job-operations.js.map +1 -0
- package/dist/utils/relationship-operations.d.ts +130 -0
- package/dist/utils/relationship-operations.d.ts.map +1 -0
- package/dist/utils/relationship-operations.js +329 -0
- package/dist/utils/relationship-operations.js.map +1 -0
- package/dist/utils/sales-pipeline-operations.d.ts +143 -0
- package/dist/utils/sales-pipeline-operations.d.ts.map +1 -0
- package/dist/utils/sales-pipeline-operations.js +649 -0
- package/dist/utils/sales-pipeline-operations.js.map +1 -0
- package/dist/utils/skills-operations.d.ts +117 -0
- package/dist/utils/skills-operations.d.ts.map +1 -0
- package/dist/utils/skills-operations.js +487 -0
- package/dist/utils/skills-operations.js.map +1 -0
- package/dist/utils/subscription-operations.d.ts +123 -0
- package/dist/utils/subscription-operations.d.ts.map +1 -0
- package/dist/utils/subscription-operations.js +391 -0
- package/dist/utils/subscription-operations.js.map +1 -0
- package/dist/utils/unipile-account-operations.d.ts +96 -0
- package/dist/utils/unipile-account-operations.d.ts.map +1 -0
- package/dist/utils/unipile-account-operations.js +255 -0
- package/dist/utils/unipile-account-operations.js.map +1 -0
- package/dist/utils/user-industry-operations.d.ts +80 -0
- package/dist/utils/user-industry-operations.d.ts.map +1 -0
- package/dist/utils/user-industry-operations.js +237 -0
- package/dist/utils/user-industry-operations.js.map +1 -0
- package/dist/utils/user-operations.d.ts +87 -0
- package/dist/utils/user-operations.d.ts.map +1 -0
- package/dist/utils/user-operations.js +212 -0
- package/dist/utils/user-operations.js.map +1 -0
- package/package.json +98 -0
|
@@ -0,0 +1,728 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* =============================================================================
|
|
4
|
+
* ON-DEMAND MAPPING OPERATIONS UTILITIES - CONSOLIDATED SCHEMA
|
|
5
|
+
* =============================================================================
|
|
6
|
+
* Utility functions for creating and managing on-demand mapping jobs from Chrome extension
|
|
7
|
+
* Updated to work with the new consolidated linkedin.accounts schema
|
|
8
|
+
*
|
|
9
|
+
* USAGE EXAMPLES:
|
|
10
|
+
*
|
|
11
|
+
* 1. CREATE ON-DEMAND REQUEST:
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const request = await createOnDemandMappingJob({
|
|
14
|
+
* requesterLinkedinAccountId: 123,
|
|
15
|
+
* internalIdentifierAcoa: "ACoAABCDEFG...", // Target ACoA identifier
|
|
16
|
+
* metadata: {
|
|
17
|
+
* source: "chrome_extension",
|
|
18
|
+
* user_agent: "Mozilla/5.0...",
|
|
19
|
+
* requested_by: "user_456"
|
|
20
|
+
* }
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* 2. GET REQUEST WITH STATUS:
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const requestWithStatus = await getOnDemandMappingJobWithStatus(123, "ACoAABCDEFG...");
|
|
27
|
+
* // Returns: { id, mappingJobId, status: "completed", progress: 100, ... }
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* 3. UPDATE MAPPING JOB ASSOCIATION:
|
|
31
|
+
* ```typescript
|
|
32
|
+
* await updateOnDemandMappingJobId(123, "ACoAABCDEFG...", 789);
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.createOnDemandMappingJob = createOnDemandMappingJob;
|
|
37
|
+
exports.getOnDemandMappingJob = getOnDemandMappingJob;
|
|
38
|
+
exports.getOnDemandMappingJobById = getOnDemandMappingJobById;
|
|
39
|
+
exports.getOnDemandMappingJobWithStatus = getOnDemandMappingJobWithStatus;
|
|
40
|
+
exports.updateOnDemandMappingJobId = updateOnDemandMappingJobId;
|
|
41
|
+
exports.getOnDemandMappingJobsMinimal = getOnDemandMappingJobsMinimal;
|
|
42
|
+
exports.getPendingOnDemandMappingJobs = getPendingOnDemandMappingJobs;
|
|
43
|
+
exports.checkOnDemandMappingJobExists = checkOnDemandMappingJobExists;
|
|
44
|
+
exports.getOrCreateOnDemandMappingJob = getOrCreateOnDemandMappingJob;
|
|
45
|
+
exports.getTargetLinkedInAccountIdForOnDemandJobInOrganization = getTargetLinkedInAccountIdForOnDemandJobInOrganization;
|
|
46
|
+
exports.deleteOnDemandMappingJob = deleteOnDemandMappingJob;
|
|
47
|
+
exports.getRelationshipScoresForOnDemandJob = getRelationshipScoresForOnDemandJob;
|
|
48
|
+
const pg_client_1 = require("../lib/pg-client");
|
|
49
|
+
const db_1 = require("../lib/db");
|
|
50
|
+
const database_service_1 = require("../lib/database-service");
|
|
51
|
+
// =============================================================================
|
|
52
|
+
// CORE OPERATIONS
|
|
53
|
+
// =============================================================================
|
|
54
|
+
/**
|
|
55
|
+
* Create a new on-demand mapping job
|
|
56
|
+
*/
|
|
57
|
+
async function createOnDemandMappingJob(params) {
|
|
58
|
+
const { requesterLinkedinAccountId, internalIdentifierAcoa, metadata = {} } = params;
|
|
59
|
+
(0, db_1.debugLogDbOperation)("insert", "monitoring.on_demand_mapping_jobs", { requesterLinkedinAccountId, internalIdentifierAcoa }, undefined, {
|
|
60
|
+
operation: "createOnDemandMappingJob",
|
|
61
|
+
requesterLinkedinAccountId,
|
|
62
|
+
internalIdentifierAcoa,
|
|
63
|
+
});
|
|
64
|
+
try {
|
|
65
|
+
// Verify requester LinkedIn account exists
|
|
66
|
+
const db = await database_service_1.dbService.getDb();
|
|
67
|
+
const requesterSql = `SELECT id FROM linkedin.accounts WHERE id = $1 LIMIT 1`;
|
|
68
|
+
const requesterAccount = await (0, pg_client_1.queryOne)(db, requesterSql, [
|
|
69
|
+
requesterLinkedinAccountId,
|
|
70
|
+
]);
|
|
71
|
+
if (!requesterAccount) {
|
|
72
|
+
throw new Error(`Requester LinkedIn account with ID ${requesterLinkedinAccountId} not found`);
|
|
73
|
+
}
|
|
74
|
+
// Create the on-demand mapping job
|
|
75
|
+
const insertSql = `
|
|
76
|
+
INSERT INTO monitoring.on_demand_mapping_jobs (
|
|
77
|
+
requester_linkedin_account_id, internal_identifier_acoa, metadata, created_at, updated_at
|
|
78
|
+
)
|
|
79
|
+
VALUES ($1, $2, $3, NOW(), NOW())
|
|
80
|
+
RETURNING id, requester_linkedin_account_id, internal_identifier_acoa, mapping_job_id, metadata, created_at, updated_at
|
|
81
|
+
`;
|
|
82
|
+
const onDemandJob = await (0, pg_client_1.queryOne)(db, insertSql, [
|
|
83
|
+
requesterLinkedinAccountId,
|
|
84
|
+
internalIdentifierAcoa,
|
|
85
|
+
JSON.stringify(metadata),
|
|
86
|
+
]);
|
|
87
|
+
if (!onDemandJob) {
|
|
88
|
+
throw new Error("Failed to create on-demand mapping job");
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
id: onDemandJob.id,
|
|
92
|
+
requesterLinkedinAccountId: onDemandJob.requester_linkedin_account_id,
|
|
93
|
+
internalIdentifierAcoa: onDemandJob.internal_identifier_acoa,
|
|
94
|
+
mappingJobId: onDemandJob.mapping_job_id,
|
|
95
|
+
metadata: onDemandJob.metadata,
|
|
96
|
+
createdAt: onDemandJob.created_at,
|
|
97
|
+
updatedAt: onDemandJob.updated_at,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
console.error("Error creating on-demand mapping job:", error);
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get on-demand mapping job by requester and target identifiers
|
|
107
|
+
*/
|
|
108
|
+
async function getOnDemandMappingJob(requesterLinkedinAccountId, internalIdentifierAcoa) {
|
|
109
|
+
(0, db_1.debugLogDbOperation)("select", "monitoring.on_demand_mapping_jobs", { requesterLinkedinAccountId, internalIdentifierAcoa }, undefined, {
|
|
110
|
+
operation: "getOnDemandMappingJob",
|
|
111
|
+
requesterLinkedinAccountId,
|
|
112
|
+
internalIdentifierAcoa,
|
|
113
|
+
});
|
|
114
|
+
try {
|
|
115
|
+
const db = await database_service_1.dbService.getDb();
|
|
116
|
+
const sql = `
|
|
117
|
+
SELECT id, requester_linkedin_account_id, internal_identifier_acoa, mapping_job_id, metadata, created_at, updated_at
|
|
118
|
+
FROM monitoring.on_demand_mapping_jobs
|
|
119
|
+
WHERE requester_linkedin_account_id = $1 AND internal_identifier_acoa = $2
|
|
120
|
+
LIMIT 1
|
|
121
|
+
`;
|
|
122
|
+
const result = await (0, pg_client_1.queryOne)(db, sql, [requesterLinkedinAccountId, internalIdentifierAcoa]);
|
|
123
|
+
if (!result)
|
|
124
|
+
return null;
|
|
125
|
+
return {
|
|
126
|
+
id: result.id,
|
|
127
|
+
requesterLinkedinAccountId: result.requester_linkedin_account_id,
|
|
128
|
+
internalIdentifierAcoa: result.internal_identifier_acoa,
|
|
129
|
+
mappingJobId: result.mapping_job_id,
|
|
130
|
+
metadata: result.metadata,
|
|
131
|
+
createdAt: result.created_at,
|
|
132
|
+
updatedAt: result.updated_at,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
console.error("Error getting on-demand mapping job:", error);
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get on-demand mapping job by ID
|
|
142
|
+
*/
|
|
143
|
+
async function getOnDemandMappingJobById(jobId) {
|
|
144
|
+
(0, db_1.debugLogDbOperation)("select", "monitoring.on_demand_mapping_jobs", { jobId }, undefined, {
|
|
145
|
+
operation: "getOnDemandMappingJobById",
|
|
146
|
+
jobId,
|
|
147
|
+
});
|
|
148
|
+
try {
|
|
149
|
+
const db = await database_service_1.dbService.getDb();
|
|
150
|
+
const sql = `
|
|
151
|
+
SELECT id, requester_linkedin_account_id, internal_identifier_acoa, mapping_job_id, metadata, created_at, updated_at
|
|
152
|
+
FROM monitoring.on_demand_mapping_jobs
|
|
153
|
+
WHERE id = $1
|
|
154
|
+
LIMIT 1
|
|
155
|
+
`;
|
|
156
|
+
const result = await (0, pg_client_1.queryOne)(db, sql, [jobId]);
|
|
157
|
+
if (!result)
|
|
158
|
+
return null;
|
|
159
|
+
return {
|
|
160
|
+
id: result.id,
|
|
161
|
+
requesterLinkedinAccountId: result.requester_linkedin_account_id,
|
|
162
|
+
internalIdentifierAcoa: result.internal_identifier_acoa,
|
|
163
|
+
mappingJobId: result.mapping_job_id,
|
|
164
|
+
metadata: result.metadata,
|
|
165
|
+
createdAt: result.created_at,
|
|
166
|
+
updatedAt: result.updated_at,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
console.error("Error getting on-demand mapping job by ID:", error);
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Get on-demand mapping job with complete status information
|
|
176
|
+
*/
|
|
177
|
+
async function getOnDemandMappingJobWithStatus(requesterLinkedinAccountId, internalIdentifierAcoa) {
|
|
178
|
+
(0, db_1.debugLogDbOperation)("select", "monitoring.on_demand_mapping_jobs + status", { requesterLinkedinAccountId, internalIdentifierAcoa }, undefined, {
|
|
179
|
+
operation: "getOnDemandMappingJobWithStatus",
|
|
180
|
+
requesterLinkedinAccountId,
|
|
181
|
+
internalIdentifierAcoa,
|
|
182
|
+
});
|
|
183
|
+
try {
|
|
184
|
+
const db = await database_service_1.dbService.getDb();
|
|
185
|
+
// Get the on-demand job with requester details
|
|
186
|
+
const jobSql = `
|
|
187
|
+
SELECT
|
|
188
|
+
odmj.id, odmj.requester_linkedin_account_id, odmj.internal_identifier_acoa,
|
|
189
|
+
odmj.mapping_job_id, odmj.created_at, odmj.updated_at, odmj.metadata,
|
|
190
|
+
la.linkedin_identifier_acoa as requester_linkedin_identifier
|
|
191
|
+
FROM monitoring.on_demand_mapping_jobs odmj
|
|
192
|
+
INNER JOIN linkedin.accounts la ON odmj.requester_linkedin_account_id = la.id
|
|
193
|
+
WHERE odmj.requester_linkedin_account_id = $1 AND odmj.internal_identifier_acoa = $2
|
|
194
|
+
LIMIT 1
|
|
195
|
+
`;
|
|
196
|
+
const job = await (0, pg_client_1.queryOne)(db, jobSql, [requesterLinkedinAccountId, internalIdentifierAcoa]);
|
|
197
|
+
if (!job) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
// Determine status and get mapping job details if available
|
|
201
|
+
let status = "pending";
|
|
202
|
+
let progress = 0;
|
|
203
|
+
let mappingJobDetails;
|
|
204
|
+
let linkedinRelationshipsCount = 0;
|
|
205
|
+
if (job.mapping_job_id) {
|
|
206
|
+
// Get mapping job details
|
|
207
|
+
const mappingJobSql = `
|
|
208
|
+
SELECT created_at, queued_at, started_at, completed_at, metadata
|
|
209
|
+
FROM monitoring.mapping_jobs
|
|
210
|
+
WHERE id = $1
|
|
211
|
+
LIMIT 1
|
|
212
|
+
`;
|
|
213
|
+
const mappingJob = await (0, pg_client_1.queryOne)(db, mappingJobSql, [job.mapping_job_id]);
|
|
214
|
+
if (mappingJob) {
|
|
215
|
+
mappingJobDetails = {
|
|
216
|
+
createdAt: mappingJob.created_at,
|
|
217
|
+
queuedAt: mappingJob.queued_at,
|
|
218
|
+
startedAt: mappingJob.started_at ?? undefined,
|
|
219
|
+
completedAt: mappingJob.completed_at ?? undefined,
|
|
220
|
+
metadata: mappingJob.metadata,
|
|
221
|
+
};
|
|
222
|
+
// Determine status based on mapping job state
|
|
223
|
+
if (mappingJob.completed_at) {
|
|
224
|
+
status = "completed";
|
|
225
|
+
progress = 100;
|
|
226
|
+
}
|
|
227
|
+
else if (mappingJob.started_at) {
|
|
228
|
+
status = "processing";
|
|
229
|
+
progress = 50; // Estimate - could be refined with more detailed progress tracking
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
status = "queued";
|
|
233
|
+
progress = 10;
|
|
234
|
+
}
|
|
235
|
+
// Get relationship scores count for completed jobs
|
|
236
|
+
if (status === "completed") {
|
|
237
|
+
const countSql = `SELECT COUNT(*) as count FROM linkedin.relationships WHERE mapping_job_id = $1`;
|
|
238
|
+
const scoresCount = await (0, pg_client_1.queryOne)(db, countSql, [
|
|
239
|
+
job.mapping_job_id,
|
|
240
|
+
]);
|
|
241
|
+
linkedinRelationshipsCount = parseInt(scoresCount?.count || "0");
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return {
|
|
246
|
+
id: job.id,
|
|
247
|
+
requesterLinkedinAccountId: job.requester_linkedin_account_id,
|
|
248
|
+
internalIdentifierAcoa: job.internal_identifier_acoa,
|
|
249
|
+
mappingJobId: job.mapping_job_id,
|
|
250
|
+
createdAt: job.created_at,
|
|
251
|
+
updatedAt: job.updated_at,
|
|
252
|
+
metadata: job.metadata,
|
|
253
|
+
status,
|
|
254
|
+
progress,
|
|
255
|
+
requesterLinkedInIdentifier: job.requester_linkedin_identifier || undefined,
|
|
256
|
+
targetLinkedInIdentifier: job.internal_identifier_acoa,
|
|
257
|
+
mappingJobDetails,
|
|
258
|
+
linkedinRelationshipsCount,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
console.error("Error getting on-demand mapping job with status:", error);
|
|
263
|
+
throw error;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Update the mapping job ID for an on-demand mapping job
|
|
268
|
+
*/
|
|
269
|
+
async function updateOnDemandMappingJobId(requesterLinkedinAccountId, internalIdentifierAcoa, mappingJobId) {
|
|
270
|
+
(0, db_1.debugLogDbOperation)("update", "monitoring.on_demand_mapping_jobs", { requesterLinkedinAccountId, internalIdentifierAcoa, mappingJobId }, undefined, {
|
|
271
|
+
operation: "updateOnDemandMappingJobId",
|
|
272
|
+
requesterLinkedinAccountId,
|
|
273
|
+
internalIdentifierAcoa,
|
|
274
|
+
mappingJobId,
|
|
275
|
+
});
|
|
276
|
+
try {
|
|
277
|
+
const db = await database_service_1.dbService.getDb();
|
|
278
|
+
const sql = `
|
|
279
|
+
UPDATE monitoring.on_demand_mapping_jobs
|
|
280
|
+
SET mapping_job_id = $1, updated_at = NOW()
|
|
281
|
+
WHERE requester_linkedin_account_id = $2 AND internal_identifier_acoa = $3
|
|
282
|
+
RETURNING id, requester_linkedin_account_id, internal_identifier_acoa, mapping_job_id, metadata, created_at, updated_at
|
|
283
|
+
`;
|
|
284
|
+
const updatedJob = await (0, pg_client_1.queryOne)(db, sql, [mappingJobId, requesterLinkedinAccountId, internalIdentifierAcoa]);
|
|
285
|
+
if (!updatedJob) {
|
|
286
|
+
throw new Error(`On-demand mapping job for requester ${requesterLinkedinAccountId} and target ${internalIdentifierAcoa} not found`);
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
id: updatedJob.id,
|
|
290
|
+
requesterLinkedinAccountId: updatedJob.requester_linkedin_account_id,
|
|
291
|
+
internalIdentifierAcoa: updatedJob.internal_identifier_acoa,
|
|
292
|
+
mappingJobId: updatedJob.mapping_job_id,
|
|
293
|
+
metadata: updatedJob.metadata,
|
|
294
|
+
createdAt: updatedJob.created_at,
|
|
295
|
+
updatedAt: updatedJob.updated_at,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
console.error("Error updating on-demand mapping job ID:", error);
|
|
300
|
+
throw error;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Get minimal on-demand mapping jobs for Chrome extension with pagination
|
|
305
|
+
* Excludes large metadata blocks to reduce response size
|
|
306
|
+
* Includes self-targeting jobs (where requester maps themselves)
|
|
307
|
+
*/
|
|
308
|
+
async function getOnDemandMappingJobsMinimal(db, requesterLinkedinAccountId, limit = 50, offset = 0) {
|
|
309
|
+
(0, db_1.debugLogDbOperation)("select", "monitoring.on_demand_mapping_jobs (minimal with pagination)", { requesterLinkedinAccountId, limit, offset }, undefined, {
|
|
310
|
+
operation: "getOnDemandMappingJobsMinimal",
|
|
311
|
+
requesterLinkedinAccountId,
|
|
312
|
+
});
|
|
313
|
+
try {
|
|
314
|
+
// Get the total count (including self-targeting jobs)
|
|
315
|
+
const countSql = `
|
|
316
|
+
SELECT COUNT(*) as count FROM monitoring.on_demand_mapping_jobs
|
|
317
|
+
WHERE requester_linkedin_account_id = $1
|
|
318
|
+
`;
|
|
319
|
+
const totalCountResult = await (0, pg_client_1.queryOne)(db, countSql, [
|
|
320
|
+
requesterLinkedinAccountId,
|
|
321
|
+
]);
|
|
322
|
+
const total_items = parseInt(totalCountResult?.count || "0");
|
|
323
|
+
// Get paginated on-demand jobs for the requester with minimal data
|
|
324
|
+
const jobsSql = `
|
|
325
|
+
SELECT id, requester_linkedin_account_id, internal_identifier_acoa, mapping_job_id, created_at, updated_at
|
|
326
|
+
FROM monitoring.on_demand_mapping_jobs
|
|
327
|
+
WHERE requester_linkedin_account_id = $1
|
|
328
|
+
ORDER BY created_at DESC
|
|
329
|
+
LIMIT $2 OFFSET $3
|
|
330
|
+
`;
|
|
331
|
+
const jobs = await (0, pg_client_1.query)(db, jobsSql, [requesterLinkedinAccountId, limit, offset]);
|
|
332
|
+
// Get minimal status for each job
|
|
333
|
+
const jobsWithMinimalStatus = await Promise.all(jobs.map(async (job) => {
|
|
334
|
+
let status = "pending";
|
|
335
|
+
let progress = 0;
|
|
336
|
+
let mappingJobDetails;
|
|
337
|
+
let linkedinRelationshipsCount;
|
|
338
|
+
if (job.mapping_job_id) {
|
|
339
|
+
// Get minimal mapping job details (no large metadata)
|
|
340
|
+
const mappingJobSql = `
|
|
341
|
+
SELECT id, created_at, queued_at, started_at, completed_at, metadata
|
|
342
|
+
FROM monitoring.mapping_jobs
|
|
343
|
+
WHERE id = $1
|
|
344
|
+
LIMIT 1
|
|
345
|
+
`;
|
|
346
|
+
const mappingJob = await (0, pg_client_1.queryOne)(db, mappingJobSql, [job.mapping_job_id]);
|
|
347
|
+
if (mappingJob) {
|
|
348
|
+
// Determine status from mapping job timestamps, not metadata
|
|
349
|
+
// Mapping jobs don't store status in metadata - it's determined by timestamps
|
|
350
|
+
if (mappingJob.completed_at) {
|
|
351
|
+
status = "completed";
|
|
352
|
+
progress = 100;
|
|
353
|
+
}
|
|
354
|
+
else if (mappingJob.started_at) {
|
|
355
|
+
status = "processing";
|
|
356
|
+
progress = 50; // Estimate 50% when started
|
|
357
|
+
}
|
|
358
|
+
else if (mappingJob.queued_at) {
|
|
359
|
+
status = "queued";
|
|
360
|
+
progress = 10; // Estimate 10% when queued
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
status = "pending";
|
|
364
|
+
progress = 0;
|
|
365
|
+
}
|
|
366
|
+
// Only include timing info, no large metadata blocks
|
|
367
|
+
mappingJobDetails = {
|
|
368
|
+
createdAt: mappingJob.created_at,
|
|
369
|
+
queuedAt: mappingJob.queued_at || undefined,
|
|
370
|
+
startedAt: mappingJob.started_at || undefined,
|
|
371
|
+
completedAt: mappingJob.completed_at || undefined,
|
|
372
|
+
};
|
|
373
|
+
// Get relationship scores count if completed
|
|
374
|
+
if (status === "completed") {
|
|
375
|
+
const scores = await getRelationshipScoresForOnDemandJob(job.requester_linkedin_account_id, job.internal_identifier_acoa);
|
|
376
|
+
linkedinRelationshipsCount = scores.length.toString();
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
// Get organization assignment job status if mapping job is completed
|
|
381
|
+
let organizationAssignmentStatus = null;
|
|
382
|
+
let organizationAssignmentJobDetails = null;
|
|
383
|
+
let organizations = null;
|
|
384
|
+
if (status === "completed" && job.mapping_job_id) {
|
|
385
|
+
try {
|
|
386
|
+
// Query ALL organization assignment jobs for this mapping job (can be multiple)
|
|
387
|
+
const orgAssignmentSql = `
|
|
388
|
+
SELECT
|
|
389
|
+
oaj.id,
|
|
390
|
+
oaj.created_at,
|
|
391
|
+
oaj.started_at,
|
|
392
|
+
oaj.completed_at,
|
|
393
|
+
oaj.organization_id,
|
|
394
|
+
o.name as organization_name,
|
|
395
|
+
o.workspace_type
|
|
396
|
+
FROM monitoring.organization_assignment_jobs oaj
|
|
397
|
+
INNER JOIN public.organizations o ON oaj.organization_id = o.id
|
|
398
|
+
WHERE oaj.mapping_job_id = $1
|
|
399
|
+
ORDER BY oaj.created_at DESC
|
|
400
|
+
`;
|
|
401
|
+
const orgAssignmentJobs = await (0, pg_client_1.query)(db, orgAssignmentSql, [job.mapping_job_id]);
|
|
402
|
+
if (orgAssignmentJobs && orgAssignmentJobs.length > 0) {
|
|
403
|
+
// Get the most recent organization assignment job for status
|
|
404
|
+
const latestOrgAssignmentJob = orgAssignmentJobs[0];
|
|
405
|
+
// Determine status based on latest job
|
|
406
|
+
if (latestOrgAssignmentJob.completed_at) {
|
|
407
|
+
organizationAssignmentStatus = "completed";
|
|
408
|
+
}
|
|
409
|
+
else if (latestOrgAssignmentJob.started_at) {
|
|
410
|
+
organizationAssignmentStatus = "processing";
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
organizationAssignmentStatus = "queued";
|
|
414
|
+
}
|
|
415
|
+
// Use the latest job for details
|
|
416
|
+
organizationAssignmentJobDetails = {
|
|
417
|
+
id: latestOrgAssignmentJob.id,
|
|
418
|
+
createdAt: latestOrgAssignmentJob.created_at,
|
|
419
|
+
startedAt: latestOrgAssignmentJob.started_at || undefined,
|
|
420
|
+
completedAt: latestOrgAssignmentJob.completed_at || undefined,
|
|
421
|
+
};
|
|
422
|
+
// Collect all unique organizations this job was exported to
|
|
423
|
+
const uniqueOrgs = new Map();
|
|
424
|
+
for (const orgJob of orgAssignmentJobs) {
|
|
425
|
+
if (!uniqueOrgs.has(orgJob.organization_id)) {
|
|
426
|
+
uniqueOrgs.set(orgJob.organization_id, {
|
|
427
|
+
id: orgJob.organization_id,
|
|
428
|
+
name: orgJob.organization_name,
|
|
429
|
+
workspaceType: orgJob.workspace_type,
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
organizations = Array.from(uniqueOrgs.values()).map(org => ({
|
|
434
|
+
id: org.id,
|
|
435
|
+
name: org.name,
|
|
436
|
+
workspaceType: org.workspaceType,
|
|
437
|
+
}));
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
// Mapping job completed but no organization assignment job yet
|
|
441
|
+
organizationAssignmentStatus = "pending";
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
catch (orgAssignmentError) {
|
|
445
|
+
// If organization assignment job query fails, log but continue
|
|
446
|
+
console.warn("Failed to fetch organization assignment job:", orgAssignmentError);
|
|
447
|
+
// If mapping job is completed but we can't find org assignment job, assume pending
|
|
448
|
+
if (status === "completed") {
|
|
449
|
+
organizationAssignmentStatus = "pending";
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
// Fetch profile details for the target LinkedIn identifier
|
|
454
|
+
// internal_identifier_acoa contains the ACoA identifier, we need to get the public identifier
|
|
455
|
+
let targetLinkedInIdentifier = job.internal_identifier_acoa; // Fallback to ACoA if public not found
|
|
456
|
+
let targetProfile = null;
|
|
457
|
+
try {
|
|
458
|
+
const profileSql = `
|
|
459
|
+
SELECT first_name, last_name,
|
|
460
|
+
COALESCE(profile_image_cloudfront_url, profile_picture_url) as profile_picture_url,
|
|
461
|
+
headline,
|
|
462
|
+
public_identifier
|
|
463
|
+
FROM linkedin.accounts
|
|
464
|
+
WHERE linkedin_identifier_acoa = $1
|
|
465
|
+
LIMIT 1
|
|
466
|
+
`;
|
|
467
|
+
const profile = await (0, pg_client_1.queryOne)(db, profileSql, [job.internal_identifier_acoa]);
|
|
468
|
+
// Use public identifier for display if available, otherwise fallback to ACoA
|
|
469
|
+
if (profile?.public_identifier) {
|
|
470
|
+
targetLinkedInIdentifier = profile.public_identifier;
|
|
471
|
+
}
|
|
472
|
+
if (profile) {
|
|
473
|
+
// Get current position from work experience
|
|
474
|
+
let currentPosition = null;
|
|
475
|
+
let currentCompany = null;
|
|
476
|
+
try {
|
|
477
|
+
const workExpSql = `
|
|
478
|
+
SELECT we.position, we.company, we.start_date, we.end_date, we.is_current
|
|
479
|
+
FROM linkedin.work_experience we
|
|
480
|
+
INNER JOIN linkedin.accounts la ON we.linkedin_account_id = la.id
|
|
481
|
+
WHERE la.linkedin_identifier_acoa = $1 AND we.is_current = true
|
|
482
|
+
ORDER BY we.start_date DESC
|
|
483
|
+
LIMIT 1
|
|
484
|
+
`;
|
|
485
|
+
const currentWork = await (0, pg_client_1.queryOne)(db, workExpSql, [job.internal_identifier_acoa]);
|
|
486
|
+
if (currentWork) {
|
|
487
|
+
currentPosition = currentWork.position || null;
|
|
488
|
+
currentCompany = currentWork.company || null;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
catch (workError) {
|
|
492
|
+
// If work experience fetch fails, continue without it
|
|
493
|
+
console.warn("Failed to fetch work experience for profile:", workError);
|
|
494
|
+
}
|
|
495
|
+
targetProfile = {
|
|
496
|
+
name: `${profile.first_name || ""} ${profile.last_name || ""}`.trim() || "Unknown User",
|
|
497
|
+
profileImageUrl: profile.profile_picture_url || null,
|
|
498
|
+
position: currentPosition,
|
|
499
|
+
currentCompany: currentCompany,
|
|
500
|
+
headline: profile.headline || null,
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
catch (profileError) {
|
|
505
|
+
// If profile fetch fails, continue without profile details
|
|
506
|
+
console.warn("Failed to fetch profile details:", profileError);
|
|
507
|
+
}
|
|
508
|
+
const minimalJob = {
|
|
509
|
+
id: job.id,
|
|
510
|
+
requesterLinkedinAccountId: job.requester_linkedin_account_id,
|
|
511
|
+
internalIdentifierAcoa: job.internal_identifier_acoa,
|
|
512
|
+
mappingJobId: job.mapping_job_id,
|
|
513
|
+
createdAt: job.created_at,
|
|
514
|
+
updatedAt: job.updated_at,
|
|
515
|
+
status,
|
|
516
|
+
progress,
|
|
517
|
+
targetLinkedInIdentifier,
|
|
518
|
+
mappingJobDetails,
|
|
519
|
+
linkedinRelationshipsCount,
|
|
520
|
+
organizationAssignmentStatus: organizationAssignmentStatus ?? null,
|
|
521
|
+
organizationAssignmentJobDetails: organizationAssignmentJobDetails ?? null,
|
|
522
|
+
organizations: organizations ?? null,
|
|
523
|
+
targetProfile,
|
|
524
|
+
};
|
|
525
|
+
return minimalJob;
|
|
526
|
+
}));
|
|
527
|
+
return {
|
|
528
|
+
jobs: jobsWithMinimalStatus,
|
|
529
|
+
total_items,
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
catch (error) {
|
|
533
|
+
console.error("Error getting minimal on-demand mapping jobs:", error);
|
|
534
|
+
throw error;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Get pending on-demand mapping jobs (no mapping job assigned yet)
|
|
539
|
+
*/
|
|
540
|
+
async function getPendingOnDemandMappingJobs(options) {
|
|
541
|
+
const { limit = 100 } = options || {};
|
|
542
|
+
(0, db_1.debugLogDbOperation)("select", "monitoring.on_demand_mapping_jobs", { limit, status: "pending" }, undefined, {
|
|
543
|
+
operation: "getPendingOnDemandMappingJobs",
|
|
544
|
+
});
|
|
545
|
+
try {
|
|
546
|
+
const db = await database_service_1.dbService.getDb();
|
|
547
|
+
const sql = `
|
|
548
|
+
SELECT id, requester_linkedin_account_id, internal_identifier_acoa, mapping_job_id, metadata, created_at, updated_at
|
|
549
|
+
FROM monitoring.on_demand_mapping_jobs
|
|
550
|
+
WHERE mapping_job_id IS NULL
|
|
551
|
+
ORDER BY created_at
|
|
552
|
+
LIMIT $1
|
|
553
|
+
`;
|
|
554
|
+
const results = await (0, pg_client_1.query)(db, sql, [limit]);
|
|
555
|
+
return results.map(r => ({
|
|
556
|
+
id: r.id,
|
|
557
|
+
requesterLinkedinAccountId: r.requester_linkedin_account_id,
|
|
558
|
+
internalIdentifierAcoa: r.internal_identifier_acoa,
|
|
559
|
+
mappingJobId: r.mapping_job_id,
|
|
560
|
+
metadata: r.metadata,
|
|
561
|
+
createdAt: r.created_at,
|
|
562
|
+
updatedAt: r.updated_at,
|
|
563
|
+
}));
|
|
564
|
+
}
|
|
565
|
+
catch (error) {
|
|
566
|
+
console.error("Error getting pending on-demand mapping jobs:", error);
|
|
567
|
+
throw error;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
// =============================================================================
|
|
571
|
+
// UTILITY FUNCTIONS
|
|
572
|
+
// =============================================================================
|
|
573
|
+
/**
|
|
574
|
+
* Check if an on-demand mapping job exists for the given parameters
|
|
575
|
+
*/
|
|
576
|
+
async function checkOnDemandMappingJobExists(requesterLinkedinAccountId, internalIdentifierAcoa) {
|
|
577
|
+
(0, db_1.debugLogDbOperation)("select", "monitoring.on_demand_mapping_jobs", { requesterLinkedinAccountId, internalIdentifierAcoa }, undefined, {
|
|
578
|
+
operation: "checkOnDemandMappingJobExists",
|
|
579
|
+
});
|
|
580
|
+
try {
|
|
581
|
+
const db = await database_service_1.dbService.getDb();
|
|
582
|
+
const sql = `
|
|
583
|
+
SELECT id, requester_linkedin_account_id, internal_identifier_acoa, mapping_job_id, metadata, created_at, updated_at
|
|
584
|
+
FROM monitoring.on_demand_mapping_jobs
|
|
585
|
+
WHERE requester_linkedin_account_id = $1 AND internal_identifier_acoa = $2
|
|
586
|
+
LIMIT 1
|
|
587
|
+
`;
|
|
588
|
+
const result = await (0, pg_client_1.queryOne)(db, sql, [requesterLinkedinAccountId, internalIdentifierAcoa]);
|
|
589
|
+
if (!result)
|
|
590
|
+
return null;
|
|
591
|
+
return {
|
|
592
|
+
id: result.id,
|
|
593
|
+
requesterLinkedinAccountId: result.requester_linkedin_account_id,
|
|
594
|
+
internalIdentifierAcoa: result.internal_identifier_acoa,
|
|
595
|
+
mappingJobId: result.mapping_job_id,
|
|
596
|
+
metadata: result.metadata,
|
|
597
|
+
createdAt: result.created_at,
|
|
598
|
+
updatedAt: result.updated_at,
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
catch (error) {
|
|
602
|
+
console.error("Error checking on-demand mapping job exists:", error);
|
|
603
|
+
throw error;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Get or create an on-demand mapping job
|
|
608
|
+
*/
|
|
609
|
+
async function getOrCreateOnDemandMappingJob(params) {
|
|
610
|
+
try {
|
|
611
|
+
// Check if job already exists
|
|
612
|
+
const existingJob = await checkOnDemandMappingJobExists(params.requesterLinkedinAccountId, params.internalIdentifierAcoa);
|
|
613
|
+
if (existingJob) {
|
|
614
|
+
return { onDemandJob: existingJob, wasCreated: false };
|
|
615
|
+
}
|
|
616
|
+
// Create new job
|
|
617
|
+
const newJob = await createOnDemandMappingJob(params);
|
|
618
|
+
return { onDemandJob: newJob, wasCreated: true };
|
|
619
|
+
}
|
|
620
|
+
catch (error) {
|
|
621
|
+
console.error("Error getting or creating on-demand mapping job:", error);
|
|
622
|
+
throw error;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Get target LinkedIn account ID for on-demand mapping job in an organization
|
|
627
|
+
*
|
|
628
|
+
* For on-demand mapping jobs, relationships are mapped for the TARGET but assigned
|
|
629
|
+
* to the REQUESTER's personal workspace. This function helps identify which account
|
|
630
|
+
* to use when querying relationships (the target's account, not the requester's).
|
|
631
|
+
*
|
|
632
|
+
* @param db - Database instance
|
|
633
|
+
* @param requesterLinkedinAccountId - The requester's LinkedIn account ID
|
|
634
|
+
* @param organizationId - The organization ID (personal workspace)
|
|
635
|
+
* @returns Target LinkedIn account ID if on-demand job exists, null otherwise
|
|
636
|
+
*/
|
|
637
|
+
async function getTargetLinkedInAccountIdForOnDemandJobInOrganization(db, requesterLinkedinAccountId, organizationId) {
|
|
638
|
+
(0, db_1.debugLogDbOperation)("select", "monitoring.on_demand_mapping_jobs + organization_assignment_jobs", { requesterLinkedinAccountId, organizationId }, undefined, {
|
|
639
|
+
operation: "getTargetLinkedInAccountIdForOnDemandJobInOrganization",
|
|
640
|
+
requesterLinkedinAccountId,
|
|
641
|
+
organizationId,
|
|
642
|
+
});
|
|
643
|
+
try {
|
|
644
|
+
const sql = `
|
|
645
|
+
SELECT
|
|
646
|
+
la_target.id as target_linkedin_account_id
|
|
647
|
+
FROM monitoring.on_demand_mapping_jobs od
|
|
648
|
+
INNER JOIN monitoring.organization_assignment_jobs oaj
|
|
649
|
+
ON oaj.mapping_job_id = od.mapping_job_id
|
|
650
|
+
INNER JOIN linkedin.accounts la_target
|
|
651
|
+
ON la_target.linkedin_identifier_acoa = od.internal_identifier_acoa
|
|
652
|
+
WHERE
|
|
653
|
+
od.requester_linkedin_account_id = $1
|
|
654
|
+
AND oaj.organization_id = $2
|
|
655
|
+
AND od.mapping_job_id IS NOT NULL
|
|
656
|
+
ORDER BY od.created_at DESC
|
|
657
|
+
LIMIT 1
|
|
658
|
+
`;
|
|
659
|
+
const result = await (0, pg_client_1.queryOne)(db, sql, [requesterLinkedinAccountId, organizationId]);
|
|
660
|
+
return result?.target_linkedin_account_id || null;
|
|
661
|
+
}
|
|
662
|
+
catch (error) {
|
|
663
|
+
console.error("Error getting target LinkedIn account ID for on-demand job:", error);
|
|
664
|
+
throw error;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
async function deleteOnDemandMappingJob(requesterLinkedinAccountId, internalIdentifierAcoa) {
|
|
668
|
+
(0, db_1.debugLogDbOperation)("delete", "monitoring.on_demand_mapping_jobs", { requesterLinkedinAccountId, internalIdentifierAcoa }, undefined, {
|
|
669
|
+
operation: "deleteOnDemandMappingJob",
|
|
670
|
+
requesterLinkedinAccountId,
|
|
671
|
+
internalIdentifierAcoa,
|
|
672
|
+
});
|
|
673
|
+
try {
|
|
674
|
+
const db = await database_service_1.dbService.getDb();
|
|
675
|
+
const sql = `
|
|
676
|
+
DELETE FROM monitoring.on_demand_mapping_jobs
|
|
677
|
+
WHERE requester_linkedin_account_id = $1 AND internal_identifier_acoa = $2
|
|
678
|
+
RETURNING id
|
|
679
|
+
`;
|
|
680
|
+
const result = await (0, pg_client_1.query)(db, sql, [
|
|
681
|
+
requesterLinkedinAccountId,
|
|
682
|
+
internalIdentifierAcoa,
|
|
683
|
+
]);
|
|
684
|
+
return result.length > 0;
|
|
685
|
+
}
|
|
686
|
+
catch (error) {
|
|
687
|
+
console.error("Error deleting on-demand mapping job:", error);
|
|
688
|
+
throw error;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Get relationship scores for an on-demand mapping job
|
|
693
|
+
*/
|
|
694
|
+
async function getRelationshipScoresForOnDemandJob(requesterLinkedinAccountId, internalIdentifierAcoa, options) {
|
|
695
|
+
const { limit = 50, minScore } = options || {};
|
|
696
|
+
(0, db_1.debugLogDbOperation)("select", "linkedin.relationships", { requesterLinkedinAccountId, internalIdentifierAcoa, limit, minScore }, undefined, {
|
|
697
|
+
operation: "getRelationshipScoresForOnDemandJob",
|
|
698
|
+
requesterLinkedinAccountId,
|
|
699
|
+
internalIdentifierAcoa,
|
|
700
|
+
});
|
|
701
|
+
try {
|
|
702
|
+
// Get the on-demand job to find the mapping job ID
|
|
703
|
+
const onDemandJob = await getOnDemandMappingJob(requesterLinkedinAccountId, internalIdentifierAcoa);
|
|
704
|
+
if (!onDemandJob || !onDemandJob.mappingJobId) {
|
|
705
|
+
return [];
|
|
706
|
+
}
|
|
707
|
+
const db = await database_service_1.dbService.getDb();
|
|
708
|
+
let sql = `
|
|
709
|
+
SELECT id, linkedin_account_id_a, linkedin_account_id_b, score, model_version, analysis_type, mapping_job_id, metadata, created_at
|
|
710
|
+
FROM linkedin.relationships
|
|
711
|
+
WHERE mapping_job_id = $1
|
|
712
|
+
`;
|
|
713
|
+
const params = [onDemandJob.mappingJobId];
|
|
714
|
+
if (minScore !== undefined) {
|
|
715
|
+
sql += ` AND score >= $2`;
|
|
716
|
+
params.push(minScore);
|
|
717
|
+
}
|
|
718
|
+
sql += ` ORDER BY score DESC LIMIT $${params.length + 1}`;
|
|
719
|
+
params.push(limit);
|
|
720
|
+
const results = await (0, pg_client_1.query)(db, sql, params);
|
|
721
|
+
return results;
|
|
722
|
+
}
|
|
723
|
+
catch (error) {
|
|
724
|
+
console.error("Error getting relationship scores for on-demand job:", error);
|
|
725
|
+
throw error;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
//# sourceMappingURL=on-demand-mapping-operations.js.map
|