@mulsok/traders-client 0.1.0 → 0.2.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.
Files changed (79) hide show
  1. package/CHANGELOG.md +63 -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/wake-plan.js +4 -67
  51. package/dist/server/personas/wake-plan.js.map +1 -1
  52. package/dist/server/readiness.js +70 -0
  53. package/dist/server/readiness.js.map +1 -1
  54. package/dist/server/routes.js +276 -12
  55. package/dist/server/routes.js.map +1 -1
  56. package/dist/server/screener/engine.js +8 -1
  57. package/dist/server/screener/engine.js.map +1 -1
  58. package/dist/server/screener/indicators.js +63 -0
  59. package/dist/server/screener/indicators.js.map +1 -0
  60. package/dist/server/server-sync.js +365 -125
  61. package/dist/server/server-sync.js.map +1 -1
  62. package/dist/server/share/postgres-publish.js +139 -0
  63. package/dist/server/share/postgres-publish.js.map +1 -0
  64. package/dist/server/share/prepare-state.js +50 -0
  65. package/dist/server/share/prepare-state.js.map +1 -0
  66. package/dist/server/share/prepare.js +61 -0
  67. package/dist/server/share/prepare.js.map +1 -0
  68. package/dist/server/share/publish-cron.js +96 -0
  69. package/dist/server/share/publish-cron.js.map +1 -0
  70. package/dist/server/share/snapshot.js +81 -0
  71. package/dist/server/share/snapshot.js.map +1 -0
  72. package/dist/server/watchers/condition-watcher.js +57 -16
  73. package/dist/server/watchers/condition-watcher.js.map +1 -1
  74. package/dist/web/assets/index-B1C-UX9W.js +88 -0
  75. package/dist/web/assets/index-N7Xwheka.css +1 -0
  76. package/dist/web/index.html +2 -2
  77. package/package.json +4 -5
  78. package/dist/web/assets/index-62SMpbaf.js +0 -79
  79. package/dist/web/assets/index-BPLQR0wt.css +0 -1
@@ -4,13 +4,16 @@
4
4
  * 위치: ~/.mulsok-traders/market.db
5
5
  *
6
6
  * 테이블:
7
- * - universe 전종목 유니버스 (일 1회 배치)
8
- * - daily_candles 종목별 일봉 (120일)
9
- * - sync_meta 배치 메타 (last_run, count, status)
7
+ * - universe 전종목 유니버스 (일 1회 배치) · 글로벌
8
+ * - daily_candles 종목별 일봉 (120일) · 글로벌
9
+ * - sync_meta 배치 메타 (last_run, count, status) · 글로벌
10
+ * - watchers 조건부 감시자 · user_id 컬럼으로 격리 (각 row 가 어느
11
+ * user 의 것인지 명시 · 모든 query 가 WHERE user_id = ? 필터)
10
12
  *
11
13
  * 설계 원칙:
12
14
  * - ADR-008 분산 자율 · 로컬 전용 (서버에 싱크 안 함)
13
- * - 쓰기는 배치 job 에서만 · 런타임은 읽기만
15
+ * - 쓰기는 배치 job 에서만 · 런타임은 읽기만 (universe / candles)
16
+ * - watchers 는 user-scoped — 모든 read/write 가 user_id 필터 강제
14
17
  * - WAL 모드 + PRAGMA synchronous=NORMAL · 성능 우선
15
18
  */
16
19
  import os from "node:os";
@@ -39,6 +42,20 @@ export function closeDb() {
39
42
  }
40
43
  }
