@crmforall/connect 0.1.2 → 0.1.4

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.
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runSyncOnce = runSyncOnce;
4
+ exports.runSyncWatch = runSyncWatch;
5
+ const connector_1 = require("@crmforall/connector");
6
+ const contracts_1 = require("../contracts");
7
+ /**
8
+ * 발송 결과 동기화 — 진행 중인 발송 작업 결과를 플랫폼에서 가져와 CRM 스키마로 반영.
9
+ * 단발(`connect sync`) 또는 주기 폴링(`connect sync --watch`)로 동작.
10
+ * 단방향(플랫폼→로컬)이라 운영 원본 테이블은 건드리지 않는다. 비밀번호는 설정/환경변수로만.
11
+ */
12
+ async function runSyncOnce(opts) {
13
+ const config = (0, connector_1.loadConfig)();
14
+ if (!config) {
15
+ return (0, contracts_1.jsonError)("sync", contracts_1.ERROR_CODE.CRM_SCHEMA_NOT_READY, "설정이 없습니다. `connect init`을 먼저 실행하세요.");
16
+ }
17
+ const adapter = (0, connector_1.buildAdapter)(config);
18
+ try {
19
+ await adapter.connect();
20
+ }
21
+ catch (err) {
22
+ return (0, contracts_1.jsonError)("sync", contracts_1.ERROR_CODE.NET_UNREACHABLE, `DB 연결 실패: ${err instanceof Error ? err.message : err}`);
23
+ }
24
+ try {
25
+ const platform = new connector_1.HttpPlatformClient({
26
+ platformUrl: config.platformUrl,
27
+ connectorId: config.connectorId,
28
+ connectorSecret: config.connectorSecret,
29
+ });
30
+ const result = await (0, connector_1.syncPendingSendJobs)({
31
+ db: adapter,
32
+ platform,
33
+ crmSchema: config.crmSchema,
34
+ limit: opts.limit,
35
+ });
36
+ return (0, contracts_1.jsonOk)("sync", result);
37
+ }
38
+ catch (err) {
39
+ return (0, contracts_1.jsonError)("sync", contracts_1.ERROR_CODE.PLATFORM_UNREACHABLE, `동기화 실패: ${err instanceof Error ? err.message : err}`);
40
+ }
41
+ finally {
42
+ await adapter.disconnect().catch(() => { });
43
+ }
44
+ }
45
+ const sleep = (ms) => new Promise((res) => setTimeout(res, ms));
46
+ /** 주기 폴링 루프 — interval초마다 동기화. SIGINT로 종료. (stdout 오염 방지로 stderr 출력) */
47
+ async function runSyncWatch(opts) {
48
+ const interval = Math.max(30, opts.intervalSec) * 1000;
49
+ console.error(`[sync] watch 시작 — ${interval / 1000}초 주기. Ctrl+C로 종료.`);
50
+ let stop = false;
51
+ process.on("SIGINT", () => {
52
+ stop = true;
53
+ });
54
+ while (!stop) {
55
+ const r = await runSyncOnce({ limit: opts.limit });
56
+ const ts = new Date().toISOString();
57
+ if (r.ok && r.data) {
58
+ console.error(`[sync] ${ts} synced=${r.data.synced} pending=${r.data.stillPending}`);
59
+ }
60
+ else {
61
+ console.error(`[sync] ${ts} 실패 [${r.error?.code}] ${r.error?.message}`);
62
+ }
63
+ if (stop)
64
+ break;
65
+ await sleep(interval);
66
+ }
67
+ console.error("[sync] 종료");
68
+ }
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ const commander_1 = require("commander");
5
5
  const init_1 = require("./commands/init");
6
6
  const doctor_1 = require("./commands/doctor");
7
7
  const status_1 = require("./commands/status");
8
+ const sync_1 = require("./commands/sync");
8
9
  const program = new commander_1.Command();
9
10
  program
10
11
  .name("connect")
@@ -53,4 +54,19 @@ program
53
54
  .action(async (opts) => {
54
55
  emit(await (0, status_1.runStatus)(), Boolean(opts.json));
55
56
  });
57
+ program
58
+ .command("sync")
59
+ .description("발송 결과 동기화 — 진행 중인 발송 작업을 플랫폼에서 가져와 CRM 스키마에 반영")
60
+ .option("--watch", "주기 폴링 데몬으로 실행 (Ctrl+C로 종료)")
61
+ .option("--interval <seconds>", "폴링 주기(초), 기본 300, 최소 30", "300")
62
+ .option("--limit <n>", "한 번에 동기화할 작업 수 상한")
63
+ .option("--json", "기계가 읽을 수 있는 JSON 출력 (단발 모드)")
64
+ .action(async (opts) => {
65
+ const limit = opts.limit ? Number(opts.limit) : undefined;
66
+ if (opts.watch) {
67
+ await (0, sync_1.runSyncWatch)({ intervalSec: Number(opts.interval) || 300, limit });
68
+ return;
69
+ }
70
+ emit(await (0, sync_1.runSyncOnce)({ limit }), Boolean(opts.json));
71
+ });
56
72
  program.parseAsync(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crmforall/connect",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "crmforall 커넥터 설치/진단 CLI — npx @crmforall/connect init --token=...",
5
5
  "main": "./dist/index.js",
6
6
  "bin": {
@@ -16,7 +16,7 @@
16
16
  "typecheck": "tsc --noEmit"
17
17
  },
18
18
  "dependencies": {
19
- "@crmforall/connector": "^0.1.2",
19
+ "@crmforall/connector": "workspace:*",
20
20
  "commander": "^13.0.0"
21
21
  },
22
22
  "devDependencies": {