@cartanova/qgrid-cli 1.0.4 → 1.1.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 (133) hide show
  1. package/bundle/dist/application/qgrid/pool.js +15 -6
  2. package/bundle/dist/application/qgrid/qgrid.frame.js +17 -22
  3. package/bundle/dist/application/qgrid/qgrid.types.js +5 -2
  4. package/bundle/dist/application/request-log/request-log.model.js +2 -2
  5. package/bundle/dist/sonamu.config.js +5 -2
  6. package/bundle/src/application/qgrid/pool.ts +17 -7
  7. package/bundle/src/application/qgrid/qgrid.frame.ts +18 -25
  8. package/bundle/src/application/qgrid/qgrid.types.ts +1 -1
  9. package/bundle/src/application/request-log/request-log.model.ts +2 -2
  10. package/bundle/src/sonamu.config.ts +1 -1
  11. package/bundle/web-dist/{web-dist/client/assets/index-DlPchHBY.js → client/assets/index-C0m8rRjO.js} +2 -2
  12. package/bundle/web-dist/client/assets/{routes-CagDz23B.js → routes-B1eOXnpo.js} +1 -1
  13. package/bundle/web-dist/client/assets/{show-aXUGa0gm.js → show-BztN6MXO.js} +1 -1
  14. package/bundle/web-dist/client/assets/tokens-rR2_-Pte.js +1 -0
  15. package/bundle/web-dist/client/index.html +1 -1
  16. package/bundle/web-dist/server/assets/{tokens-JH6FsnWZ.js → tokens-ARL5AOAh.js} +4 -1
  17. package/bundle/web-dist/server/entry-server.generated.js +1 -1
  18. package/dist/cli.js +34 -25
  19. package/package.json +10 -10
  20. package/bundle/dist/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js +0 -9
  21. package/bundle/dist/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js +0 -6
  22. package/bundle/dist/dist/_virtual/_rolldown/runtime.js +0 -15
  23. package/bundle/dist/dist/application/qgrid/oauth.js +0 -140
  24. package/bundle/dist/dist/application/qgrid/pool.js +0 -100
  25. package/bundle/dist/dist/application/qgrid/qgrid.frame.js +0 -280
  26. package/bundle/dist/dist/application/qgrid/qgrid.types.js +0 -79
  27. package/bundle/dist/dist/application/qgrid/worker.js +0 -183
  28. package/bundle/dist/dist/application/queries.generated.js +0 -31
  29. package/bundle/dist/dist/application/request-log/request-log.model.js +0 -113
  30. package/bundle/dist/dist/application/request-log/request-log.types.js +0 -13
  31. package/bundle/dist/dist/application/sonamu.generated.js +0 -99
  32. package/bundle/dist/dist/application/sonamu.generated.sso.js +0 -34
  33. package/bundle/dist/dist/application/token/token.model.js +0 -157
  34. package/bundle/dist/dist/application/token/token.types.js +0 -22
  35. package/bundle/dist/dist/i18n/en.js +0 -63
  36. package/bundle/dist/dist/i18n/ko.js +0 -62
  37. package/bundle/dist/dist/i18n/sd.generated.js +0 -272
  38. package/bundle/dist/dist/index.js +0 -11
  39. package/bundle/dist/dist/migrations/20260410171405_create__request_logs.js +0 -26
  40. package/bundle/dist/dist/migrations/20260410171406_create__tokens.js +0 -24
  41. package/bundle/dist/dist/migrations/20260411120624_alter_tokens_alter2.js +0 -16
  42. package/bundle/dist/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +0 -155
  43. package/bundle/dist/dist/node_modules/.pnpm/@vitest_expect@4.1.2/node_modules/@vitest/expect/dist/index.js +0 -1484
  44. package/bundle/dist/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.2/node_modules/@vitest/pretty-format/dist/index.js +0 -887
  45. package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2746
  46. package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/index.js +0 -8
  47. package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/utils.js +0 -8
  48. package/bundle/dist/dist/node_modules/.pnpm/@vitest_snapshot@4.1.2/node_modules/@vitest/snapshot/dist/index.js +0 -662
  49. package/bundle/dist/dist/node_modules/.pnpm/@vitest_spy@4.1.2/node_modules/@vitest/spy/dist/index.js +0 -386
  50. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -82
  51. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/constants.js +0 -48
  52. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/diff.js +0 -1307
  53. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/display.js +0 -558
  54. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/error.js +0 -33
  55. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/helpers.js +0 -226
  56. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/offset.js +0 -27
  57. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/serialize.js +0 -77
  58. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/source-map.js +0 -374
  59. package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/timers.js +0 -37
  60. package/bundle/dist/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +0 -2886
  61. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +0 -10
  62. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +0 -109
  63. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +0 -10
  64. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +0 -10
  65. package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +0 -10
  66. package/bundle/dist/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +0 -1127
  67. package/bundle/dist/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +0 -21
  68. package/bundle/dist/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +0 -432
  69. package/bundle/dist/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +0 -506
  70. package/bundle/dist/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +0 -86
  71. package/bundle/dist/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.9.2_@emnapi_runtime@1.9.2_@types_node@25.0.7_esbuild@0.27.4_jiti@2.6.1_sass@1.98.0_tsx@4.21.0/node_modules/vite/dist/node/module-runner.js +0 -426
  72. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +0 -6
  73. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +0 -41
  74. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +0 -19
  75. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +0 -202
  76. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/index.DOa3dzoN.js +0 -16
  77. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +0 -59
  78. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/test.p_J6dB8a.js +0 -2910
  79. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +0 -44
  80. package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/index.js +0 -28
  81. package/bundle/dist/dist/sonamu.config.js +0 -196
  82. package/bundle/dist/dist/testing/fixture.js +0 -8
  83. package/bundle/dist/dist/testing/global.js +0 -9
  84. package/bundle/dist/dist/testing/setup-mocks.js +0 -17
  85. package/bundle/dist/dist/utils/subset-loaders.js +0 -12
  86. package/bundle/src/src/application/qgrid/oauth.ts +0 -181
  87. package/bundle/src/src/application/qgrid/pool.ts +0 -132
  88. package/bundle/src/src/application/qgrid/qgrid.frame.ts +0 -275
  89. package/bundle/src/src/application/qgrid/qgrid.types.ts +0 -117
  90. package/bundle/src/src/application/qgrid/worker.ts +0 -234
  91. package/bundle/src/src/application/queries.generated.ts +0 -59
  92. package/bundle/src/src/application/request-log/request-log.entity.json +0 -75
  93. package/bundle/src/src/application/request-log/request-log.model.ts +0 -155
  94. package/bundle/src/src/application/request-log/request-log.types.ts +0 -15
  95. package/bundle/src/src/application/sonamu.generated.http +0 -187
  96. package/bundle/src/src/application/sonamu.generated.sso.ts +0 -66
  97. package/bundle/src/src/application/sonamu.generated.ts +0 -135
  98. package/bundle/src/src/application/token/token.entity.json +0 -37
  99. package/bundle/src/src/application/token/token.model.ts +0 -160
  100. package/bundle/src/src/application/token/token.types.ts +0 -26
  101. package/bundle/src/src/i18n/en.ts +0 -59
  102. package/bundle/src/src/i18n/ko.ts +0 -59
  103. package/bundle/src/src/i18n/sd.generated.ts +0 -384
  104. package/bundle/src/src/index.ts +0 -6
  105. package/bundle/src/src/migrations/20260410171405_create__request_logs.ts +0 -23
  106. package/bundle/src/src/migrations/20260410171406_create__tokens.ts +0 -21
  107. package/bundle/src/src/migrations/20260411120624_alter_tokens_alter2.ts +0 -15
  108. package/bundle/src/src/sonamu.config.ts +0 -248
  109. package/bundle/src/src/testing/fixture.ts +0 -6
  110. package/bundle/src/src/testing/global.ts +0 -6
  111. package/bundle/src/src/testing/setup-mocks.ts +0 -44
  112. package/bundle/src/src/typings/fastify.d.ts +0 -8
  113. package/bundle/src/src/typings/sonamu.d.ts +0 -17
  114. package/bundle/src/src/utils/subset-loaders.ts +0 -11
  115. package/bundle/web-dist/client/assets/index-DlPchHBY.js +0 -116
  116. package/bundle/web-dist/client/assets/tokens-DRkXtZ3Q.js +0 -1
  117. package/bundle/web-dist/web-dist/client/assets/index-vZsvyuFn.css +0 -1
  118. package/bundle/web-dist/web-dist/client/assets/rolldown-runtime-Dw2cE7zH.js +0 -1
  119. package/bundle/web-dist/web-dist/client/assets/routes-CagDz23B.js +0 -1
  120. package/bundle/web-dist/web-dist/client/assets/sd.generated-BrQoQXvv.js +0 -47
  121. package/bundle/web-dist/web-dist/client/assets/services.generated-BspO2L0j.js +0 -1
  122. package/bundle/web-dist/web-dist/client/assets/show-aXUGa0gm.js +0 -29
  123. package/bundle/web-dist/web-dist/client/assets/tokens-DRkXtZ3Q.js +0 -1
  124. package/bundle/web-dist/web-dist/client/assets/vendor-react-DH4kUfK2.js +0 -9
  125. package/bundle/web-dist/web-dist/client/assets/vendor-tanstack-CUxlo6YN.js +0 -1
  126. package/bundle/web-dist/web-dist/client/index.html +0 -18
  127. package/bundle/web-dist/web-dist/server/assets/react-dom-CGIzOSuj.js +0 -335
  128. package/bundle/web-dist/web-dist/server/assets/routes-ClzReRep.js +0 -490
  129. package/bundle/web-dist/web-dist/server/assets/sd.generated-BnonqqKr.js +0 -21694
  130. package/bundle/web-dist/web-dist/server/assets/services.generated-D5ABD5fr.js +0 -836
  131. package/bundle/web-dist/web-dist/server/assets/show-C9pcdSxc.js +0 -23364
  132. package/bundle/web-dist/web-dist/server/assets/tokens-JH6FsnWZ.js +0 -860
  133. package/bundle/web-dist/web-dist/server/entry-server.generated.js +0 -44646