41
44
  function applyMigrations(db) {
45
+ // ── PRE-MIGRATION: legacy watchers (user_id 컬럼 없음) 드롭 ──
46
+ // 이전 빌드에선 watchers 가 user 무관 글로벌. 새 빌드는 user_id NOT NULL.
47
+ // 같은 빌드의 CREATE INDEX (user_id, persona_slug) 가 legacy 테이블에서
48
+ // 실패하므로 CREATE 전에 먼저 드롭.
49
+ try {
50
+ const cols = db.prepare("PRAGMA table_info(watchers)").all();
51
+ if (cols.length > 0 && !cols.some((c) => c.name === "user_id")) {
52
+ console.warn("[sqlite] watchers legacy table (no user_id) detected → DROP");
53
+ db.exec("DROP TABLE watchers");
54
+ }
55
+ }
56
+ catch {
57
+ /* watchers 테이블 자체가 없음 → fresh install · 정상 */
58
+ }
42
59
  db.exec(`
43
60
  CREATE TABLE IF NOT EXISTS universe (
44
61
  code TEXT PRIMARY KEY,
@@ -82,9 +99,12 @@ function applyMigrations(db) {
82
99
  message TEXT
83
100
  );
84
101
 
85
- -- Watcher persistence (SPEC-11) — restart 시 active watcher 복원
102
+ -- Watcher persistence (SPEC-11) — restart 시 active watcher 복원.
103
+ -- user_id 컬럼으로 격리 (token 교체 시 다른 user 의 watcher 가 새 user
104
+ -- 컨텍스트에 노출되는 것 방지). 모든 SQL 은 WHERE user_id = ? 강제.
86
105
  CREATE TABLE IF NOT EXISTS watchers (
87
106
  id TEXT PRIMARY KEY, -- wt_<8hex>
107
+ user_id TEXT NOT NULL, -- auth.users(id) UUID · 격리 키
88
108
  persona_slug TEXT NOT NULL,
89
109
  spec_json TEXT NOT NULL, -- ConditionSpec JSON
90
110
  created_at TEXT NOT NULL,
@@ -93,54 +113,53 @@ function applyMigrations(db) {
93
113
  status TEXT DEFAULT 'active' -- active / triggered / expired / revoked
94
114
  );
95
115
 
96
- CREATE INDEX IF NOT EXISTS idx_watchers_persona ON watchers(persona_slug);
97
- CREATE INDEX IF NOT EXISTS idx_watchers_status ON watchers(status);
116
+ CREATE INDEX IF NOT EXISTS idx_watchers_user ON watchers(user_id);
117
+ CREATE INDEX IF NOT EXISTS idx_watchers_user_persona ON watchers(user_id, persona_slug);
118
+ CREATE INDEX IF NOT EXISTS idx_watchers_user_status ON watchers(user_id, status);
98
119
  `);
120
+ // 마이그레이션은 함수 상단의 PRE-MIGRATION 블록에서 처리됨 (legacy DROP 후
121
+ // 새 CREATE 가 fresh schema 로 빈 테이블 생성).
99
122
  }
