@mulsok/traders-client 0.1.0 → 0.2.1

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.
Files changed (81) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +42 -5
  3. package/bin/cli.js +618 -38
  4. package/dist/server/auth/admin.js +32 -0
  5. package/dist/server/auth/admin.js.map +1 -0
  6. package/dist/server/broker/kiwoom/_helpers/symbol-code.js +21 -0
  7. package/dist/server/broker/kiwoom/_helpers/symbol-code.js.map +1 -0
  8. package/dist/server/broker/kiwoom/client.js +23 -4
  9. package/dist/server/broker/kiwoom/client.js.map +1 -1
  10. package/dist/server/broker/kiwoom/endpoints/account.js +14 -6
  11. package/dist/server/broker/kiwoom/endpoints/account.js.map +1 -1
  12. package/dist/server/broker/kiwoom/endpoints/quote.js +99 -13
  13. package/dist/server/broker/kiwoom/endpoints/quote.js.map +1 -1
  14. package/dist/server/broker/kiwoom/index.js +1 -1
  15. package/dist/server/broker/kiwoom/index.js.map +1 -1
  16. package/dist/server/broker/kiwoom/order-tracker.js +13 -0
  17. package/dist/server/broker/kiwoom/order-tracker.js.map +1 -1
  18. package/dist/server/broker/kiwoom/price-feed.js +13 -0
  19. package/dist/server/broker/kiwoom/price-feed.js.map +1 -1
  20. package/dist/server/broker/kiwoom/ws/endpoints/condition.js +3 -2
  21. package/dist/server/broker/kiwoom/ws/endpoints/condition.js.map +1 -1
  22. package/dist/server/calendar/kst-marker.js +68 -0
  23. package/dist/server/calendar/kst-marker.js.map +1 -0
  24. package/dist/server/config.js +370 -72
  25. package/dist/server/config.js.map +1 -1
  26. package/dist/server/db/sqlite.js +53 -29
  27. package/dist/server/db/sqlite.js.map +1 -1
  28. package/dist/server/diary/writer.js +151 -46
  29. package/dist/server/diary/writer.js.map +1 -1
  30. package/dist/server/index.js +166 -11
  31. package/dist/server/index.js.map +1 -1
  32. package/dist/server/jobs/universe-sync.js +48 -11
  33. package/dist/server/jobs/universe-sync.js.map +1 -1
  34. package/dist/server/jobs/watchdog.js +4 -0
  35. package/dist/server/jobs/watchdog.js.map +1 -1
  36. package/dist/server/journal/telemetry.js +11 -0
  37. package/dist/server/journal/telemetry.js.map +1 -1
  38. package/dist/server/journal/trade-journal.js +42 -16
  39. package/dist/server/journal/trade-journal.js.map +1 -1
  40. package/dist/server/llm/context-builder.js +9 -5
  41. package/dist/server/llm/context-builder.js.map +1 -1
  42. package/dist/server/personas/loader.js +46 -16
  43. package/dist/server/personas/loader.js.map +1 -1
  44. package/dist/server/personas/persona-agent.js +93 -21
  45. package/dist/server/personas/persona-agent.js.map +1 -1
  46. package/dist/server/personas/persona-state.js +198 -19
  47. package/dist/server/personas/persona-state.js.map +1 -1
  48. package/dist/server/personas/runner.js +29 -0
  49. package/dist/server/personas/runner.js.map +1 -1
  50. package/dist/server/personas/schema.js +13 -0
  51. package/dist/server/personas/schema.js.map +1 -1
  52. package/dist/server/personas/wake-plan.js +4 -67
  53. package/dist/server/personas/wake-plan.js.map +1 -1
  54. package/dist/server/readiness.js +70 -0
  55. package/dist/server/readiness.js.map +1 -1
  56. package/dist/server/routes.js +300 -13
  57. package/dist/server/routes.js.map +1 -1
  58. package/dist/server/screener/engine.js +110 -1
  59. package/dist/server/screener/engine.js.map +1 -1
  60. package/dist/server/screener/indicators.js +63 -0
  61. package/dist/server/screener/indicators.js.map +1 -0
  62. package/dist/server/server-sync.js +387 -126
  63. package/dist/server/server-sync.js.map +1 -1
  64. package/dist/server/share/postgres-publish.js +139 -0
  65. package/dist/server/share/postgres-publish.js.map +1 -0
  66. package/dist/server/share/prepare-state.js +50 -0
  67. package/dist/server/share/prepare-state.js.map +1 -0
  68. package/dist/server/share/prepare.js +61 -0
  69. package/dist/server/share/prepare.js.map +1 -0
  70. package/dist/server/share/publish-cron.js +96 -0
  71. package/dist/server/share/publish-cron.js.map +1 -0
  72. package/dist/server/share/snapshot.js +81 -0
  73. package/dist/server/share/snapshot.js.map +1 -0
  74. package/dist/server/watchers/condition-watcher.js +57 -16
  75. package/dist/server/watchers/condition-watcher.js.map +1 -1
  76. package/dist/web/assets/index-B1C-UX9W.js +88 -0
  77. package/dist/web/assets/index-N7Xwheka.css +1 -0
  78. package/dist/web/index.html +2 -2
  79. package/package.json +4 -5
  80. package/dist/web/assets/index-62SMpbaf.js +0 -79
  81. package/dist/web/assets/index-BPLQR0wt.css +0 -1