@@ -1,234 +0,0 @@
1
- /**
2
- * Worker — Claude CLI stream-json 프로세스 하나를 관리.
3
- *
4
- * 기존 SocratsAI ClaudeCliService에서 추출 + 리팩터:
5
- * - 토큰/모델을 생성자에서 주입
6
- * - env allowlist (PATH, HOME, TMPDIR, CLAUDE_CODE_OAUTH_TOKEN만)
7
- * - callCount 추적 + maxCalls 도달 시 프로세스 재활용
8
- * - QuotaError/TimeoutError/ProcessError 구분
9
- */
10
- import { type ChildProcess, spawn } from "node:child_process";
11
- import { mkdirSync } from "node:fs";
12
-
13
- import type { CliResult, QueryInput } from "./qgrid.types";
14
- import { maskToken, ProcessError, QuotaError, TimeoutError } from "./qgrid.types";
15
-
16
- type PendingRequest = {
17
- resolve: (value: CliResult) => void;
18
- reject: (reason: Error) => void;
19
- timer: ReturnType<typeof setTimeout>;
20
- };
21
-
22
- export type WorkerConfig = {
23
- token: string;
24
- model: string;
25
- timeout: number;
26
- cwd: string;
27
- maxCalls: number;
28
- };
29
-
30
- export class Worker {
31
- tokenId: string;
32
- config: WorkerConfig;
33
- process: ChildProcess | null = null;
34
- buffer = "";
35
- pending: PendingRequest | null = null;
36
- sessionId: string | null = null;
37
- queue: Array<() => void> = [];
38
- cwdCreated = false;
39
- callCount = 0;
40
- needsRecycle = false;
41
-
42
- constructor(config: WorkerConfig) {
43
- this.config = config;
44
- this.tokenId = config.token;
45
- }
46
-
47
- getQueueDepth(): number {
48
- return this.queue.length + (this.pending ? 1 : 0);
49
- }
50
-
51
- rejectPending(err: Error): void {
52
- if (!this.pending) return;
53
- this.pending.reject(err);
54
- clearTimeout(this.pending.timer);
55
- this.pending = null;
56
- }
57
-
58
- ensureProcess(): ChildProcess {
59
- if (this.process && this.process.exitCode === null && !this.needsRecycle) {
60
- return this.process;
61
- }
62
-
63
- if (this.process && this.process.exitCode === null) {
64
- this.process.kill();
65
- this.process = null;
66
- }
67
-
68
- const env: NodeJS.ProcessEnv = {
69
- PATH: process.env.PATH,
70
- HOME: process.env.HOME,
71
- TMPDIR: process.env.TMPDIR,
72
- CLAUDE_CODE_OAUTH_TOKEN: this.config.token,
73
- };
74
-
75
- const { cwd } = this.config;
76
- if (!this.cwdCreated) {
77
- mkdirSync(cwd, { recursive: true });
78
- this.cwdCreated = true;
79
- }
80
-
81
- const child = spawn(
82
- "claude",
83
- [
84
- "-p",
85
- "--input-format",
86
- "stream-json",
87
- "--output-format",
88
- "stream-json",
89
- "--verbose",
90
- "--max-turns",
91
- "1",
92
- "--model",
93
- this.config.model,
94
- ],
95
- { stdio: ["pipe", "pipe", "ignore"], env, cwd },
96
- );
97
-
98
- child.stdout?.on("data", (d: Buffer) => {
99
- this.buffer += d.toString();
100
- this.processBuffer();
101
- });
102
-
103
- child.on("close", () => {
104
- this.process = null;
105
- this.rejectPending(
106
- new ProcessError(`CLI process closed (token: ${maskToken(this.tokenId)})`),
107
- );
108
- this.drainQueue();
109
- });
110
-
111
- child.on("error", (err) => {
112
- this.process = null;
113
- this.rejectPending(
114
- new ProcessError(`CLI process error: ${err.message} (token: ${maskToken(this.tokenId)})`),
115
- );
116
- this.drainQueue();
117
- });
118
-
119
- this.process = child;
120
- this.buffer = "";
121
- this.sessionId = null;
122
- this.callCount = 0;
123
- this.needsRecycle = false;
124
- return child;
125
- }
126
-
127
- processBuffer(): void {
128
- const lines = this.buffer.split("\n");
129
- this.buffer = lines.pop() ?? "";
130
-
131
- lines
132
- .filter((line) => line.trim() !== "")
133
- .forEach((line) => {
134
- try {
135
- const j = JSON.parse(line);
136
-
137
- if (j.type === "system" && j.subtype === "init" && j.session_id) {
138
- this.sessionId = j.session_id;
139
- }
140
-
141
- if (j.type === "result" && this.pending) {
142
- let text: string = j.result ?? "";
143
- text = text.replace(/^```(?:json)?\s*\n?/i, "").replace(/\n?```\s*$/i, "");
144
-
145
- if (text.startsWith("You've hit")) {
146
- this.pending.reject(
147
- new QuotaError(`Quota exhausted (token: ${maskToken(this.tokenId)})`),
148
- );
149
- clearTimeout(this.pending.timer);
150
- this.pending = null;
151
- this.drainQueue();
152
- return;
153
- }
154
-
155
- const u = j.usage ?? {};
156
- this.pending.resolve({
157
- text,
158
- usage: {
159
- input_tokens: u.input_tokens ?? 0,
160
- output_tokens: u.output_tokens ?? 0,
161
- cache_creation_input_tokens: u.cache_creation_input_tokens ?? 0,
162
- cache_read_input_tokens: u.cache_read_input_tokens ?? 0,
163
- },
164
- durationMs: j.duration_ms ?? 0,
165
- costUsd: j.total_cost_usd ?? 0,
166
- });
167
- clearTimeout(this.pending.timer);
168
- this.pending = null;
169
- this.drainQueue();
170
- }
171
- } catch {
172
- // skip non-json lines
173
- }
174
- });
175
- }
176
-
177
- drainQueue(): void {
178
- if (this.pending) return;
179
- const next = this.queue.shift();
180
- if (next) next();
181
- }
182
-
183
- async query(input: QueryInput, timeoutMs?: number): Promise<CliResult> {
184
- if (this.pending) {
185
- await new Promise<void>((resolve) => {
186
- this.queue.push(resolve);
187
- });
188
- }
189
-
190
- const child = this.ensureProcess();
191
- const timeout = timeoutMs ?? this.config.timeout;
192
-
193
- this.callCount++;
194
- if (this.callCount >= this.config.maxCalls) {
195
- this.needsRecycle = true;
196
- }
197
-
198
- const prompt = input.system ? `${input.system}\n\n${input.prompt}` : input.prompt;
199
-
200
- return new Promise<CliResult>((resolve, reject) => {
201
- const timer = setTimeout(() => {
202
- this.pending = null;
203
- reject(
204
- new TimeoutError(`Timeout after ${timeout / 1000}s (token: ${maskToken(this.tokenId)})`),
205
- );
206
- this.kill();
207
- }, timeout);
208
-
209
- this.pending = { resolve, reject, timer };
210
-
211
- const msg = JSON.stringify({
212
- type: "user",
213
- message: { role: "user", content: prompt },
214
- session_id: this.sessionId ?? "default",
215
- parent_tool_use_id: null,
216
- });
217
-
218
- child.stdin?.write(`${msg}\n`);
219
- });
220
- }
221
-
222
- kill(): void {
223
- if (this.process && this.process.exitCode === null) {
224
- this.process.kill();
225
- }
226
- this.process = null;
227
- this.buffer = "";
228
- this.sessionId = null;
229
- this.callCount = 0;
230
- this.needsRecycle = false;
231
- this.rejectPending(new ProcessError(`Worker killed (token: ${maskToken(this.tokenId)})`));
232
- this.drainQueue();
233
- }
234
- }
@@ -1,59 +0,0 @@
1
- /**
2
- * @generated
3
- * 직접 수정하지 마세요.
4
- */
5
- /* oxlint-disable */
6
-
7
- import type { SSRQuery } from "sonamu/ssr";
8
-
9
- // SSRQuery 헬퍼 함수
10
- function createSSRQuery(
11
- modelName: string,
12
- methodName: string,
13
- params: any[],
14
- serviceKey: [string, string],
15
- ): SSRQuery {
16
- return { modelName, methodName, params, serviceKey, __brand: "SSRQuery" } as SSRQuery;
17
- }
18
-
19
- import { RequestLogListParams } from "./request-log/request-log.types";
20
- import { TokenSubsetKey, RequestLogSubsetKey } from "./sonamu.generated";
21
- import { TokenListParams } from "./token/token.types";
22
-
23
- export namespace TokenService {
24
- export const getToken = <T extends TokenSubsetKey>(subset: T, id: number): SSRQuery =>
25
- createSSRQuery("TokenModel", "findById", [subset, id], ["Token", "getToken"]);
26
-
27
- export const getTokens = <T extends TokenSubsetKey, LP extends TokenListParams>(
28
- subset: T,
29
- rawParams?: LP,
30
- ): SSRQuery =>
31
- createSSRQuery("TokenModel", "findMany", [subset, rawParams], ["Token", "getTokens"]);
32
- }
33
-
34
- export namespace RequestLogService {
35
- export const getRequestLog = <T extends RequestLogSubsetKey>(subset: T, id: number): SSRQuery =>
36
- createSSRQuery("RequestLogModel", "findById", [subset, id], ["RequestLog", "getRequestLog"]);
37
-
38
- export const getRequestLogs = <T extends RequestLogSubsetKey, LP extends RequestLogListParams>(
39
- subset: T,
40
- rawParams?: LP,
41
- ): SSRQuery =>
42
- createSSRQuery(
43
- "RequestLogModel",
44
- "findMany",
45
- [subset, rawParams],
46
- ["RequestLog", "getRequestLogs"],
47
- );
48
- }
49
-
50
- export namespace QgridService {
51
- export const stats = (): SSRQuery =>
52
- createSSRQuery("QgridFrame", "stats", [], ["Qgrid", "stats"]);
53
-
54
- export const usage = (tokenName?: string): SSRQuery =>
55
- createSSRQuery("QgridFrame", "usage", [tokenName], ["Qgrid", "usage"]);
56
-
57
- export const health = (): SSRQuery =>
58
- createSSRQuery("QgridFrame", "health", [], ["Qgrid", "health"]);
59
- }
@@ -1,75 +0,0 @@
1
- {
2
- "id": "RequestLog",
3
- "table": "request_logs",
4
- "title": "RequestLog",
5
- "cone": {
6
- "note": "RequestLog 엔티티. 테스트 데이터 생성 시 각 필드는 실제 데이터와 유사한 형식으로 생성됩니다."
7
- },
8
- "props": [
9
- {
10
- "name": "id",
11
- "type": "integer",
12
- "desc": "ID",
13
- "cone": {
14
- "note": "정수 형식으로 생성됩니다.",
15
- "fixtureGenerator": "faker.number.int({ \"min\": 1, \"max\": 1000 })"
16
- }
17
- },
18
- {
19
- "name": "created_at",
20
- "type": "date",
21
- "desc": "등록일시",
22
- "dbDefault": "CURRENT_TIMESTAMP",
23
- "cone": { "note": "날짜 형식으로 생성됩니다.", "fixtureGenerator": "faker.date.past()" }
24
- },
25
- {
26
- "name": "token_name",
27
- "toFilter": true,
28
- "desc": "토큰 이름",
29
- "type": "string",
30
- "length": 100
31
- },
32
- { "name": "query", "type": "string", "desc": "prompt 전문" },
33
- { "name": "response", "desc": "llm 응답 전문", "type": "string" },
34
- { "name": "input_tokens", "type": "integer", "desc": "입력 토큰" },
35
- { "name": "output_tokens", "type": "integer", "desc": "출력 토큰" },
36
- { "name": "cache_read_tokens", "type": "integer", "desc": "캐시 읽기 토큰" },
37
- { "name": "cache_creation_tokens", "type": "integer", "desc": "캐시 생성 토큰" },
38
- { "name": "duration_ms", "type": "integer", "desc": "응답 소요시간(ms)" }
39
- ],
40
- "indexes": [],
41
- "subsets": {
42
- "A": {
43
- "fields": [
44
- "id",
45
- "created_at",
46
- "token_name",
47
- "query",
48
- "response",
49
- "input_tokens",
50
- "output_tokens",
51
- "cache_read_tokens",
52
- "cache_creation_tokens",
53
- "duration_ms"
54
- ],
55
- "cone": { "note": "전체 필드 서브셋" }
56
- }
57
- },
58
- "enums": {
59
- "RequestLogOrderBy": {
60
- "values": { "id-desc": "ID최신순" },
61
- "cone": { "note": "가능한 값: id-desc", "values": { "id-desc": { "note": "ID최신순" } } }
62
- },
63
- "RequestLogSearchField": {
64
- "values": { "id": "ID", "token_name": "토큰이름", "query": "쿼리" },
65
- "cone": {
66
- "note": "가능한 값: id, token_name, query",
67
- "values": {
68
- "id": { "note": "ID" },
69
- "token_name": { "note": "토큰이름" },
70
- "query": { "note": "쿼리" }
71
- }
72
- }
73
- }
74
- }
75
- }
@@ -1,155 +0,0 @@
1
- import {
2
- api,
3
- asArray,
4
- BadRequestException,
5
- BaseModelClass,
6
- exhaustive,
7
- type ListResult,
8
- NotFoundException,
9
- } from "sonamu";
10
-
11
- import { SD } from "../../i18n/sd.generated";
12
- import type { RequestLogSubsetKey, RequestLogSubsetMapping } from "../sonamu.generated";
13
- import { requestLogLoaderQueries, requestLogSubsetQueries } from "../sonamu.generated.sso";
14
- import type { RequestLogListParams, RequestLogSaveParams } from "./request-log.types";
15
-
16
- /*
17
- RequestLog Model
18
- */
19
- class RequestLogModelClass extends BaseModelClass<
20
- RequestLogSubsetKey,
21
- RequestLogSubsetMapping,
22
- typeof requestLogSubsetQueries,
23
- typeof requestLogLoaderQueries
24
- > {
25
- constructor() {
26
- super("RequestLog", requestLogSubsetQueries, requestLogLoaderQueries);
27
- }
28
-
29
- @api({ httpMethod: "GET", clients: ["axios", "tanstack-query"], resourceName: "RequestLog" })
30
- async findById<T extends RequestLogSubsetKey>(
31
- subset: T,
32
- id: number,
33
- ): Promise<RequestLogSubsetMapping[T]> {
34
- const { rows } = await this.findMany(subset, {
35
- id,
36
- num: 1,
37
- page: 1,
38
- });
39
- if (!rows[0]) {
40
- throw new NotFoundException(SD("error.entityNotFound")("RequestLog", id));
41
- }
42
-
43
- return rows[0];
44
- }
45
-
46
- async findOne<T extends RequestLogSubsetKey>(
47
- subset: T,
48
- listParams: RequestLogListParams,
49
- ): Promise<RequestLogSubsetMapping[T] | null> {
50
- const { rows } = await this.findMany(subset, {
51
- ...listParams,
52
- num: 1,
53
- page: 1,
54
- });
55
-
56
- return rows[0] ?? null;
57
- }
58
-
59
- @api({ httpMethod: "GET", clients: ["axios", "tanstack-query"], resourceName: "RequestLogs" })
60
- async findMany<T extends RequestLogSubsetKey, LP extends RequestLogListParams>(
61
- subset: T,
62
- rawParams?: LP,
63
- ): Promise<ListResult<LP, RequestLogSubsetMapping[T]>> {
64
- // params with defaults
65
- const params = {
66
- num: 24,
67
- page: 1,
68
- search: "id" as const,
69
- orderBy: "id-desc" as const,
70
- ...rawParams,
71
- } satisfies RequestLogListParams;
72
-
73
- // build queries
74
- const { qb, onSubset: _ } = this.getSubsetQueries(subset);
75
-
76
- // id
77
- if (params.id) {
78
- qb.whereIn("request_logs.id", asArray(params.id));
79
- }
80
-
81
- // token_name filter (toFilter)
82
- if (params.token_name) {
83
- qb.where("request_logs.token_name", params.token_name);
84
- }
85
-
86
- // search-keyword
87
- if (params.search && params.keyword && params.keyword.length > 0) {
88
- if (params.search === "id") {
89
- qb.where("request_logs.id", Number(params.keyword));
90
- } else if (params.search === "token_name") {
91
- qb.where("request_logs.token_name", "like", `%${params.keyword}%`);
92
- } else if (params.search === "query") {
93
- qb.where("request_logs.query", "like", `%${params.keyword}%`);
94
- } else {
95
- throw new BadRequestException(SD("error.unknownSearchField")(params.search));
96
- }
97
- }
98
-
99
- // orderBy
100
- if (params.orderBy) {
101
- // default orderBy
102
- if (params.orderBy === "id-desc") {
103
- qb.orderBy("request_logs.id", "desc");
104
- } else {
105
- exhaustive(params.orderBy);
106
- }
107
- }
108
-
109
- const enhancers = this.createEnhancers({
110
- A: (row) => ({
111
- ...row,
112
- // 서브셋별로 virtual 필드 계산로직 추가
113
- }),
114
- });
115
-
116
- return this.executeSubsetQuery({
117
- subset,
118
- qb,
119
- params,
120
- enhancers,
121
- debug: false,
122
- });
123
- }
124
-
125
- @api({ httpMethod: "POST", clients: ["axios", "tanstack-mutation"] })
126
- async save(spa: RequestLogSaveParams[]): Promise<number[]> {
127
- const wdb = this.getPuri("w");
128
-
129
- // register
130
- spa.forEach((sp) => {
131
- wdb.ubRegister("request_logs", sp);
132
- });
133
-
134
- // transaction
135
- return wdb.transaction(async (trx) => {
136
- const ids = await trx.ubUpsert("request_logs");
137
-
138
- return ids;
139
- });
140
- }
141
-
142
- @api({ httpMethod: "POST", clients: ["axios", "tanstack-mutation"] })
143
- async del(ids: number[]): Promise<number> {
144
- const wdb = this.getPuri("w");
145
-
146
- // transaction
147
- await wdb.transaction(async (trx) => {
148
- return trx.table("request_logs").whereIn("request_logs.id", ids).delete();
149
- });
150
-
151
- return ids.length;
152
- }
153
- }
154
-
155
- export const RequestLogModel = new RequestLogModelClass();
@@ -1,15 +0,0 @@
1
- import type { z } from "zod";
2
-
3
- import { RequestLogBaseListParams, RequestLogBaseSchema } from "../sonamu.generated";
4
-
5
- // RequestLog - ListParams
6
- export const RequestLogListParams = RequestLogBaseListParams;
7
- export type RequestLogListParams = z.infer<typeof RequestLogListParams>;
8
-
9
- // RequestLog - SaveParams
10
- export const RequestLogSaveParams = RequestLogBaseSchema.partial({
11
- id: true,
12
- created_at: true,
13
- token_name: true,
14
- });
15
- export type RequestLogSaveParams = z.infer<typeof RequestLogSaveParams>;