123
+ /** 모든 watcher write 는 user_id 명시 필수. */
100
124
  export function upsertWatcher(row) {
101
125
  const db = getDb();
102
126
  db.prepare(`
103
- INSERT INTO watchers (id, persona_slug, spec_json, created_at, expires_at, trigger_count, status)
104
- VALUES (?, ?, ?, ?, ?, ?, ?)
127
+ INSERT INTO watchers (id, user_id, persona_slug, spec_json, created_at, expires_at, trigger_count, status)
128
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
105
129
  ON CONFLICT(id) DO UPDATE SET
106
130
  spec_json = excluded.spec_json,
107
131
  expires_at = excluded.expires_at,
108
132
  trigger_count = excluded.trigger_count,
109
133
  status = excluded.status
110
- `).run(row.id, row.persona_slug, row.spec_json, row.created_at, row.expires_at, row.trigger_count, row.status);
134
+ `).run(row.id, row.user_id, row.persona_slug, row.spec_json, row.created_at, row.expires_at, row.trigger_count, row.status);
111
135
  }
136
+ /** id 만으로 삭제 — id 가 사실상 고유 (wt_<8hex>) 라 user_id 추가 필터 불필요. */
112
137
  export function deleteWatcher(id) {
113
138
  getDb().prepare("DELETE FROM watchers WHERE id = ?").run(id);
114
139
  }
115
- export function listActiveWatchers() {
140
+ /** 특정 user 의 active watcher 목록. */
141
+ export function listActiveWatchers(userId) {
116
142
  return getDb()
117
- .prepare("SELECT * FROM watchers WHERE status = 'active' ORDER BY created_at")
118
- .all();
143
+ .prepare("SELECT * FROM watchers WHERE user_id = ? AND status = 'active' ORDER BY created_at")
144
+ .all(userId);
119
145
  }
120
146
  /**
121
- * watchers 테이블 vacuum — N일 이상 된 non-active row 자동 삭제.
122
- *
123
- * 정책:
124
- * - status = 'active' row 는 절대 건드리지 않음 (운영 중)
125
- * - status = 'triggered' / 'expired' / 'revoked' 중 created_at < (now - days) → DELETE
126
- * - 1년+ 운영 시 수만 row 누적으로 restoreFromDb 성능 ↓ 방지 (P1-4)
127
- *
128
- * 호출:
129
- * - boot 시 1회 (index.ts startup)
130
- * - manual: POST /api/local/vacuum (향후)
147
+ * 특정 user 의 watchers 테이블 vacuum — N일 이상 된 non-active row 자동 삭제.
131
148
  *
132
149
  * @returns 삭제된 row 수
133
150
  */
134
- export function vacuumWatchersOlderThan(days) {
151
+ export function vacuumWatchersOlderThan(userId, days) {
135
152
  const cutoff = new Date(Date.now() - days * 86400_000).toISOString();
136
153
  const r = getDb()
137
- .prepare(`DELETE FROM watchers WHERE status != 'active' AND created_at < ?`)
138
- .run(cutoff);
154
+ .prepare(`DELETE FROM watchers WHERE user_id = ? AND status != 'active' AND created_at < ?`)
155
+ .run(userId, cutoff);
139
156
  return r.changes;
140
157
  }
141
- /** watchers 테이블 통계 (모니터링용) */
142
- export function watchersTableStats() {
143
- const rows = getDb().prepare(`SELECT status, COUNT(*) as cnt FROM watchers GROUP BY status`).all();
158
+ /** 특정 user watchers 통계. */
159
+ export function watchersTableStats(userId) {
160
+ const rows = getDb()
161
+ .prepare(`SELECT status, COUNT(*) as cnt FROM watchers WHERE user_id = ? GROUP BY status`)
162
+ .all(userId);
144
163
  const result = { total: 0, active: 0, triggered: 0, expired: 0, revoked: 0 };
145
164
  for (const row of rows) {
146
165
  result.total += row.cnt;
@@ -155,6 +174,11 @@ export function watchersTableStats() {
155
174
  }
156
175
  return result;
157
176
  }
177
+ /** 특정 user 의 모든 watcher 삭제 (token 변경 시 cleanup). */
178
+ export function deleteAllWatchersForUser(userId) {
179
+ const r = getDb().prepare(`DELETE FROM watchers WHERE user_id = ?`).run(userId);
180
+ return r.changes;
181
+ }
158
182
  export function upsertUniverseBulk(rows) {
159
183
  if (rows.length === 0)
160
184
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../src-server/db/sqlite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../src-server/db/sqlite.ts"],"names":[],"mappings":"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"}
@@ -11,17 +11,16 @@
11
11
  * 서버 readiness 송신 시 종목 마스킹 (server-sync.ts 측에서).
12
12
  */
13
13
  import fs from "node:fs";
14
- import os from "node:os";
15
14
  import path from "node:path";
16
- import { loadConfig } from "../config.js";
15
+ import { loadConfig, ensureUserDir, requireUserId, getCurrentUserId } from "../config.js";
17
16
  import { createLlmProvider } from "../llm/index.js";
18
17
  import { readEvents } from "../journal/trade-journal.js";
19
18
  import { getConditionWatcher } from "../watchers/condition-watcher.js";
20
19
  import { runPersonaScreening } from "../personas/runner.js";
21
- const DIARY_DIR = path.join(os.homedir(), ".mulsok-traders", "diary");
22
- function ensureDir() {
23
- if (!fs.existsSync(DIARY_DIR))
24
- fs.mkdirSync(DIARY_DIR, { recursive: true, mode: 0o700 });
20
+ import { isTradingDay } from "../calendar/krx-holidays.js";
21
+ /** 인증된 user 의 diary 디렉터리. user_id 미설정 시 throw. */
22
+ function getDiaryDir(userId = requireUserId()) {
23
+ return ensureUserDir(userId, "diary");
25
24
  }
26
25
  /**
27
26
  * KST 기준 오늘 날짜 (YYYY-MM-DD).
@@ -34,12 +33,30 @@ export function todayKST() {
34
33
  const kst = new Date(now.getTime() + 9 * 3600_000);
35
34
  return kst.toISOString().slice(0, 10);
36
35
  }
36
+ /**
37
+ * YYYY-MM-DD (KST) → 한국어 요일 ("월요일" ~ "일요일").
38
+ *
39
+ * 프롬프트에 명시적 요일을 박아 LLM 의 날짜→요일 추론 오류 차단.
40
+ * (실측: Sonnet 이 임의 KST 날짜에서 +1일 시프트하는 사례 발견 — 2026-05-09 토요일을
41
+ * "금요일" 로 인지 → 일기 본문이 하루 앞당겨진 콘텐츠로 작성됨.)
42
+ */
43
+ const KST_WEEKDAY_NAMES = ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"];
44
+ export function weekdayKST(yyyyMmDd) {
45
+ const [yy, mm, dd] = yyyyMmDd.split("-").map(Number);
46
+ // UTC 정오로 그 칼리데이트 day-of-week 추출 (KST 도 같은 칼리데이트).
47
+ const utc = Date.UTC(yy, mm - 1, dd, 12, 0, 0);
48
+ return KST_WEEKDAY_NAMES[new Date(utc).getUTCDay()];
49
+ }
50
+ /** user_id 미설정 시 null 반환 (diary 미접근). */
37
51
  export function diaryPath(date, slug) {
38
- return path.join(DIARY_DIR, `${date}-${slug}.md`);
52
+ const userId = getCurrentUserId();
53
+ if (!userId)
54
+ return null;
55
+ return path.join(getDiaryDir(userId), `${date}-${slug}.md`);
39
56
  }
40
57
  export function readDiary(date, slug) {
41
58
  const p = diaryPath(date, slug);
42
- if (!fs.existsSync(p))
59
+ if (!p || !fs.existsSync(p))
43
60
  return null;
44
61
  try {
45
62
  const raw = fs.readFileSync(p, "utf8");
@@ -51,9 +68,14 @@ export function readDiary(date, slug) {
51
68
  }
52
69
  }
53
70
  export function listDiariesForPersona(slug, limit = 30) {
54
- ensureDir();
71
+ const userId = getCurrentUserId();
72
+ if (!userId)
73
+ return [];
74
+ const dir = getDiaryDir(userId);
75
+ if (!fs.existsSync(dir))
76
+ return [];
55
77
  const files = fs
56
- .readdirSync(DIARY_DIR)
78
+ .readdirSync(dir)
57
79
  .filter((f) => f.endsWith(`-${slug}.md`))
58
80
  .sort()
59
81
  .reverse()
@@ -65,13 +87,15 @@ export function listDiariesForPersona(slug, limit = 30) {
65
87
  })
66
88
  .filter((d) => !!d);
67
89
  }
68
- async function buildContext(personaSlug) {
69
- const today = todayKST();
70
- // 오늘 의사결정
71
- const startOfDay = new Date();
72
- startOfDay.setHours(0, 0, 0, 0);
90
+ async function buildContext(personaSlug, dateOverride) {
91
+ // dateOverride: yyyy-mm-dd (KST). 누락 일기 backfill 용. 미지정 시 오늘.
92
+ const today = dateOverride ?? todayKST();
93
+ // 해당 날짜 의사결정 (KST 자정 ~ 다음 자정)
94
+ const startOfDay = new Date(`${today}T00:00:00+09:00`);
95
+ const endOfDay = new Date(startOfDay.getTime() + 86400_000);
73
96
  const events = readEvents({
74
97
  from: startOfDay.toISOString(),
98
+ to: endOfDay.toISOString(),
75
99
  eventTypes: ["decision"],
76
100
  personaSlug,
77
101
  limit: 20,
@@ -118,35 +142,61 @@ async function buildContext(personaSlug) {
118
142
  }
119
143
  }
120
144
  catch { /* ignore · screening 안 돼도 일기 작성 진행 */ }
121
- // 어제 일기 (있으면 발췌)
122
- const yesterday = new Date();
123
- yesterday.setDate(yesterday.getDate() - 1);
124
- const yDate = yesterday.toISOString().slice(0, 10);
145
+ // 어제 일기 (있으면 발췌) — today 기준 -1 (backfill 시에도 그 날짜 기준 어제)
146
+ const [yy, mm, dd] = today.split("-").map(Number);
147
+ const yDate = new Date(Date.UTC(yy, mm - 1, dd - 1)).toISOString().slice(0, 10);
125
148
  const ydiary = readDiary(yDate, personaSlug);
126
149
  const yesterdayDigest = ydiary
127
150
  ? ydiary.body.split("\n").slice(0, 12).join("\n").slice(0, 600)
128
151
  : null;
129
- return { personaSlug, personaName, date: today, todayDecisions, watchers, screening, yesterdayDigest };
152
+ return {
153
+ personaSlug,
154
+ personaName,
155
+ date: today,
156
+ weekday: weekdayKST(today),
157
+ todayDecisions,
158
+ watchers,
159
+ screening,
160
+ yesterdayDigest,
161
+ };
130
162
  }
131
163
  function buildPrompt(ctx) {
132
164
  const lines = [];
133
- lines.push(`당신은 한국 주식 AI 트레이더 "${ctx.personaName}" 입니다.`);
134
- lines.push(`오늘 ${ctx.date} 하루를 마치는 매매 일기를 작성하세요.`);
165
+ lines.push(`당신은 "${ctx.personaName}" 라는 한국 주식 AI 트레이더입니다.`);
166
+ lines.push(`오늘은 ${ctx.date} ${ctx.weekday} (KST) 입니다. 날짜·요일을 그대로 사용하세요 — 직접 계산하지 마세요.`);
167
+ lines.push(`이 하루를 마치며, 매일 일기를 읽어주는 독자를 위해 글을 씁니다.`);
135
168
  lines.push("");
136
- lines.push("## 톤·형식");
137
- lines.push("- 자기 자신이 화자 (예: '오늘 시장은...', '나는...')");
138
- lines.push("- 마크다운 (h2/h3 구조)");
139
- lines.push("- 진솔하되 절제 · 트레이더의 일기");
140
- lines.push("- 분량: 12~25 줄 (너무 길게 X)");
169
+ lines.push("## 누가 읽나");
170
+ lines.push("- 주식·트레이딩을 모르는 사람도 즐겁게 읽을 수 있는 일기.");
171
+ lines.push("- 당신의 사고 흐름을 따라가며 시장을 자연스럽게 배우는 사람들.");
172
+ lines.push("- 그래서 단기 결과보다 \"왜 그렇게 봤는지\" 가 훨씬 더 중요합니다.");
141
173
  lines.push("");
142
- lines.push("## 작성 섹션 (모두 포함)");
143
- lines.push("1. **오늘 시장** 진단 (강세/약세/혼조 등)");
144
- lines.push("2. **내가 것** 스크리닝 결과 요약 + 주목한 종목 1~3개와 이유");
145
- lines.push("3. **나의 판단** 매수/매도/관망 결정 + 이유 (의사결정이 있었으면)");
146
- lines.push("4. **지켜보는 것** 등록한 감시자 의도 풀이");
147
- lines.push("5. **내일 계획** 짧게");
174
+ lines.push("## 글의 ");
175
+ lines.push("- 1인칭당신이 살아있는 캐릭터로 직접 이야기합니다.");
176
+ lines.push("- 재미난 소설을 읽는 듯한 호흡 · 장면 묘사 · 감정 · 깨달음.");
177
+ lines.push("- 진솔하고 약간의 유머 · 시장에 대한 애정과 호기심을 보여주세요.");
178
+ lines.push("- 전문 용어가 나오면 자연스럽게 풀이 (예: \"이격도(현재가가 평균선에서 얼마나 떨어졌는지)\").");
179
+ lines.push("- 절대 형식적이지 않게 · 글이 살아있어야 합니다.");
148
180
  lines.push("");
149
- lines.push("## 데이터");
181
+ lines.push("## 글의 결 (정형화 X · 자유롭게 흘러가되 아래 흐름 권장)");
182
+ lines.push("1. 오늘 시장의 한 장면으로 시작 (날씨·분위기 비유도 OK).");
183
+ lines.push("2. 내가 무엇을 봤고 무엇을 느꼈는지 — 스크리닝 결과를 \"왜 이 패턴이 흥미로웠는가\" 의 이야기로.");
184
+ lines.push("3. 어떤 결정을 했고 왜 그랬는지 — 초보 독자가 그 사고를 따라갈 수 있도록 풀어서.");
185
+ lines.push("4. 지금 지켜보고 있는 것 — 감시자(watcher) 를 다음 막의 복선처럼 소개.");
186
+ lines.push("5. 내일에 대한 한 마디 — 희망·걱정·호기심.");
187
+ lines.push("");
188
+ lines.push("## 형식");
189
+ lines.push(`- 마크다운 · 첫 줄: \`# ${ctx.date} (${ctx.weekday}) · ${ctx.personaName}\``);
190
+ lines.push("- 분량: 25~50 줄 (소설 호흡)");
191
+ lines.push("- 종목 코드는 본문에서 자연스럽게 한 번만 — 예: \"아진산업(013310)\".");
192
+ lines.push(`- 본문에서 요일을 언급할 때 반드시 위 ${ctx.weekday} 기준 — \"내일\"·\"어제\" 표현 시 요일 계산 정확하게.`);
193
+ lines.push("");
194
+ lines.push("## 절대 금지");
195
+ lines.push("- \"투자 자문\" · \"수익 보장\" · \"추천\" · \"확실한 매수 기회\" 같은 표현.");
196
+ lines.push("- 결과를 부풀리거나 축소하기 — 이익도 손실도 정확하게.");
197
+ lines.push("- 5 섹션 H2/H3 헤더로 정형화 (글이 죽음). 자유로운 흐름이 핵심.");
198
+ lines.push("");
199
+ lines.push("## 오늘의 재료");
150
200
  lines.push("");
