twenty-app-intake 0.3.0 → 0.4.0
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/README.md +292 -7
- package/manifest.json +389 -15
- package/package.json +1 -1
- package/src/front-components/settings-panel.mjs +7 -7
- package/src/front-components/settings-panel.mjs.map +2 -2
- package/src/front-components/settings-panel.tsx +49 -0
- package/src/logic-functions/check-silence.mjs +263 -0
- package/src/logic-functions/check-silence.mjs.map +7 -0
- package/src/logic-functions/check-silence.ts +52 -0
- package/src/logic-functions/contract.mjs +507 -0
- package/src/logic-functions/contract.mjs.map +7 -0
- package/src/logic-functions/contract.ts +172 -0
- package/src/logic-functions/health.mjs +125 -5
- package/src/logic-functions/health.mjs.map +3 -3
- package/src/logic-functions/health.ts +41 -5
- package/src/logic-functions/quarantine-discard.mjs +380 -0
- package/src/logic-functions/quarantine-discard.mjs.map +7 -0
- package/src/logic-functions/quarantine-discard.ts +65 -0
- package/src/logic-functions/quarantine-list.mjs +211 -0
- package/src/logic-functions/quarantine-list.mjs.map +7 -0
- package/src/logic-functions/quarantine-list.ts +93 -0
- package/src/logic-functions/quarantine-release.mjs +1974 -0
- package/src/logic-functions/quarantine-release.mjs.map +7 -0
- package/src/logic-functions/quarantine-release.ts +94 -0
- package/src/logic-functions/register.mjs +34 -1
- package/src/logic-functions/register.mjs.map +2 -2
- package/src/logic-functions/replay-bulk.mjs +2040 -0
- package/src/logic-functions/replay-bulk.mjs.map +7 -0
- package/src/logic-functions/replay-bulk.ts +83 -0
- package/src/logic-functions/replay-log.mjs +1987 -0
- package/src/logic-functions/replay-log.mjs.map +7 -0
- package/src/logic-functions/replay-log.ts +54 -0
- package/src/logic-functions/retry.mjs +1001 -248
- package/src/logic-functions/retry.mjs.map +4 -4
- package/src/logic-functions/retry.ts +45 -68
- package/src/logic-functions/test-ingest.mjs +616 -28
- package/src/logic-functions/test-ingest.mjs.map +4 -4
- package/src/logic-functions/test-ingest.ts +132 -28
- package/src/logic-functions/webhook.mjs +965 -209
- package/src/logic-functions/webhook.mjs.map +4 -4
- package/src/logic-functions/webhook.ts +23 -48
- package/src/post-install.mjs +34 -1
- package/src/post-install.mjs.map +2 -2
|
@@ -1,112 +1,89 @@
|
|
|
1
1
|
import { defineLogicFunction, type RoutePayload } from 'twenty-sdk/define';
|
|
2
|
-
import { CoreApiClient } from 'twenty-client-sdk/core';
|
|
3
|
-
import { MetadataApiClient } from 'twenty-client-sdk/metadata';
|
|
4
2
|
import { IDS } from '../constants/universal-identifiers';
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import { coreApi } from '../lib/rest-client';
|
|
3
|
+
import { loadLog, slugForSource } from '../lib/replay';
|
|
4
|
+
import { runIngestion, successBody } from '../lib/ingest';
|
|
8
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Re-run a failed ingestion.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately narrower than replay: this refuses a log that already succeeded,
|
|
10
|
+
* so an operator clicking Retry on a working record cannot create a second one.
|
|
11
|
+
* Use `/replay` for a log that succeeded but needs re-mapping.
|
|
12
|
+
*/
|
|
9
13
|
const handler = async (params: RoutePayload) => {
|
|
10
|
-
const
|
|
11
|
-
if (!logId) {
|
|
12
|
-
return { statusCode: 400, body: { error: 'Missing logId in URL' } };
|
|
13
|
-
}
|
|
14
|
+
const startedAt = Date.now();
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
data: {
|
|
18
|
-
intakeLog: {
|
|
19
|
-
id: string;
|
|
20
|
-
status: string;
|
|
21
|
-
rawPayload: string | null;
|
|
22
|
-
intakeSourceId: string | null;
|
|
23
|
-
error: string | null;
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
}>(`/intakeLogs/${logId}`).catch(() => null);
|
|
16
|
+
const logId = params.pathParameters?.['logId'];
|
|
17
|
+
if (!logId) return { statusCode: 400, body: { error: 'Missing logId in URL' } };
|
|
27
18
|
|
|
28
|
-
const log =
|
|
19
|
+
const log = await loadLog(logId);
|
|
20
|
+
if (!log) return { statusCode: 404, body: { error: `IntakeLog ${logId} not found` } };
|
|
29
21
|
|
|
30
|
-
if (
|
|
31
|
-
return {
|
|
22
|
+
if (log.status === 'SUCCESS') {
|
|
23
|
+
return {
|
|
24
|
+
statusCode: 400,
|
|
25
|
+
body: {
|
|
26
|
+
error: 'This ingestion already succeeded — no retry needed. Use POST /s/intake/logs/:logId/replay to re-run it through the current rules.',
|
|
27
|
+
status: log.status,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
if (log.status === '
|
|
32
|
+
if (log.status === 'QUARANTINED') {
|
|
35
33
|
return {
|
|
36
34
|
statusCode: 400,
|
|
37
|
-
body: {
|
|
35
|
+
body: {
|
|
36
|
+
error: 'This payload is quarantined. Use POST /s/intake/quarantine/:logId/release to let it through.',
|
|
37
|
+
status: log.status,
|
|
38
|
+
},
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
if (!log.rawPayload) {
|
|
42
43
|
return {
|
|
43
44
|
statusCode: 400,
|
|
44
|
-
body: {
|
|
45
|
+
body: {
|
|
46
|
+
error: 'No raw payload stored on this log — retry needs one. Check INTAKE_RAW_PAYLOAD_RETENTION and INTAKE_RAW_PAYLOAD_MAX_BYTES.',
|
|
47
|
+
code: 'NO_STORED_PAYLOAD',
|
|
48
|
+
},
|
|
45
49
|
};
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
let rawPayload: Record<string, unknown>;
|
|
49
53
|
try {
|
|
50
|
-
rawPayload = JSON.parse(log.rawPayload)
|
|
54
|
+
rawPayload = JSON.parse(log.rawPayload) as Record<string, unknown>;
|
|
51
55
|
} catch {
|
|
52
56
|
return { statusCode: 400, body: { error: 'rawPayload is not valid JSON' } };
|
|
53
57
|
}
|
|
54
58
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const srcResult = await coreApi.get<{ data: { intakeSource: { slug: string } } }>(
|
|
59
|
-
`/intakeSources/${log.intakeSourceId}`,
|
|
60
|
-
).catch(() => null);
|
|
61
|
-
sourceSlug = srcResult?.data?.intakeSource?.slug ?? 'unknown';
|
|
59
|
+
const sourceSlug = await slugForSource(log.intakeSourceId);
|
|
60
|
+
if (!sourceSlug) {
|
|
61
|
+
return { statusCode: 400, body: { error: 'The source for this log no longer exists' } };
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
const
|
|
65
|
-
const coreClient = new CoreApiClient();
|
|
66
|
-
const metadataClient = new MetadataApiClient();
|
|
67
|
-
const pipeline = createPipeline(coreClient, metadataClient);
|
|
68
|
-
|
|
69
|
-
const ctx: PipelineContext = {
|
|
64
|
+
const outcome = await runIngestion({
|
|
70
65
|
sourceSlug,
|
|
71
|
-
rawBody: undefined, // HMAC skipped on retry — source already verified originally
|
|
72
66
|
rawPayload,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
skipDedup: true,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
warnings: [],
|
|
79
|
-
events: [],
|
|
80
|
-
};
|
|
67
|
+
// The signature was verified when the payload first arrived and there is no
|
|
68
|
+
// body to re-verify against; the caller here is already authenticated.
|
|
69
|
+
skipDedup: true,
|
|
70
|
+
replayOfLogId: log.id,
|
|
71
|
+
});
|
|
81
72
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (!result.ok) {
|
|
73
|
+
if (!outcome.ok) {
|
|
85
74
|
return {
|
|
86
75
|
statusCode: 500,
|
|
87
76
|
body: {
|
|
88
|
-
error: `Retry failed: ${
|
|
89
|
-
code:
|
|
77
|
+
error: `Retry failed: ${outcome.error.message}`,
|
|
78
|
+
code: outcome.error.code,
|
|
90
79
|
originalLogId: logId,
|
|
91
80
|
},
|
|
92
81
|
};
|
|
93
82
|
}
|
|
94
83
|
|
|
95
|
-
const { value: finalCtx } = result;
|
|
96
|
-
|
|
97
84
|
return {
|
|
98
85
|
statusCode: 200,
|
|
99
|
-
body: {
|
|
100
|
-
success: true,
|
|
101
|
-
originalLogId: logId,
|
|
102
|
-
recordId: finalCtx.personId ?? finalCtx.companyId,
|
|
103
|
-
recordType: finalCtx.recordType,
|
|
104
|
-
personId: finalCtx.personId,
|
|
105
|
-
companyId: finalCtx.companyId,
|
|
106
|
-
fieldsCreated: finalCtx.fieldsCreated,
|
|
107
|
-
processingMs: Date.now() - startedAt,
|
|
108
|
-
warnings: finalCtx.warnings,
|
|
109
|
-
},
|
|
86
|
+
body: { originalLogId: logId, ...successBody(outcome.ctx, startedAt) },
|
|
110
87
|
};
|
|
111
88
|
};
|
|
112
89
|
|