@@ -18,6 +18,31 @@ import { loadConfig, SERVER_BASE_URL } from "./config.js";
18
18
  import { createLlmProvider } from "./llm/index.js";
19
19
  import { fetchCommonBundle, fetchPersonaBundle } from "./bundle.js";
20
20
  import { getAccessToken, getDeposit, kiwoomHostLabel } from "./broker/kiwoom/index.js";
21
+ import { getDb } from "./db/sqlite.js";
22
+ /**
23
+ * 페르소나 평가 가능한 최소 봉수 (현재 너울 = longMaBreakoutBonus 120 기준).
24
+ * 새 페르소나가 더 깊은 EMA 사용 시 상향 검토 (224 → 329, 448 → 538).
25
+ */
26
+ const MIN_CANDLES_FOR_DEEP_PERSONA = 120;
27
+ /** 「준비됨」 판정 — universe 의 최소 N개 종목이 deep 깊이 보유 */
28
+ const MIN_DEEP_STOCKS = 500;
29
+ /** 캔들 깊이 통계 — Phase 5c data-readiness check 의 핵심 helper */
30
+ function getCandleDepthStats() {
31
+ try {
32
+ const db = getDb();
33
+ const totalRow = db.prepare("SELECT COUNT(DISTINCT code) AS n FROM daily_candles").get();
34
+ const deepRow = db
35
+ .prepare(`SELECT COUNT(*) AS n FROM (
36
+ SELECT code FROM daily_candles GROUP BY code HAVING COUNT(*) >= ?
37
+ )`)
38
+ .get(MIN_CANDLES_FOR_DEEP_PERSONA);
39
+ return { totalStocks: totalRow.n, deepStocks: deepRow.n };
40
+ }
41
+ catch {
42
+ // DB 미생성 등 — 0/0 반환 (data-prepared = todo)
43
+ return { totalStocks: 0, deepStocks: 0 };
44
+ }
45
+ }
21
46
  export async function runReadinessCheck() {
22
47
  const cfg = loadConfig();
23
48
  const items = [];
@@ -375,6 +400,51 @@ export async function runReadinessCheck() {
375
400
  blocking: false,
376
401
  });
377
402
  }
403
+ /* ──────────────────────────────────────────────────
404
+ * 7. 데이터 준비 (data-prepared) — Phase 5c
405
+ *
406
+ * 페르소나가 평가 가능한 최소 봉수 (현재 너울 120봉 기준) 를 보유한 종목
407
+ * 수가 충분한지 (≥500). 미달 시 사용자에게 backfill 진행 안내.
408
+ * blocking — 데이터 부족하면 분석 시작해도 「후보 0」 만 나옴.
409
+ * 추후 깊은 EMA 페르소나 추가 시 MIN_CANDLES_FOR_DEEP_PERSONA 상향.
410
+ * ────────────────────────────────────────────────── */
411
+ const depthStats = getCandleDepthStats();
412
+ if (depthStats.deepStocks >= MIN_DEEP_STOCKS) {
413
+ items.push({
414
+ id: "data-prepared",
415
+ label: "시장 데이터 준비",
416
+ status: "ok",
417
+ detail: `${depthStats.deepStocks.toLocaleString()} 종목 ≥${MIN_CANDLES_FOR_DEEP_PERSONA}봉 (총 ${depthStats.totalStocks.toLocaleString()})`,
418
+ blocking: true,
419
+ });
420
+ }
421
+ else {
422
+ // Phase 5e-4 · prepare 진행 중이면 progress hint 추가
423
+ const { getPrepareState } = await import("./share/prepare-state.js");
424
+ const prep = getPrepareState();
425
+ const hint = prep.running
426
+ ? ` · prepare 진행 중 (page ${prep.candles.pages} · ${prep.candles.returned.toLocaleString()} row)`
427
+ : " · `mulsok-client prepare` 실행 또는 webui 첫 진입";
428
+ if (depthStats.totalStocks === 0) {
429
+ items.push({
430
+ id: "data-prepared",
431
+ label: "시장 데이터 준비",
432
+ status: "todo",
433
+ detail: `초기 데이터 미수집${hint}`,
434
+ blocking: true,
435
+ });
436
+ }
437
+ else {
438
+ const pct = Math.round((depthStats.deepStocks / depthStats.totalStocks) * 100);
439
+ items.push({
440
+ id: "data-prepared",
441
+ label: "시장 데이터 준비",
442
+ status: "fail",
443
+ detail: `${depthStats.deepStocks.toLocaleString()} / ${MIN_DEEP_STOCKS}+ 필요 (${depthStats.totalStocks.toLocaleString()} 종목 중 ${pct}% 깊이)${hint}`,
444
+ blocking: true,
445
+ });
446
+ }
447
+ }
378
448
  const blocking = items.filter((i) => i.blocking);
379
449
  const okCount = blocking.filter((i) => i.status === "ok").length;