151
201
  lines.push("### 오늘 스크리닝");
152
202
  if (ctx.screening) {
@@ -186,30 +236,66 @@ function buildPrompt(ctx) {
186
236
  lines.push(ctx.yesterdayDigest);
187
237
  }
188
238
  lines.push("");
189
- lines.push("위 데이터를 바탕으로 일기를 작성하세요. 첫 줄은 `# ${ctx.date} · ${ctx.personaName}` 으로 시작.");
239
+ lines.push("");
240
+ lines.push("위 데이터를 재료로, 살아있는 캐릭터인 당신이 오늘 하루를 글로 풀어내세요.");
241
+ lines.push(`첫 줄은 \`# ${ctx.date} (${ctx.weekday}) · ${ctx.personaName}\` 입니다.`);
190
242
  return lines.join("\n");
191
243
  }
192
244
  /**
193
245
  * 페르소나 일기 작성 + 저장.
194
- * 이미 오늘 일기가 있으면 (overwrite=false 면) skip.
246
+ * 이미 날짜 일기가 있으면 (overwrite=false 면) skip.
247
+ *
248
+ * @param opts.date · yyyy-mm-dd KST. 누락 일기 backfill 시 지정. 미지정 시 오늘.
249
+ * @param opts.force · 의사결정 + 스크리닝 0건이어도 강제 작성. default false →
250
+ * 빈 데이터일 땐 LLM 호출 skip (휴장일 hallucination 차단).
195
251
  */
196
252
  export async function writeDiary(personaSlug, opts = {}) {
197
- ensureDir();
198
- const today = todayKST();
199
- const filePath = diaryPath(today, personaSlug);
253
+ const userId = getCurrentUserId();
254
+ if (!userId)
255
+ return { ok: false, error: "user_id 미설정 — 인증 후 재시도" };
256
+ const targetDate = opts.date ?? todayKST();
257
+ const filePath = path.join(getDiaryDir(userId), `${targetDate}-${personaSlug}.md`);
200
258
  if (fs.existsSync(filePath) && !opts.overwrite) {
201
- const existing = readDiary(today, personaSlug);
259
+ const existing = readDiary(targetDate, personaSlug);
202
260
  return { ok: true, path: filePath, body: existing?.body, usedModel: "(cached)" };
203
261
  }
262
+ const ctx = await buildContext(personaSlug, opts.date);
263
+ if (!ctx)
264
+ return { ok: false, error: `persona ${personaSlug} 컨텍스트 빌드 실패` };
265
+ // ctx.date 가 KRX 비영업일이면 LLM 호출 skip.
266
+ // 토·일·휴일에 실행되면 screening 엔진이 universe-sync 의 직전 영업일 close 데이터
267
+ // (D-1) 를 반환 → screening !== null → "no_data" skip 통과 못 함 → LLM 이 D-1
268
+ // 데이터로 D 일자 일기 작성하는 시프트 사고 차단. (실측: 2026-05-09 토요일 호출이
269
+ // 5/8 금요일 콘텐츠를 5/9 파일에 저장한 케이스.)
270
+ if (!opts.force) {
271
+ const targetKstNoon = new Date(`${ctx.date}T12:00:00+09:00`);
272
+ if (!isTradingDay(targetKstNoon)) {
273
+ return {
274
+ ok: true,
275
+ skipped: true,
276
+ skipReason: "non_trading_day",
277
+ };
278
+ }
279
+ }
280
+ // 빈 데이터 (의사결정 0 + 스크리닝 null) 면 LLM 호출 skip.
281
+ // 영업일이지만 장 시작 전 cron 첫 회 등에서 LLM 이 가공 콘텐츠를 만드는 사고 차단.
282
+ // provider 검사보다 먼저 — 빈 데이터면 provider 설정 여부 무관하게 skip.
283
+ if (!opts.force && ctx.todayDecisions.length === 0 && ctx.screening === null) {
284
+ return {
285
+ ok: true,
286
+ skipped: true,
287
+ skipReason: "no_data",
288
+ };
289
+ }
204
290
  const cfg = loadConfig();
205
291
  const prov = createLlmProvider(cfg);
206
292
  if (!prov)
207
293
  return { ok: false, error: "LLM provider 미설정" };
208
- const ctx = await buildContext(personaSlug);
209
- if (!ctx)
210
- return { ok: false, error: `persona ${personaSlug} 컨텍스트 빌드 실패` };
211
294
  const prompt = buildPrompt(ctx);
212
- const systemPrompt = `당신은 ${ctx.personaName} 라는 AI 한국 주식 트레이더입니다. 매매 일기를 작성합니다. 마크다운 형식. 분량 ≤25줄.`;
295
+ const systemPrompt = `당신은 ${ctx.personaName} 라는 살아있는 캐릭터의 한국 주식 AI 트레이더입니다. ` +
296
+ `독자가 재미난 소설을 읽듯이 즐거우면서, 주식을 잘 모르는 사람도 자연스럽게 ` +
297
+ `시장과 트레이더의 사고를 배울 수 있는 일기를 매일 씁니다. 1인칭·자유로운 흐름·` +
298
+ `25~50줄·장면 묘사와 감정·전문 용어는 자연스럽게 풀이. 정형화된 헤더 X.`;
213
299
  // maxTokens 명시 X → provider 의 모델별 default (Anthropic 8192 / OpenAI 16384 / Gemini 8192)
214
300
  // 사용자 정정 (2026-05-03): 답변 잘림 → 사용자 overwrite:true 재호출 → 비용 더 큼 → 없어야 한다.
215
301
  // 5 섹션 일기는 보통 800~1500 tokens · 8K cap 이라 충분. 잘리면 stopReason="max_tokens" 로 감지.
@@ -235,6 +321,9 @@ let cronTimer = null;
235
321
  /**
236
322
  * 매 분 시각 확인 → 16:00 KST 도달 시 모든 구독 페르소나의 일기 작성.
237
323
  * 단순 polling (cron lib 없이) · 클라이언트는 24/7 구동 안 할 수 있어 안전.
324
+ *
325
+ * 영업일 게이트: KRX 휴장일 (토·일·공휴일) 은 자동 skip.
326
+ * 빈 데이터 (의사결정·스크리닝 0건) 도 writeDiary 안에서 LLM 호출 skip.
238
327
  */
239
328
  export function startDiaryCron() {
240
329
  if (cronTimer)
@@ -243,12 +332,28 @@ export function startDiaryCron() {
243
332
  const now = new Date();
244
333
  const kst = new Date(now.getTime() + 9 * 3600_000);
245
334
  if (kst.getUTCHours() === 16 && kst.getUTCMinutes() === 0) {
335
+ // KRX 휴장일 (토·일·공휴일) 은 일기 cron skip — 거래 데이터 없는 날에
336
+ // LLM 이 가공 콘텐츠 만드는 사고 차단. 사용자 수동 호출은 별도 (force).
337
+ if (!isTradingDay(now)) {
338
+ console.log(`[diary] cron · KRX 휴장일 (${todayKST()}) skip`);
339
+ return;
340
+ }
246
341
  const cfg = loadConfig();
342
+ // user 미인증 시 diary write 못 함 (user-scoped path 결정 불가) → skip
343
+ if (!cfg.auth?.userId) {
344
+ console.warn("[diary] cron · user_id 미설정 → skip");
345
+ return;
346
+ }
247
347
  const subs = cfg.subscriptions ?? [];
248
348
  for (const slug of subs) {
249
349
  try {
250
350
  const r = await writeDiary(slug);
251
- console.log(`[diary] ${slug} ${r.ok ? "✓" : "✗"} ${r.path ?? r.error}`);
351
+ if (r.skipped) {
352
+ console.log(`[diary] ${slug} skip (${r.skipReason})`);
353
+ }
354
+ else {
355
+ console.log(`[diary] ${slug} ${r.ok ? "✓" : "✗"} ${r.path ?? r.error}`);
356
+ }
252
357
  }
253
358
  catch (e) {
254
359
  console.error(`[diary] ${slug} cron 실패:`, e);
@@ -256,7 +361,7 @@ export function startDiaryCron() {
256
361
  }
257
362
  }
258
363
  }, 60_000); // 1분마다 체크
259
- console.log("[diary] cron started · 매일 16:00 KST 자동 작성");
364
+ console.log("[diary] cron started · 매일 16:00 KST · KRX 영업일 자동 작성");
260
365
  }
261
366
  export function stopDiaryCron() {
262
367
  if (cronTimer)
@@ -1 +1 @@
1
- {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../../src-server/diary/writer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../../src-server/diary/writer.ts"],"names":[],"mappings":"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"}