380
450
  const report = {
@@ -1 +1 @@
1
- {"version":3,"file":"readiness.js","sourceRoot":"","sources":["../../src-server/readiness.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"readiness.js","sourceRoot":"","sources":["../../src-server/readiness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACvF,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC;;;GAGG;AACH,MAAM,4BAA4B,GAAG,GAAG,CAAC;AACzC,iDAAiD;AACjD,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B,2DAA2D;AAC3D,SAAS,mBAAmB;IAC1B,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,qDAAqD,CAAC,CAAC,GAAG,EAAmB,CAAC;QAC1G,MAAM,OAAO,GAAG,EAAE;aACf,OAAO,CACN;;WAEG,CACJ;aACA,GAAG,CAAC,4BAA4B,CAAkB,CAAC;QACtD,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,2CAA2C;QAC3C,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC;AAmCD,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,MAAM,KAAK,GAAoB,EAAE,CAAC;IAElC,MAAM,WAAW,GAAG,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC;IAC1C,MAAM,QAAQ,GAAG,CAAC,CAAC,WAAW,IAAI,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAEjE,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,kBAAkB,CAAC;IAC1E,IAAI,IAAI,GAAwB,IAAI,CAAC;IACrC,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,aAAa;IACb,IAAI,CAAC;QACH,MAAM,OAAO,GAA2B,EAAE,eAAe,EAAE,UAAU,EAAE,CAAC;QACxE,IAAI,QAAQ;YAAE,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,WAAW,EAAE,CAAC;QACjE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,QAAQ;gBACZ,KAAK,EAAE,sBAAsB;gBAC7B,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE;gBAC5B,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAiB,CAAC;YAC1C,MAAM,GAAG,IAAI,CAAC;YACd,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,QAAQ;gBACZ,KAAK,EAAE,sBAAsB;gBAC7B,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,MAAM,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;gBAC/E,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,sBAAsB;YAC7B,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,UAAU,MAAM,CAAC,CAAC,CAAC,EAAE;YAC7B,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;IAED,WAAW;IACX,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,iBAAiB;YACzB,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,8BAA8B;YACtC,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,gCAAgC;YACxC,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE;YACvF,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;IAED,yCAAyC;IACzC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,eAAe;YACnB,KAAK,EAAE,uBAAuB;YAC9B,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,iBAAiB;YACzB,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,eAAe;YACnB,KAAK,EAAE,uBAAuB;YAC9B,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;YACnC,MAAM,EAAE,IAAI,EAAE,cAAc;gBAC1B,CAAC,CAAC,MAAM,IAAI,CAAC,cAAc,KAAK;gBAChC,CAAC,CAAC,oCAAoC;YACxC,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;IAED,yCAAyC;IACzC,MAAM,aAAa,GAAG,IAAI,EAAE,aAAa,IAAI,EAAE,CAAC;IAChD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,iBAAiB;YACzB,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,2BAA2B;YACnC,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,CAAC,IAAI,EAAE,aAAa,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9D,8BAA8B;QAC9B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,eAAe,CAAC,CAAC;YACxD,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,aAAa;gBACjB,KAAK,EAAE,YAAY;gBACnB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;gBACtC,MAAM,EAAE,MAAM,CAAC,OAAO;oBACpB,CAAC,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,OAAO,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,6BAA6B;oBAC9G,CAAC,CAAC,0BAA0B;gBAC9B,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,aAAa;gBACjB,KAAK,EAAE,YAAY;gBACnB,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,iBAAiB,MAAM,CAAC,CAAC,CAAC,EAAE;gBACpC,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;QACL,CAAC;IACH,CAAC;SAAM,CAAC;QACN,+CAA+C;QAC/C,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,IAAI,SAAS,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,eAAe,CAAC,CAAC;YACxD,IAAI,CAAC,MAAM,CAAC,OAAO;gBAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACpD,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;YACxC,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QACpC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,MAAM,WAAW,GAAa,EAAE,CAAC;QACjC,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,MAAM,EAAE,GAAG,MAAM,kBAAkB,CAAC,eAAe,EAAE,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;gBACpF,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;oBACf,SAAS,EAAE,CAAC;gBACd,CAAC;qBAAM,CAAC;oBACN,WAAW,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,YAAY,WAAW,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,WAAW,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC;QAElC,IAAI,MAAc,CAAC;QACnB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;YACf,MAAM,GAAG,MAAM,CAAC,MAAM;gBACpB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;gBACpB,CAAC,CAAC,UAAU,SAAS,MAAM,WAAW,CAAC,cAAc,EAAE,yBAAyB,CAAC;QACrF,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,SAAS;gBAChB,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;gBACzC,CAAC,CAAC,UAAU,SAAS,WAAW,SAAS,IAAI,IAAI,cAAc,CAAC;QACpE,CAAC;QAED,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;YACjC,MAAM;YACN,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;IAED,yBAAyB;IACzB,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,cAAc;YACrB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,uBAAuB;YAC/B,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,cAAc;gBACrB,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,wBAAwB;gBAChC,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;gBAClC,KAAK,CAAC,IAAI,CAAC;oBACT,EAAE,EAAE,KAAK;oBACT,KAAK,EAAE,kBAAkB,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE;oBAC3C,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;oBAClC,MAAM,EACJ,OAAO,CAAC,MAAM;wBACd,OAAO,CAAC,KAAK;wBACb,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;oBAC5D,QAAQ,EAAE,IAAI;iBACf,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,KAAK,CAAC,IAAI,CAAC;oBACT,EAAE,EAAE,KAAK;oBACT,KAAK,EAAE,kBAAkB,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE;oBAC3C,MAAM,EAAE,MAAM;oBACd,MAAM,EAAE,WAAW,MAAM,CAAC,CAAC,CAAC,EAAE;oBAC9B,QAAQ,EAAE,IAAI;iBACf,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,cAAc;YAClB,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,eAAe;YACvB,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,cAAc;YAClB,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,sCAAsC;YAC9C,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,cAAc;YAClB,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,YAAY,MAAM,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YACxF,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;IACL,CAAC;IAED,6BAA6B;IAC7B,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,4CAA4C;YACpD,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAChD,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,QAAQ;gBACZ,KAAK,EAAE,YAAY,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;gBACpD,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,wBAAwB;gBAChC,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC;gBACH,8BAA8B;gBAC9B,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC;oBACpC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM;oBACzB,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS;oBAC/B,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM;iBAC1B,CAAC,CAAC;gBACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,KAAK,CAAC,IAAI,CAAC;wBACT,EAAE,EAAE,QAAQ;wBACZ,KAAK,EAAE,YAAY,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;wBACpD,MAAM,EAAE,MAAM;wBACd,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,SAAS;4BAC9B,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,MAAM,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE;4BAC3D,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO;wBAC1B,QAAQ,EAAE,IAAI;qBACf,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,iCAAiC;oBACjC,MAAM,UAAU,GAAG,MAAM,UAAU,EAAE,CAAC;oBACtC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;wBACnB,KAAK,CAAC,IAAI,CAAC;4BACT,EAAE,EAAE,QAAQ;4BACZ,KAAK,EAAE,YAAY,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;4BACpD,MAAM,EAAE,MAAM;4BACd,MAAM,EAAE,sBAAsB,UAAU,CAAC,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE;4BAC/H,QAAQ,EAAE,IAAI;yBACf,CAAC,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC;wBAC1B,KAAK,CAAC,IAAI,CAAC;4BACT,EAAE,EAAE,QAAQ;4BACZ,KAAK,EAAE,YAAY,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;4BACpD,MAAM,EAAE,IAAI;4BACZ,MAAM,EAAE,GAAG,SAAS,kBAAkB,CAAC,CAAC,eAAe,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,YAAY,CAAC,cAAc,EAAE,IAAI;4BACpH,QAAQ,EAAE,IAAI;yBACf,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,KAAK,CAAC,IAAI,CAAC;oBACT,EAAE,EAAE,QAAQ;oBACZ,KAAK,EAAE,YAAY,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;oBACpD,MAAM,EAAE,MAAM;oBACd,MAAM,EAAE,UAAU,MAAM,CAAC,CAAC,CAAC,EAAE;oBAC7B,QAAQ,EAAE,IAAI;iBACf,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACrC,wBAAwB;QACxB,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,cAAc;YACrB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,8BAA8B;YACtC,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;4DAOwD;IACxD,MAAM,UAAU,GAAG,mBAAmB,EAAE,CAAC;IACzC,IAAI,UAAU,CAAC,UAAU,IAAI,eAAe,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,eAAe;YACnB,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,GAAG,UAAU,CAAC,UAAU,CAAC,cAAc,EAAE,QAAQ,4BAA4B,QAAQ,UAAU,CAAC,WAAW,CAAC,cAAc,EAAE,GAAG;YACvI,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,+CAA+C;QAC/C,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO;YACvB,CAAC,CAAC,yBAAyB,IAAI,CAAC,OAAO,CAAC,KAAK,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,EAAE,OAAO;YAChG,CAAC,CAAC,6CAA6C,CAAC;QAElD,IAAI,UAAU,CAAC,WAAW,KAAK,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,eAAe;gBACnB,KAAK,EAAE,WAAW;gBAClB,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,aAAa,IAAI,EAAE;gBAC3B,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC;YAC/E,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,eAAe;gBACnB,KAAK,EAAE,WAAW;gBAClB,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,GAAG,UAAU,CAAC,UAAU,CAAC,cAAc,EAAE,MAAM,eAAe,SAAS,UAAU,CAAC,WAAW,CAAC,cAAc,EAAE,SAAS,GAAG,QAAQ,IAAI,EAAE;gBAChJ,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;IACjE,MAAM,MAAM,GAAoB;QAC9B,KAAK,EAAE,OAAO,KAAK,QAAQ,CAAC,MAAM;QAClC,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,CAAC,MAAM,EAAE;QACvD,KAAK;QACL,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACrC,CAAC;IAEF,6DAA6D;IAC7D,IAAI,IAAI,EAAE,aAAa,IAAI,QAAQ,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,SAAS,EAAE;gBACrB,OAAO,EAAE;oBACP,eAAe,EAAE,UAAU;oBAC3B,eAAe,EAAE,UAAU,WAAW,EAAE;oBACxC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC;wBAC5B,KAAK,EAAE,MAAM,CAAC,KAAK;wBACnB,KAAK,EAAE,MAAM,CAAC,KAAK;wBACnB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BAC9B,EAAE,EAAE,CAAC,CAAC,EAAE;4BACR,KAAK,EAAE,CAAC,CAAC,KAAK;4BACd,MAAM,EAAE,CAAC,CAAC,MAAM;4BAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;4BACpB,MAAM,EAAE,CAAC,CAAC,MAAM;yBACjB,CAAC,CAAC;wBACH,UAAU,EAAE,MAAM,CAAC,UAAU;qBAC9B,CAAC;iBACH;aACF,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,6 +1,8 @@
1
1
  import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
2
4
  import { z } from "zod";
3
- import { loadConfig, saveConfig, maskedConfig, mergeConfigPatch, DEFAULT_CONFIG, CONFIG_PATHS, SERVER_BASE_URL, } from "./config.js";
5
+ import { loadConfig, saveConfig, maskedConfig, mergeConfigPatch, DEFAULT_CONFIG, CONFIG_PATHS, SERVER_BASE_URL, getCurrentUserId, resetAllLocalData, } from "./config.js";
4
6
  import { createLlmProvider } from "./llm/index.js";
5
7
  import { fetchCommonBundle, fetchPersonaBundle, assembleFullPrompt } from "./bundle.js";
6
8
  import { runReadinessCheck } from "./readiness.js";
@@ -14,12 +16,34 @@ import { getStockUniverse, getStandardUniverse, getMarketIndex, getAllSectorIndi
14
16
  import { countUniverse, getSyncMeta, listUniverse, vacuumWatchersOlderThan, watchersTableStats } from "./db/sqlite.js";
15
17
  import { runUniverseSync } from "./jobs/universe-sync.js";
16
18
  import { runScreener } from "./screener/engine.js";
17
- import { loadPersona, reloadPersona, PERSONA_OVERRIDE_DIR } from "./personas/loader.js";
19
+ import { loadPersona, reloadPersona, getPersonaOverrideDir } from "./personas/loader.js";
18
20
  import { listAvailablePersonas, runPersonaScreening } from "./personas/runner.js";
19
21
  // SPEC-27 (ADR-011): executePersonaDecision 폐기 → executePersonaCycle (lazy import)
20
22
  import { fetchServerSubscriptions, getLastSync } from "./server-sync.js";
23
+ import { isAdmin } from "./auth/admin.js";
21
24
  import { writeDiary, readDiary, listDiariesForPersona } from "./diary/writer.js";
22
25
  import { extractWakePlan, registerWakePlan } from "./personas/wake-plan.js";
26
+ // package.json 의 version 을 build 시점이 아닌 runtime 에 read (dist/server/routes.js 기준
27
+ // 으로 ../../package.json 위치). Test 환경에선 src-server/routes.ts 기준.
28
+ function readPackageVersion() {
29
+ try {
30
+ const here = path.dirname(fileURLToPath(import.meta.url));
31
+ // dist/server/routes.js → dist/server → dist → apps/client/package.json
32
+ // src-server/routes.ts → src-server → apps/client/package.json
33
+ for (const candidate of [
34
+ path.resolve(here, "../../package.json"),
35
+ path.resolve(here, "../package.json"),
36
+ ]) {
37
+ if (fs.existsSync(candidate)) {
38
+ const pkg = JSON.parse(fs.readFileSync(candidate, "utf-8"));
39
+ return pkg.version ?? "0.0.0";
40
+ }
41
+ }
42
+ }
43
+ catch { /* ignore */ }
44
+ return "0.0.0";
45
+ }
46
+ const PKG_VERSION = readPackageVersion();
23
47
  export async function registerRoutes(app) {
24
48
  // ── 헬스체크 ────────────────────────────────────────────────
25
49
  app.get("/api/health", async () => {
@@ -27,7 +51,7 @@ export async function registerRoutes(app) {
27
51
  return {
28
52
  ok: true,
29
53
  service: "@mulsok/client",
30
- version: "0.0.0",
54
+ version: PKG_VERSION,
31
55
  node: process.version,
32
56
  config: {
33
57
  present: fs.existsSync(CONFIG_PATHS.file),
@@ -55,8 +79,38 @@ export async function registerRoutes(app) {
55
79
  const existing = loadConfig();
56
80
  try {
57
81
  const merged = mergeConfigPatch(existing, body);
58
- const saved = saveConfig(merged);
59
- return { ok: true, config: maskedConfig(saved) };
82
+ // token 변경됐으면 (다른 user 의 것일 수 있으므로) 캐시된 user 식별
83
+ // 정보는 즉시 비움. 다음 ping 응답으로 server 가 새 user_id 알려주면
84
+ // server-sync 가 cfg.auth.userId 채움.
85
+ const oldTok = existing.auth?.deviceToken;
86
+ const newTok = merged.auth?.deviceToken;
87
+ const tokenChanged = newTok !== oldTok;
88
+ if (tokenChanged) {
89
+ merged.auth = {
90
+ ...merged.auth,
91
+ userId: undefined,
92
+ userEmail: undefined,
93
+ };
94
+ merged.subscriptions = [];
95
+ }
96
+ saveConfig(merged);
97
+ // 어떤 config 섹션 변경이든 token 이 있으면 ping 발사.
98
+ // 응답 시점까지 대기 — 그 결과 cfg.auth.userId 가 갱신된 후에 응답
99
+ // 보내야 caller (webui) 가 인증 완료 상태의 config 를 즉시 읽을 수 있음.
100
+ // (이전엔 fire-and-forget 으로 race condition · webui banner 가
101
+ // 「⏳ 인증 중」 에서 멈춰 있었음 — 새로고침 해야 풀림)
102
+ const tokAfter = loadConfig().auth?.deviceToken;
103
+ if (tokAfter && tokAfter.startsWith("mtd_")) {
104
+ try {
105
+ await fetchServerSubscriptions();
106
+ }
107
+ catch (e) {
108
+ console.warn("[/api/config] ping 동기 실패 (config 저장은 OK):", e);
109
+ }
110
+ }
111
+ // ping 끝난 후 최신 config 읽어서 응답 (auth.userId/userEmail 채워진 상태)
112
+ const finalCfg = loadConfig();
113
+ return { ok: true, config: maskedConfig(finalCfg) };
60
114
  }
61
115
  catch (e) {
62
116
  const issues = e.issues;
@@ -64,6 +118,153 @@ export async function registerRoutes(app) {
64
118
  return { ok: false, error: "스키마 오류", issues };
65
119
  }
66
120
  });
121
+ // ── 자격증명 명시 제거 (DELETE) ─────────────────────────────
122
+ // mergeConfigPatch 의 secret-preserve 규칙 때문에 POST /api/config 로는
123
+ // 비우기가 불가능. 명시적 「제거」 API 분리.
124
+ /**
125
+ * DELETE /api/auth/device-token · 「로그아웃」 의미.
126
+ *
127
+ * 동작:
128
+ * - cfg.auth (deviceToken / userId / userEmail) 모두 비움
129
+ * - 메모리 watchers 정리 (이전 user 의 active watchers)
130
+ *
131
+ * 보존 (v2 schema 핵심):
132
+ * - users[<userId>] 의 LLM / broker / subscriptions / allocations 그대로
133
+ * → 재로그인 시 즉시 복원
134
+ * - LOCAL fs (state.json · diary · trade-journal · watchers DB) 그대로
135
+ *
136
+ * 명시적 wipe 는 POST /api/local/reset 사용.
137
+ */
138
+ app.delete("/api/auth/device-token", async () => {
139
+ const cfg = loadConfig();
140
+ const cleared = saveConfig({
141
+ ...cfg,
142
+ auth: { ...cfg.auth, deviceToken: undefined, userId: undefined, userEmail: undefined },
143
+ });
144
+ try {
145
+ getConditionWatcher().clearAll();
146
+ }
147
+ catch {
148
+ /* ignore */
149
+ }
150
+ return { ok: true, config: maskedConfig(cleared) };
151
+ });
152
+ /** DELETE /api/broker · broker 자격증명 제거 (kind=none, key/secret 비움) */
153
+ app.delete("/api/broker", async () => {
154
+ const cfg = loadConfig();
155
+ const cleared = saveConfig({
156
+ ...cfg,
157
+ broker: { kind: "none", appKey: undefined, appSecret: undefined, isDemo: true },
158
+ });
159
+ // server 의 readiness 도 즉시 갱신 (kiwoom_connected:false 반영) →
160
+ // dashboard 가 「broker 제거됐음」 을 본인 새로고침 없이 알 수 있도록.
161
+ if (cleared.auth?.deviceToken?.startsWith("mtd_")) {
162
+ void fetchServerSubscriptions();
163
+ }
164
+ return { ok: true, config: maskedConfig(cleared) };
165
+ });
166
+ /** DELETE /api/llm · LLM 설정 제거 (provider=none, apiKey 비움) */
167
+ app.delete("/api/llm", async () => {
168
+ const cfg = loadConfig();
169
+ const cleared = saveConfig({
170
+ ...cfg,
171
+ llm: { provider: "none", apiKey: undefined, model: undefined, claudeCli: undefined },
172
+ });
173
+ if (cleared.auth?.deviceToken?.startsWith("mtd_")) {
174
+ void fetchServerSubscriptions();
175
+ }
176
+ return { ok: true, config: maskedConfig(cleared) };
177
+ });
178
+ /**
179
+ * GET /api/me/identity · 현재 인증된 user 정보.
180
+ *
181
+ * 응답:
182
+ * { authenticated: true, userId: "...", userEmail: "...", deviceToken: "(masked)" }
183
+ * { authenticated: false }
184
+ *
185
+ * webui 가 「현재 user: <email>」 표시에 사용. server-sync lastSync 결과
186
+ * 도 함께 반환해 인증 실패 banner 등 UX 결정 가능.
187
+ */
188
+ app.get("/api/me/identity", async () => {
189
+ const cfg = loadConfig();
190
+ const tok = cfg.auth?.deviceToken;
191
+ const userId = cfg.auth?.userId;
192
+ const userEmail = cfg.auth?.userEmail;
193
+ const last = getLastSync();
194
+ return {
195
+ authenticated: !!userId,
196
+ userId: userId ?? null,
197
+ userEmail: userEmail ?? null,
198
+ hasToken: !!tok,
199
+ // Phase 5e-0 — admin 판정 (ENV 기반 · web 의 isAdmin 과 동일 default)
200
+ isAdmin: isAdmin(userEmail),
201
+ lastSyncedAt: last?.syncedAt ?? null,
202
+ lastAuthenticated: last?.authenticated ?? false,
203
+ lastError: last?.error ?? null,
204
+ };
205
+ });
206
+ /**
207
+ * POST /api/local/reset · ~/.mulsok-traders/ 사용자 데이터 일체 삭제 (위험).
208
+ *
209
+ * 삭제 대상:
210
+ * - u/ (모든 user 의 user-scoped 데이터)
211
+ * - personas/, diary/, trade-journal/, layer3-patches/, watchers.db
212
+ * (구버전에서 남은 글로벌 잔재)
213
+ * - config.json (모든 자격증명)
214
+ *
215
+ * 보존: market.db (universe + candles · 글로벌 시장 데이터 · 재 sync 비용 큼),
216
+ * krx-holidays.json, logs/
217
+ *
218
+ * 호출 후 사용자가 client 재시작 권장 (메모리에 떠 있는 PriceFeed/Watcher 정리 위함).
219
+ */
220
+ /**
221
+ * POST /api/local/server-sync · 강제 server-sync ping
222
+ *
223
+ * 일반 흐름: startPeriodicSync(3600s) 가 1시간 주기로 자동 ping. 단 watcher
224
+ * 등록·해제·trade 발생 직후 즉시 web 측 readiness 갱신 원할 때 trigger.
225
+ */
226
+ app.post("/api/local/server-sync", async () => {
227
+ const result = await fetchServerSubscriptions();
228
+ return { ok: result.ok, syncedAt: result.syncedAt, error: result.error };
229
+ });
230
+ app.post("/api/local/reset", async (req, reply) => {
231
+ const body = (req.body ?? {});
232
+ if (body.confirm !== "RESET-MY-LOCAL-DATA") {
233
+ reply.code(400);
234
+ return {
235
+ ok: false,
236
+ error: "확인 문자열 필요 — body 에 { confirm: \"RESET-MY-LOCAL-DATA\" }",
237
+ };
238
+ }
239
+ // 메모리 정리 (LOCAL DB / config 삭제 전)
240
+ try {
241
+ getConditionWatcher().clearAll();
242
+ }
243
+ catch {
244
+ /* ignore */
245
+ }
246
+ const removed = [];
247
+ // user-scoped + legacy global 모두 삭제
248
+ const r = resetAllLocalData();
249
+ removed.push(...r.removed);
250
+ // config.json 도 삭제
251
+ try {
252
+ if (fs.existsSync(CONFIG_PATHS.file)) {
253
+ fs.rmSync(CONFIG_PATHS.file, { force: true });
254
+ removed.push("config.json");
255
+ }
256
+ }
257
+ catch (e) {
258
+ console.warn("[local/reset] config.json 삭제 실패:", e);
259
+ }
260
+ // 새 default config 즉시 저장 (다음 요청들이 안전하게 동작)
261
+ saveConfig(DEFAULT_CONFIG);
262
+ return {
263
+ ok: true,
264
+ removed,
265
+ hint: "정상 가동을 위해 클라이언트를 재시작 (또는 dev 환경이면 자동 reload).",
266
+ };
267
+ });
67
268
  // ── Readiness Check · 거래 준비 상태 종합 ──────────────────
68
269
  app.get("/api/readiness", async () => {
69
270
  return runReadinessCheck();
@@ -306,7 +507,9 @@ export async function registerRoutes(app) {
306
507
  // SQLite watchers 테이블 누적 통계 (P1-4 보강 · 모니터링용 · vacuum 시점 판단)
307
508
  let dbStats = null;
308
509
  try {
309
- dbStats = watchersTableStats();
510
+ const userId = getCurrentUserId();
511
+ if (userId)
512
+ dbStats = watchersTableStats(userId);
310
513
  }
311
514
  catch (e) {
312
515
  // SQLite 일시 장애 등 — 응답에 영향 X
@@ -351,7 +554,7 @@ export async function registerRoutes(app) {
351
554
  const q = req.query;
352
555
  const slugs = (q.slugs ?? "neoul").split(",").map((s) => s.trim()).filter(Boolean);
353
556
  const results = await listAvailablePersonas(slugs);
354
- return { ok: true, items: results, overrideDir: PERSONA_OVERRIDE_DIR };
557
+ return { ok: true, items: results, overrideDir: getPersonaOverrideDir() };
355
558
  });
356
559
  app.post("/api/personas/:personaId/reload", async (req, reply) => {
357
560
  const { personaId } = req.params;
@@ -632,7 +835,12 @@ export async function registerRoutes(app) {
632
835
  app.post("/api/diary/:slug/write", async (req, reply) => {
633
836
  const { slug } = req.params;
634
837
  const body = (req.body ?? {});
635
- const r = await writeDiary(slug, { overwrite: body.overwrite });
838
+ // body.date yyyy-mm-dd 형식이면 날짜 backfill (누락 일기 채우기).
839
+ if (body.date && !/^\d{4}-\d{2}-\d{2}$/.test(body.date)) {
840
+ reply.code(400);
841
+ return { ok: false, error: "date 형식: yyyy-mm-dd (예: 2026-05-08)" };
842
+ }
843
+ const r = await writeDiary(slug, { overwrite: body.overwrite, date: body.date, force: body.force });
636
844
  if (!r.ok) {
637
845
  reply.code(500);
638
846
  return r;
@@ -1102,9 +1310,14 @@ export async function registerRoutes(app) {
1102
1310
  return { ok: false, error: "days 는 1 이상 정수" };
1103
1311
  }
1104
1312
  try {
1105
- const before = watchersTableStats();
1106
- const removed = vacuumWatchersOlderThan(days);
1107
- const after = watchersTableStats();
1313
+ const userId = getCurrentUserId();
1314
+ if (!userId) {
1315
+ reply.code(409);
1316
+ return { ok: false, error: "user_id 미설정 — 토큰 등록 후 재시도" };
1317
+ }
1318
+ const before = watchersTableStats(userId);
1319
+ const removed = vacuumWatchersOlderThan(userId, days);
1320
+ const after = watchersTableStats(userId);
1108
1321
  return {
1109
1322
  ok: true,
1110
1323
  days,
@@ -1125,6 +1338,11 @@ export async function registerRoutes(app) {
1125
1338
  maxCodes: body.maxCodes ?? 50,
1126
1339
  candleDays: body.candleDays ?? 120,
1127
1340
  targetCodes: body.targetCodes,
1341
+ onProgress: (done, total, lastCode) => {
1342
+ if (done % 50 === 0 || done === total) {
1343
+ console.log(`[local/sync] ${done}/${total} · last=${lastCode ?? "-"}`);
1344
+ }
1345
+ },
1128
1346
  });
1129
1347
  return { ok: true, result: r };
1130
1348
  }
@@ -1133,6 +1351,72 @@ export async function registerRoutes(app) {
1133
1351
  return { ok: false, error: String(e) };
1134
1352
  }
1135
1353
  });
1354
+ /**
1355
+ * Phase 5e-1a · admin 시세 스냅샷 export.
1356
+ * VACUUM INTO + gzip → ~/.mulsok-traders/u/<userId>/share/market-YYYY-MM-DD.sqlite.gz
1357
+ * Storage 업로드는 5e-1b 별도 phase.
1358
+ */
1359
+ app.post("/api/admin/share/dump", async (req, reply) => {
1360
+ void req;
1361
+ const cfg = loadConfig();
1362
+ if (!isAdmin(cfg.auth?.userEmail)) {
1363
+ reply.code(403);
1364
+ return { ok: false, error: "admin 전용 명령" };
1365
+ }
1366
+ const { exportSnapshot } = await import("./share/snapshot.js");
1367
+ const r = await exportSnapshot();
1368
+ if (!r.ok) {
1369
+ reply.code(500);
1370
+ }
1371
+ return r;
1372
+ });
1373
+ /**
1374
+ * Phase 5e-4 · 명시적 prepare (시세 데이터 download) 시작.
1375
+ * 첫 install 사용자가 cycle 시도 전 진행률 가시화 위해 호출.
1376
+ * 이미 running 이면 trigger 안 하고 같은 state 공유.
1377
+ */
1378
+ app.post("/api/prepare/start", async (req, reply) => {
1379
+ void req;
1380
+ void reply;
1381
+ const { startPrepare } = await import("./share/prepare.js");
1382
+ return startPrepare();
1383
+ });
1384
+ /**
1385
+ * Phase 5e-4 · prepare 진행 상태 polling.
1386
+ * CLI / WebUI 가 1초 간격으로 호출 — progress bar 갱신.
1387
+ */
1388
+ app.get("/api/prepare/status", async (req, reply) => {
1389
+ void req;
1390
+ void reply;
1391
+ const { getPrepareState } = await import("./share/prepare-state.js");
1392
+ return getPrepareState();
1393
+ });
1394
+ /**
1395
+ * Phase 5e-1' · admin SQLite → Supabase Postgres bulk publish.
1396
+ * 환경변수: SUPABASE_URL · SUPABASE_SERVICE_ROLE_KEY (~/.mulsok-traders/.env)
1397
+ */
1398
+ app.post("/api/admin/share/publish-postgres", async (req, reply) => {
1399
+ const cfg = loadConfig();
1400
+ if (!isAdmin(cfg.auth?.userEmail)) {
1401
+ reply.code(403);
1402
+ return { ok: false, error: "admin 전용 명령" };
1403
+ }
1404
+ const body = (req.body ?? {});
1405
+ const { publishToPostgres } = await import("./share/postgres-publish.js");
1406
+ const r = await publishToPostgres({
1407
+ universeOnly: body.universeOnly,
1408
+ candlesOnly: body.candlesOnly,
1409
+ onProgress: (kind, done, total) => {
1410
+ if (done % 10000 === 0 || done === total) {
1411
+ console.log(`[publish-postgres] ${kind} ${done}/${total}`);
1412
+ }
1413
+ },
1414
+ });
1415
+ if (!r.ok) {
1416
+ reply.code(500);
1417
+ }
1418
+ return r;
1419
+ });
1136
1420
  /**
1137
1421
  * 너울 양음양 타겟 배치:
1138
1422
  * ka10031 전일 거래량 상위 (KOSPI + KOSDAQ) + 현재 보유 종목 → 일봉 배치.
@@ -1154,9 +1438,12 @@ export async function registerRoutes(app) {
1154
1438
  if (kosdaqVol.ok)
1155
1439
  for (const r of kosdaqVol.data)
1156
1440
  codes.add(r.symbolCode);
1157
- if (holdingsRes.ok)
1441
+ // holdings.symbolCode 는 account.ts 에서 이미 정규화 후 반환. 안전망 + 단일 helper.
1442
+ if (holdingsRes.ok) {
1443
+ const { normalizeKiwoomCode } = await import("./broker/kiwoom/_helpers/symbol-code.js");
1158
1444
  for (const h of holdingsRes.data.items)
1159
- codes.add(h.symbolCode.replace(/^A/, ""));
1445
+ codes.add(normalizeKiwoomCode(h.symbolCode));
1446
+ }
1160
1447
  const r = await runUniverseSync({
1161
1448
  candleDays,
1162
1449
  targetCodes: Array.from(codes),