@autobe/agent 0.11.2 → 0.12.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 (72) hide show
  1. package/lib/AutoBeAgent.d.ts +3 -146
  2. package/lib/AutoBeAgent.js +6 -180
  3. package/lib/AutoBeAgent.js.map +1 -1
  4. package/lib/AutoBeAgentBase.d.ts +18 -0
  5. package/lib/AutoBeAgentBase.js +54 -0
  6. package/lib/AutoBeAgentBase.js.map +1 -0
  7. package/lib/AutoBeMockAgent.d.ts +14 -0
  8. package/lib/AutoBeMockAgent.js +135 -0
  9. package/lib/AutoBeMockAgent.js.map +1 -0
  10. package/lib/constants/AutoBeSystemPromptConstant.d.ts +8 -4
  11. package/lib/constants/AutoBeSystemPromptConstant.js.map +1 -1
  12. package/lib/factory/getAutoBeGenerated.d.ts +3 -4
  13. package/lib/factory/getAutoBeGenerated.js +6 -250
  14. package/lib/factory/getAutoBeGenerated.js.map +1 -1
  15. package/lib/index.js +2 -0
  16. package/lib/index.js.map +1 -1
  17. package/lib/index.mjs +883 -399
  18. package/lib/index.mjs.map +1 -1
  19. package/lib/orchestrate/analyze/orchestrateAnalyze.js +6 -1
  20. package/lib/orchestrate/analyze/orchestrateAnalyze.js.map +1 -1
  21. package/lib/orchestrate/analyze/writeDocumentUntilReviewPassed.d.ts +4 -1
  22. package/lib/orchestrate/analyze/writeDocumentUntilReviewPassed.js +6 -2
  23. package/lib/orchestrate/analyze/writeDocumentUntilReviewPassed.js.map +1 -1
  24. package/lib/orchestrate/realize/orchestrateRealize.js +11 -2
  25. package/lib/orchestrate/realize/orchestrateRealize.js.map +1 -1
  26. package/lib/orchestrate/realize/orchestrateRealizeCoder.js +46 -15
  27. package/lib/orchestrate/realize/orchestrateRealizeCoder.js.map +1 -1
  28. package/lib/orchestrate/realize/orchestrateRealizeDecorator.d.ts +10 -0
  29. package/lib/orchestrate/realize/orchestrateRealizeDecorator.js +545 -0
  30. package/lib/orchestrate/realize/orchestrateRealizeDecorator.js.map +1 -0
  31. package/lib/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.d.ts +12 -9
  32. package/lib/orchestrate/realize/structures/IAutoBeRealizeDecoratorApplication.d.ts +85 -0
  33. package/lib/orchestrate/realize/structures/IAutoBeRealizeDecoratorApplication.js +3 -0
  34. package/lib/orchestrate/realize/structures/IAutoBeRealizeDecoratorApplication.js.map +1 -0
  35. package/lib/orchestrate/realize/transformRealizeCoderHistories.d.ts +1 -1
  36. package/lib/orchestrate/realize/transformRealizeCoderHistories.js +24 -30
  37. package/lib/orchestrate/realize/transformRealizeCoderHistories.js.map +1 -1
  38. package/lib/orchestrate/realize/transformRealizeDecorator.d.ts +4 -0
  39. package/lib/orchestrate/realize/transformRealizeDecorator.js +32 -0
  40. package/lib/orchestrate/realize/transformRealizeDecorator.js.map +1 -0
  41. package/lib/orchestrate/realize/transformRealizeDecoratorCorrectHistories.d.ts +6 -0
  42. package/lib/orchestrate/realize/transformRealizeDecoratorCorrectHistories.js +49 -0
  43. package/lib/orchestrate/realize/transformRealizeDecoratorCorrectHistories.js.map +1 -0
  44. package/lib/orchestrate/realize/writeCodeUntilCompilePassed.js +30 -11
  45. package/lib/orchestrate/realize/writeCodeUntilCompilePassed.js.map +1 -1
  46. package/lib/orchestrate/test/orchestrateTest.js.map +1 -1
  47. package/lib/orchestrate/test/orchestrateTestCorrect.js +2 -1
  48. package/lib/orchestrate/test/orchestrateTestCorrect.js.map +1 -1
  49. package/lib/utils/backoffRetry.d.ts +18 -0
  50. package/lib/utils/backoffRetry.js +38 -0
  51. package/lib/utils/backoffRetry.js.map +1 -1
  52. package/package.json +8 -8
  53. package/src/AutoBeAgent.ts +10 -203
  54. package/src/AutoBeAgentBase.ts +78 -0
  55. package/src/AutoBeMockAgent.ts +163 -0
  56. package/src/constants/AutoBeSystemPromptConstant.ts +8 -4
  57. package/src/factory/getAutoBeGenerated.ts +8 -13
  58. package/src/index.ts +3 -1
  59. package/src/orchestrate/analyze/orchestrateAnalyze.ts +7 -1
  60. package/src/orchestrate/analyze/writeDocumentUntilReviewPassed.ts +8 -0
  61. package/src/orchestrate/realize/orchestrateRealize.ts +11 -0
  62. package/src/orchestrate/realize/orchestrateRealizeCoder.ts +26 -4
  63. package/src/orchestrate/realize/orchestrateRealizeDecorator.ts +286 -0
  64. package/src/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.ts +12 -9
  65. package/src/orchestrate/realize/structures/IAutoBeRealizeDecoratorApplication.ts +94 -0
  66. package/src/orchestrate/realize/transformRealizeCoderHistories.ts +22 -29
  67. package/src/orchestrate/realize/transformRealizeDecorator.ts +37 -0
  68. package/src/orchestrate/realize/transformRealizeDecoratorCorrectHistories.ts +58 -0
  69. package/src/orchestrate/realize/writeCodeUntilCompilePassed.ts +34 -9
  70. package/src/orchestrate/test/orchestrateTest.ts +1 -0
  71. package/src/orchestrate/test/orchestrateTestCorrect.ts +1 -1
  72. package/src/utils/backoffRetry.ts +56 -0
package/lib/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { AgenticaTokenUsage, MicroAgentica } from "@agentica/core";
2
2
 
3
- import { hash, HashSet, HashMap, Pair, Semaphore, Singleton } from "tstl";
3
+ import { hash, HashSet, HashMap, Pair, Semaphore, Singleton, sleep_for } from "tstl";
4
4
 
5
5
  import { v4 } from "uuid";
6
6
 
@@ -18,19 +18,75 @@ import { OpenApiV3_1Emender } from "@samchon/openapi/lib/converters/OpenApiV3_1E
18
18
 
19
19
  import * as __typia_transform__isUniqueItems from "typia/lib/internal/_isUniqueItems.js";
20
20
 
21
- import { readFile } from "fs/promises";
21
+ import fs, { readFile } from "fs/promises";
22
22
 
23
23
  import path from "path";
24
24
 
25
- import * as __typia_transform__jsonStringifyString from "typia/lib/internal/_jsonStringifyString.js";
26
-
27
- import * as __typia_transform__throwTypeGuardError from "typia/lib/internal/_throwTypeGuardError.js";
28
-
29
- import "typia/lib/internal/_isFormatDateTime.js";
25
+ async function getAutoBeGenerated(compiler, state, histories, tokenUsage, options) {
26
+ const ret = {};
27
+ if (state.analyze === null) return {};
28
+ Object.assign(ret, Object.fromEntries(Object.entries(state.analyze.files).map((([key, value]) => [ `docs/analysis/${key.split("/").at(-1)}`, value ]))));
29
+ if (state.prisma?.step === state.analyze.step) {
30
+ const schemaFiles = (options?.dbms ?? "postgres") === "postgres" ? state.prisma.schemas : await compiler.prisma.write(state.prisma.result.data, options.dbms);
31
+ Object.assign(ret, Object.fromEntries(Object.entries(schemaFiles).map((([key, value]) => [ `prisma/schema/${key.split("/").at(-1)}`, value ]))), {
32
+ "autobe/prisma.json": JSON.stringify(state.prisma.result.data)
33
+ });
34
+ if (state.prisma.compiled.type === "success") ret["docs/ERD.md"] = state.prisma.compiled.document; else if (state.prisma.compiled.type === "failure") ret["prisma/compile-error-reason.log"] = state.prisma.compiled.reason;
35
+ }
36
+ if (state.interface?.step === state.analyze.step) {
37
+ const files = await compiler.interface.write(state.interface.document);
38
+ Object.assign(ret, state.test?.step === state.interface.step ? Object.fromEntries(Object.entries(files).filter((([key]) => key.startsWith("test/features/") === false))) : files, {
39
+ "autobe/document.json": JSON.stringify(state.interface.document)
40
+ });
41
+ }
42
+ if (state.test?.step === state.analyze.step) Object.assign(ret, Object.fromEntries(state.test.files.map((f => [ f.location, f.content ]))), await compiler.test.getTemplate());
43
+ if (state.realize?.step === state.analyze.step) Object.assign(ret, state.realize.files, await compiler.realize.getTemplate());
44
+ Object.assign(ret, {
45
+ "autobe/histories.json": JSON.stringify(histories),
46
+ "autobe/tokenUsage.json": JSON.stringify(tokenUsage)
47
+ });
48
+ return ret;
49
+ }
30
50
 
31
- import "typia/lib/internal/_isFormatUuid.js";
51
+ function emplaceMap(dict, key, generator) {
52
+ const oldbie = dict.get(key);
53
+ if (oldbie !== undefined) {
54
+ return oldbie;
55
+ }
56
+ const value = generator();
57
+ dict.set(key, value);
58
+ return value;
59
+ }
32
60
 
33
- import "typia/lib/internal/_isFormatUrl.js";
61
+ class AutoBeAgentBase {
62
+ constructor(asset) {
63
+ this.asset = asset;
64
+ this.listeners_ = new Map;
65
+ }
66
+ async getFiles(options) {
67
+ return getAutoBeGenerated(await this.asset.compiler(), this.asset.state(), this.getHistories(), this.getTokenUsage(), options);
68
+ }
69
+ on(type, listener) {
70
+ emplaceMap(this.listeners_, type, (() => new Set)).add(listener);
71
+ return this;
72
+ }
73
+ off(type, listener) {
74
+ const set = this.listeners_.get(type);
75
+ if (set === undefined) return this;
76
+ set.delete(listener);
77
+ if (set.size === 0) this.listeners_.delete(type);
78
+ return this;
79
+ }
80
+ async dispatch(event) {
81
+ const set = this.listeners_.get(event.type);
82
+ if (set === undefined) return;
83
+ await Promise.all(Array.from(set).map((async listener => {
84
+ try {
85
+ await listener(event);
86
+ } catch {}
87
+ })));
88
+ }
89
+ }
34
90
 
35
91
  class AutoBeTokenUsage {
36
92
  constructor(props) {
@@ -169,7 +225,7 @@ class AutoBeAnalyzeComposerApplication {
169
225
 
170
226
  function createController$1(props) {
171
227
  assertSchemaModel(props.model);
172
- const application = collection$d[props.model];
228
+ const application = collection$e[props.model];
173
229
  return {
174
230
  protocol: "class",
175
231
  name: "Compose",
@@ -183,7 +239,7 @@ function createController$1(props) {
183
239
  };
184
240
  }
185
241
 
186
- const claude$d = {
242
+ const claude$e = {
187
243
  model: "claude",
188
244
  options: {
189
245
  reference: true,
@@ -395,7 +451,7 @@ const claude$d = {
395
451
  } ]
396
452
  };
397
453
 
398
- const collection$d = {
454
+ const collection$e = {
399
455
  chatgpt: {
400
456
  model: "chatgpt",
401
457
  options: {
@@ -607,13 +663,32 @@ const collection$d = {
607
663
  })()
608
664
  } ]
609
665
  },
610
- claude: claude$d,
611
- llama: claude$d,
612
- deepseek: claude$d,
613
- 3.1: claude$d
666
+ claude: claude$e,
667
+ llama: claude$e,
668
+ deepseek: claude$e,
669
+ 3.1: claude$e
614
670
  };
615
671
 
672
+ async function randomBackoffRetry(fn, options = {}) {
673
+ const {maxRetries = 5, baseDelay = 4e3, maxDelay = 6e4, jitter = .8, handleError = isRetryError} = options;
674
+ let lastError;
675
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
676
+ try {
677
+ return await fn();
678
+ } catch (err) {
679
+ lastError = err;
680
+ if (attempt === maxRetries - 1) throw err;
681
+ if (!handleError(err)) throw err;
682
+ const tempDelay = Math.min(baseDelay * 2 ** attempt, maxDelay);
683
+ const delay = tempDelay * (1 + Math.random() * jitter);
684
+ await new Promise((res => setTimeout(res, delay)));
685
+ }
686
+ }
687
+ throw lastError;
688
+ }
689
+
616
690
  function randomBackoffStrategy(props) {
691
+ console.log("randomBackoffStrategy");
617
692
  const {count, error} = props;
618
693
  if (count > 5) {
619
694
  throw error;
@@ -762,7 +837,7 @@ const orchestrateAnalyzeWrite = (ctx, input, pointer, isAborted) => {
762
837
 
763
838
  function createController(props) {
764
839
  assertSchemaModel(props.model);
765
- const application = collection$c[props.model];
840
+ const application = collection$d[props.model];
766
841
  return {
767
842
  protocol: "class",
768
843
  name: "Planning",
@@ -782,7 +857,7 @@ function createController(props) {
782
857
  };
783
858
  }
784
859
 
785
- const claude$c = {
860
+ const claude$d = {
786
861
  model: "claude",
787
862
  options: {
788
863
  reference: true,
@@ -964,7 +1039,7 @@ const claude$c = {
964
1039
  } ]
965
1040
  };
966
1041
 
967
- const collection$c = {
1042
+ const collection$d = {
968
1043
  chatgpt: {
969
1044
  model: "chatgpt",
970
1045
  options: {
@@ -1147,13 +1222,13 @@ const collection$c = {
1147
1222
  })()
1148
1223
  } ]
1149
1224
  },
1150
- claude: claude$c,
1151
- llama: claude$c,
1152
- deepseek: claude$c,
1153
- 3.1: claude$c
1225
+ claude: claude$d,
1226
+ llama: claude$d,
1227
+ deepseek: claude$d,
1228
+ 3.1: claude$d
1154
1229
  };
1155
1230
 
1156
- async function writeDocumentUntilReviewPassed(ctx, pointer, totalFiles, filename, roles, retry = 3) {
1231
+ async function writeDocumentUntilReviewPassed(ctx, pointer, totalFiles, filename, roles, progress, retry = 3) {
1157
1232
  const isAborted = {
1158
1233
  value: false
1159
1234
  };
@@ -1179,6 +1254,8 @@ async function writeDocumentUntilReviewPassed(ctx, pointer, totalFiles, filename
1179
1254
  ctx.dispatch({
1180
1255
  type: "analyzeWrite",
1181
1256
  files: pointer.value.files,
1257
+ total: progress.total,
1258
+ completed: ++progress.completed,
1182
1259
  step: ctx.state().analyze?.step ?? 0,
1183
1260
  created_at: (new Date).toISOString()
1184
1261
  });
@@ -1186,6 +1263,8 @@ async function writeDocumentUntilReviewPassed(ctx, pointer, totalFiles, filename
1186
1263
  if (review !== null) ctx.dispatch({
1187
1264
  type: "analyzeReview",
1188
1265
  review,
1266
+ total: progress.total,
1267
+ completed: progress.completed,
1189
1268
  step: ctx.state().analyze?.step ?? 0,
1190
1269
  created_at: (new Date).toISOString()
1191
1270
  });
@@ -1235,13 +1314,18 @@ const orchestrateAnalyze = ctx => async props => {
1235
1314
  });
1236
1315
  return history;
1237
1316
  }
1317
+ const retryCount = 3;
1318
+ const progress = {
1319
+ total: tableOfContents.length * retryCount,
1320
+ completed: 0
1321
+ };
1238
1322
  const pointers = await Promise.all(tableOfContents.map((async ({filename}) => {
1239
1323
  const pointer = {
1240
1324
  value: {
1241
1325
  files: {}
1242
1326
  }
1243
1327
  };
1244
- await writeDocumentUntilReviewPassed(ctx, pointer, tableOfContents, filename, roles, 3);
1328
+ await writeDocumentUntilReviewPassed(ctx, pointer, tableOfContents, filename, roles, progress, retryCount);
1245
1329
  return pointer;
1246
1330
  })));
1247
1331
  const files = pointers.map((pointer => pointer.value?.files ?? {})).reduce(((acc, cur) => Object.assign(acc, cur)));
@@ -1363,7 +1447,7 @@ async function step$1(ctx, document, retry) {
1363
1447
  type: "assistantMessage",
1364
1448
  text: [ "You have missed below schema types in the document.components.schemas:", "", ...missed.map((s => `- ${s}`)) ].join("\n")
1365
1449
  } ],
1366
- controllers: [ createApplication$a({
1450
+ controllers: [ createApplication$b({
1367
1451
  model: ctx.model,
1368
1452
  build: next => {
1369
1453
  pointer.value ?? (pointer.value = {});
@@ -1420,9 +1504,9 @@ const getMissed = document => {
1420
1504
  return Array.from(missed);
1421
1505
  };
1422
1506
 
1423
- function createApplication$a(props) {
1507
+ function createApplication$b(props) {
1424
1508
  assertSchemaModel(props.model);
1425
- const application = collection$b[props.model];
1509
+ const application = collection$c[props.model];
1426
1510
  return {
1427
1511
  protocol: "class",
1428
1512
  name: "interface",
@@ -1435,7 +1519,7 @@ function createApplication$a(props) {
1435
1519
  };
1436
1520
  }
1437
1521
 
1438
- const claude$b = {
1522
+ const claude$c = {
1439
1523
  model: "claude",
1440
1524
  options: {
1441
1525
  reference: true,
@@ -1548,7 +1632,7 @@ const claude$b = {
1548
1632
  } ]
1549
1633
  };
1550
1634
 
1551
- const collection$b = {
1635
+ const collection$c = {
1552
1636
  chatgpt: {
1553
1637
  model: "chatgpt",
1554
1638
  options: {
@@ -1661,10 +1745,10 @@ const collection$b = {
1661
1745
  })()
1662
1746
  } ]
1663
1747
  },
1664
- claude: claude$b,
1665
- llama: claude$b,
1666
- deepseek: claude$b,
1667
- 3.1: claude$b
1748
+ claude: claude$c,
1749
+ llama: claude$c,
1750
+ deepseek: claude$c,
1751
+ 3.1: claude$c
1668
1752
  };
1669
1753
 
1670
1754
  function divideArray(props) {
@@ -1727,7 +1811,7 @@ async function divideAndConquer$1(ctx, operations, typeNames, retry, progress) {
1727
1811
  for (let i = 0; i < retry; ++i) {
1728
1812
  if (remained.size === 0) break;
1729
1813
  const before = remained.size;
1730
- const newbie = await forceRetry((() => process$4(ctx, operations, components, remained)));
1814
+ const newbie = await forceRetry((() => process$5(ctx, operations, components, remained)));
1731
1815
  for (const key of Object.keys(newbie.schemas)) {
1732
1816
  components.schemas[key] = newbie.schemas[key];
1733
1817
  remained.delete(key);
@@ -1737,7 +1821,7 @@ async function divideAndConquer$1(ctx, operations, typeNames, retry, progress) {
1737
1821
  return components;
1738
1822
  }
1739
1823
 
1740
- async function process$4(ctx, operations, oldbie, remained) {
1824
+ async function process$5(ctx, operations, oldbie, remained) {
1741
1825
  const pointer = {
1742
1826
  value: null
1743
1827
  };
@@ -1756,7 +1840,7 @@ async function process$4(ctx, operations, oldbie, remained) {
1756
1840
  type: "assistantMessage",
1757
1841
  text: [ "Here is the OpenAPI operations generated by phase 2.", "", "```json", JSON.stringify(operations), "```" ].join("\n")
1758
1842
  } ],
1759
- controllers: [ createApplication$9({
1843
+ controllers: [ createApplication$a({
1760
1844
  model: ctx.model,
1761
1845
  build: async components => {
1762
1846
  pointer.value ?? (pointer.value = {
@@ -1779,9 +1863,9 @@ async function process$4(ctx, operations, oldbie, remained) {
1779
1863
  return OpenApiV3_1Emender.convertComponents(pointer.value);
1780
1864
  }
1781
1865
 
1782
- function createApplication$9(props) {
1866
+ function createApplication$a(props) {
1783
1867
  assertSchemaModel(props.model);
1784
- const application = collection$a[props.model];
1868
+ const application = collection$b[props.model];
1785
1869
  return {
1786
1870
  protocol: "class",
1787
1871
  name: "interface",
@@ -1794,7 +1878,7 @@ function createApplication$9(props) {
1794
1878
  };
1795
1879
  }
1796
1880
 
1797
- const claude$a = {
1881
+ const claude$b = {
1798
1882
  model: "claude",
1799
1883
  options: {
1800
1884
  reference: true,
@@ -1928,7 +2012,7 @@ const claude$a = {
1928
2012
  } ]
1929
2013
  };
1930
2014
 
1931
- const collection$a = {
2015
+ const collection$b = {
1932
2016
  chatgpt: {
1933
2017
  model: "chatgpt",
1934
2018
  options: {
@@ -2061,10 +2145,10 @@ const collection$a = {
2061
2145
  })()
2062
2146
  } ]
2063
2147
  },
2064
- claude: claude$a,
2065
- llama: claude$a,
2066
- deepseek: claude$a,
2067
- 3.1: claude$a
2148
+ claude: claude$b,
2149
+ llama: claude$b,
2150
+ deepseek: claude$b,
2151
+ 3.1: claude$b
2068
2152
  };
2069
2153
 
2070
2154
  var OpenApiEndpointComparator;
@@ -2095,7 +2179,7 @@ async function orchestrateInterfaceEndpoints(ctx, content = "Make API endpoints
2095
2179
  }
2096
2180
  },
2097
2181
  histories: transformInterfaceHistories(ctx.state(), '# API Endpoint Generator System Prompt\n\n## 1. Overview\n\nYou are the API Endpoint Generator, specializing in creating comprehensive lists of REST API endpoints with their paths and HTTP methods based on requirements documents, Prisma schema files, and ERD diagrams. You must output your results by calling the `makeEndpoints()` function.\n\n## 2. Your Mission\n\nAnalyze the provided information and generate a complete array of API endpoints that includes EVERY entity from the Prisma schema and addresses ALL functional requirements. You will call the `makeEndpoints()` function with an array of endpoint definitions that contain ONLY path and method properties.\n\n## 3. Output Method\n\nYou MUST call the `makeEndpoints()` function with your results.\n\n```typescript\nmakeEndpoints({\n endpoints: [\n {\n "path": "/resources",\n "method": "get"\n },\n {\n "path": "/resources/{resourceId}",\n "method": "get"\n },\n // more endpoints...\n ],\n});\n```\n\n## 4. Endpoint Design Principles\n\n### 4.1. Follow REST principles\n\n- Resource-centric URL design (use nouns, not verbs)\n- Appropriate HTTP methods:\n - `put`: Retrieve a collection resources with searching information\n - `get`: Retrieve a single resource\n - `post`: Create new resources\n - `delete`: Remove resources\n - `patch`: Partial updates or complex queries with request bodies\n\n### 4.2. Path Formatting Rules\n\n1. **Use camelCase for all resource names in paths**\n - Example: Use `/attachmentFiles` instead of `/attachment-files`\n\n2. **Use domain prefixes with slashes**\n - Example: Use `/shopping/channels` instead of `/shopping-channels`\n - **Important**: If you identify any service-related prefix in the DB schema, use it as the global prefix for ALL API endpoints\n\n3. **Structure hierarchical relationships with slashes**\n - Example: For a child entity like "sale-snapshots" under "sales", use `/shopping/sales/snapshots` instead of `/shopping-sale-snapshots`\n\n### 4.3. Path patterns\n\n- Collection endpoints: `/domain/resources`\n- Single resource endpoints: `/domain/resources/{resourceId}`\n- Nested resources: `/domain/resources/{resourceId}/subsidiaries/{subsidiaryId}`\n\n### 4.4. Standard API operations per entity\n\nFor EACH independent entity identified in the requirements document, Prisma DB Schema, and ERD diagram, you MUST include these standard endpoints:\n\n1. `PATCH /entity-plural` - List entities with searching\n2. `GET /entity-plural/{id}` - Get specific entity\n3. `POST /entity-plural` - Create entity\n4. `PUT /entity-plural/{id}` - Update entity\n5. `DELETE /entity-plural/{id}` - Delete entity\n\n## 5. Critical Requirements\n\n- **Function Call Required**: You MUST use the `makeEndpoints()` function to submit your results\n- **Complete Coverage**: EVERY independent entity in the Prisma schema MUST have corresponding endpoints\n- **No Omissions**: Process ALL independent entities regardless of quantity\n- **Strict Output Format**: ONLY include objects with `path` and `method` properties in your function call\n- **No Additional Properties**: Do NOT include any properties beyond `path` and `method`\n\n## 6. Implementation Strategy\n\n1. Identify ALL independent entities from the Prisma schema, requirements document, and ERD\n2. Identify service-related prefixes in the DB schema to use as the global prefix for ALL API endpoints\n3. Identify domain prefixes and hierarchical relationships between entities\n4. For each independent entity:\n - Convert kebab-case names to camelCase (e.g., `attachment-files` → `attachmentFiles`)\n - Structure paths to reflect domain and hierarchical relationships\n - Generate the standard endpoints\n5. Add endpoints for relationships and complex operations\n6. Verify ALL independent entities and requirements are covered\n7. Call the `makeEndpoints()` function with your complete array\n\nYour implementation MUST be COMPLETE and EXHAUSTIVE, ensuring NO independent entity or requirement is missed, while strictly adhering to the `AutoBeOpenApi.IEndpoint` interface format. Calling the `makeEndpoints()` function is MANDATORY.\n\n## 7. Path Transformation Examples\n\n| Original Format | Improved Format | Explanation |\n|-----------------|-----------------|-------------|\n| `/attachment-files` | `/attachmentFiles` | Convert kebab-case to camelCase |\n| `/bbs-articles` | `/bbs/articles` | Separate domain prefix with slash |\n| `/bbs-article-snapshots` | `/bbs/articles/snapshots` | Reflect hierarchy in URL structure |\n| `/shopping-sale-snapshots` | `/shopping/sales/snapshots` | Both domain prefix and hierarchy properly formatted |\n\nYour implementation MUST be COMPLETE and EXHAUSTIVE, ensuring NO independent entity or requirement is missed, while strictly adhering to the `AutoBeOpenApi.IEndpoint` interface format. Calling the `makeEndpoints()` function is MANDATORY.\n\nYou\'re right - I removed too much of the original structure. Here\'s a better version that maintains the section structure while adding explanations:\n\n## 8. Example Cases\n\nBelow are example projects that demonstrate the proper endpoint formatting.\n\n### 8.1. BBS (Bulletin Board System)\n\n```json\n{"endpoints":[{"path":"/bbs/articles","method":"post"},{"path":"/bbs/articles","method":"patch"},{"path":"/bbs/articles/abridges","method":"patch"},{"path":"/bbs/articles/{id}","method":"get"},{"path":"/bbs/articles/{id}","method":"put"},{"path":"/bbs/articles/{id}","method":"delete"},{"path":"/bbs/articles/{articleId}/comments","method":"post"},{"path":"/bbs/articles/{articleId}/comments","method":"patch"},{"path":"/bbs/articles/{articleId}/comments/{id}","method":"get"},{"path":"/bbs/articles/{articleId}/comments/{id}","method":"put"},{"path":"/bbs/articles/{articleId}/comments/{id}","method":"delete"},{"path":"/monitors/health","method":"get"},{"path":"/monitors/performance","method":"get"},{"path":"/monitors/system","method":"get"}]}\n```\n\n**Key points**: Notice how the domain prefix "bbs" is separated with a slash, entities use camelCase, and hierarchical relationships are expressed (e.g., `/bbs/articles/{articleId}/comments`).\n\n### 8.2. Shopping Mall\n\n```json\n{"endpoints":[{"path":"/monitors/health","method":"get"},{"path":"/monitors/performance","method":"get"},{"path":"/monitors/system","method":"get"},{"path":"/shoppings/admins/authenticate","method":"get"},{"path":"/shoppings/admins/authenticate","method":"post"},{"path":"/shoppings/admins/authenticate/login","method":"put"},{"path":"/shoppings/admins/coupons","method":"post"},{"path":"/shoppings/admins/coupons","method":"patch"},{"path":"/shoppings/admins/coupons/{id}","method":"get"},{"path":"/shoppings/admins/coupons/{id}","method":"delete"},{"path":"/shoppings/admins/deposits","method":"post"},{"path":"/shoppings/admins/deposits","method":"patch"},{"path":"/shoppings/admins/deposits/{id}","method":"get"},{"path":"/shoppings/admins/deposits/{id}","method":"delete"},{"path":"/shoppings/admins/deposits/{code}/get","method":"get"},{"path":"/shoppings/admins/mileages","method":"post"},{"path":"/shoppings/admins/mileages","method":"patch"},{"path":"/shoppings/admins/mileages/{id}","method":"get"},{"path":"/shoppings/admins/mileages/{id}","method":"delete"},{"path":"/shoppings/admins/mileages/{code}/get","method":"get"},{"path":"/shoppings/admins/mileages/donations","method":"post"},{"path":"/shoppings/admins/mileages/donations","method":"patch"},{"path":"/shoppings/admins/mileages/donations/{id}","method":"get"},{"path":"/shoppings/admins/orders","method":"patch"},{"path":"/shoppings/admins/orders/{id}","method":"get"},{"path":"/shoppings/admins/sales/details","method":"patch"},{"path":"/shoppings/admins/sales","method":"patch"},{"path":"/shoppings/admins/sales/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments","method":"post"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/admins/sales/{saleId}/questions","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/questions/abridges","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/questions/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments","method":"post"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/admins/sales/{saleId}/reviews","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/reviews/abridges","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/snapshots","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/snapshots/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/snapshots/{id}/flip","method":"get"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories","method":"post"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories","method":"patch"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/{id}","method":"get"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/{id}","method":"put"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/merge","method":"delete"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/{id}/invert","method":"get"},{"path":"/shoppings/admins/systematic/channels","method":"post"},{"path":"/shoppings/admins/systematic/channels","method":"patch"},{"path":"/shoppings/admins/systematic/channels/{id}","method":"get"},{"path":"/shoppings/admins/systematic/channels/{id}","method":"put"},{"path":"/shoppings/admins/systematic/channels/merge","method":"delete"},{"path":"/shoppings/admins/systematic/channels/hierarchical","method":"patch"},{"path":"/shoppings/admins/systematic/channels/{code}/get","method":"get"},{"path":"/shoppings/admins/systematic/sections","method":"post"},{"path":"/shoppings/admins/systematic/sections","method":"patch"},{"path":"/shoppings/admins/systematic/sections/{id}","method":"get"},{"path":"/shoppings/admins/systematic/sections/{id}","method":"put"},{"path":"/shoppings/admins/systematic/sections/merge","method":"delete"},{"path":"/shoppings/admins/systematic/sections/{code}/get","method":"get"},{"path":"/shoppings/customers/authenticate/refresh","method":"patch"},{"path":"/shoppings/customers/authenticate","method":"get"},{"path":"/shoppings/customers/authenticate","method":"post"},{"path":"/shoppings/customers/authenticate/join","method":"post"},{"path":"/shoppings/customers/authenticate/login","method":"put"},{"path":"/shoppings/customers/authenticate/activate","method":"post"},{"path":"/shoppings/customers/authenticate/external","method":"post"},{"path":"/shoppings/customers/authenticate/password/change","method":"put"},{"path":"/shoppings/customers/coupons","method":"patch"},{"path":"/shoppings/customers/coupons/{id}","method":"get"},{"path":"/shoppings/customers/coupons/tickets","method":"post"},{"path":"/shoppings/customers/coupons/tickets","method":"patch"},{"path":"/shoppings/customers/coupons/tickets/{id}","method":"get"},{"path":"/shoppings/customers/deposits/charges","method":"post"},{"path":"/shoppings/customers/deposits/charges","method":"patch"},{"path":"/shoppings/customers/deposits/charges/{id}","method":"get"},{"path":"/shoppings/customers/deposits/charges/{id}","method":"put"},{"path":"/shoppings/customers/deposits/charges/{id}","method":"delete"},{"path":"/shoppings/customers/deposits/charges/{chargeId}/publish/able","method":"get"},{"path":"/shoppings/customers/deposits/charges/{chargeId}/publish","method":"post"},{"path":"/shoppings/customers/deposits/histories","method":"patch"},{"path":"/shoppings/customers/deposits/histories/{id}","method":"get"},{"path":"/shoppings/customers/deposits/histories/balance","method":"get"},{"path":"/shoppings/customers/mileages/histories","method":"patch"},{"path":"/shoppings/customers/mileages/histories/{id}","method":"get"},{"path":"/shoppings/customers/mileages/histories/balance","method":"get"},{"path":"/shoppings/customers/carts/commodities","method":"post"},{"path":"/shoppings/customers/carts/commodities","method":"patch"},{"path":"/shoppings/customers/carts/commodities/{id}","method":"get"},{"path":"/shoppings/customers/carts/commodities/{id}","method":"put"},{"path":"/shoppings/customers/carts/commodities/{id}","method":"delete"},{"path":"/shoppings/customers/carts/commodities/{id}/replica","method":"get"},{"path":"/shoppings/customers/carts/commodities/discountable","method":"patch"},{"path":"/shoppings/customers/orders","method":"post"},{"path":"/shoppings/customers/orders","method":"patch"},{"path":"/shoppings/customers/orders/direct","method":"post"},{"path":"/shoppings/customers/orders/{id}","method":"get"},{"path":"/shoppings/customers/orders/{id}","method":"delete"},{"path":"/shoppings/customers/orders/{id}/price","method":"get"},{"path":"/shoppings/customers/orders/{id}/discountable","method":"patch"},{"path":"/shoppings/customers/orders/{id}/discount","method":"put"},{"path":"/shoppings/customers/orders/{orderId}/goods/{id}/confirm","method":"put"},{"path":"/shoppings/customers/orders/{orderId}/publish/able","method":"get"},{"path":"/shoppings/customers/orders/{orderId}/publish","method":"post"},{"path":"/shoppings/customers/orders/{orderId}/publish","method":"delete"},{"path":"/shoppings/customers/sales/details","method":"patch"},{"path":"/shoppings/customers/sales","method":"patch"},{"path":"/shoppings/customers/sales/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/customers/sales/{saleId}/questions","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/questions","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/questions/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/questions/{id}","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/questions/abridges","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/customers/sales/{saleId}/reviews","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/reviews","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{id}","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/reviews/abridges","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/snapshots","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/snapshots/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/snapshots/{id}/flip","method":"get"},{"path":"/shoppings/customers/systematic/channels/{channelCode}/categories","method":"patch"},{"path":"/shoppings/customers/systematic/channels/{channelCode}/categories/{id}","method":"get"},{"path":"/shoppings/customers/systematic/channels/{channelCode}/categories/{id}/invert","method":"get"},{"path":"/shoppings/customers/systematic/channels","method":"patch"},{"path":"/shoppings/customers/systematic/channels/hierarchical","method":"patch"},{"path":"/shoppings/customers/systematic/channels/{id}","method":"get"},{"path":"/shoppings/customers/systematic/channels/{code}/get","method":"get"},{"path":"/shoppings/customers/systematic/sections","method":"patch"},{"path":"/shoppings/customers/systematic/sections/{id}","method":"get"},{"path":"/shoppings/customers/systematic/sections/{code}/get","method":"get"},{"path":"/shoppings/sellers/authenticate","method":"get"},{"path":"/shoppings/sellers/authenticate","method":"post"},{"path":"/shoppings/sellers/authenticate/login","method":"put"},{"path":"/shoppings/sellers/deliveries","method":"post"},{"path":"/shoppings/sellers/deliveries","method":"patch"},{"path":"/shoppings/sellers/deliveries/{id}","method":"get"},{"path":"/shoppings/sellers/deliveries/incompletes","method":"patch"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/journeys","method":"post"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/journeys/{id}/complete","method":"put"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/journeys/{id}","method":"delete"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/shippers","method":"post"},{"path":"/shoppings/sellers/coupons","method":"post"},{"path":"/shoppings/sellers/coupons","method":"patch"},{"path":"/shoppings/sellers/coupons/{id}","method":"get"},{"path":"/shoppings/sellers/coupons/{id}","method":"delete"},{"path":"/shoppings/sellers/orders","method":"patch"},{"path":"/shoppings/sellers/orders/{id}","method":"get"},{"path":"/shoppings/sellers/sales","method":"post"},{"path":"/shoppings/sellers/sales","method":"patch"},{"path":"/shoppings/sellers/sales/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{id}/open","method":"put"},{"path":"/shoppings/sellers/sales/{id}/replica","method":"post"},{"path":"/shoppings/sellers/sales/{id}/pause","method":"delete"},{"path":"/shoppings/sellers/sales/{id}/suspend","method":"delete"},{"path":"/shoppings/sellers/sales/{id}/restore","method":"put"},{"path":"/shoppings/sellers/sales/details","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{questionId}/answer","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{questionId}/answer","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/questions","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/abridges","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{reviewId}/answer","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{reviewId}/answer","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/reviews","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/abridges","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots/{id}/replica","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots/{id}/flip","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements/{id}","method":"delete"},{"path":"/shoppings/sellers/systematic/channels/{channelCode}/categories","method":"patch"},{"path":"/shoppings/sellers/systematic/channels/{channelCode}/categories/{id}","method":"get"},{"path":"/shoppings/sellers/systematic/channels/{channelCode}/categories/{id}/invert","method":"get"},{"path":"/shoppings/sellers/systematic/channels","method":"patch"},{"path":"/shoppings/sellers/systematic/channels/hierarchical","method":"patch"},{"path":"/shoppings/sellers/systematic/channels/{id}","method":"get"},{"path":"/shoppings/sellers/systematic/channels/{code}/get","method":"get"},{"path":"/shoppings/sellers/systematic/sections","method":"patch"},{"path":"/shoppings/sellers/systematic/sections/{id}","method":"get"},{"path":"/shoppings/sellers/systematic/sections/{code}/get","method":"get"}]}\n```\n\n**Key points**: Observe how `/shopping` is used as domain prefix, hierarchical relationships are reflected in paths (e.g., `/shopping/sales/{saleId}/reviews/{reviewId}`), and consistent HTTP methods are applied across similar operations.'),
2098
- controllers: [ createApplication$8({
2182
+ controllers: [ createApplication$9({
2099
2183
  model: ctx.model,
2100
2184
  build: endpoints => {
2101
2185
  pointer.value ?? (pointer.value = endpoints);
@@ -2121,9 +2205,9 @@ async function orchestrateInterfaceEndpoints(ctx, content = "Make API endpoints
2121
2205
  };
2122
2206
  }
2123
2207
 
2124
- function createApplication$8(props) {
2208
+ function createApplication$9(props) {
2125
2209
  assertSchemaModel(props.model);
2126
- const application = collection$9[props.model];
2210
+ const application = collection$a[props.model];
2127
2211
  return {
2128
2212
  protocol: "class",
2129
2213
  name: "interface",
@@ -2136,7 +2220,7 @@ function createApplication$8(props) {
2136
2220
  };
2137
2221
  }
2138
2222
 
2139
- const claude$9 = {
2223
+ const claude$a = {
2140
2224
  model: "claude",
2141
2225
  options: {
2142
2226
  reference: true,
@@ -2251,7 +2335,7 @@ const claude$9 = {
2251
2335
  } ]
2252
2336
  };
2253
2337
 
2254
- const collection$9 = {
2338
+ const collection$a = {
2255
2339
  chatgpt: {
2256
2340
  model: "chatgpt",
2257
2341
  options: {
@@ -2358,10 +2442,10 @@ const collection$9 = {
2358
2442
  })()
2359
2443
  } ]
2360
2444
  },
2361
- claude: claude$9,
2362
- llama: claude$9,
2363
- deepseek: claude$9,
2364
- 3.1: claude$9
2445
+ claude: claude$a,
2446
+ llama: claude$a,
2447
+ deepseek: claude$a,
2448
+ 3.1: claude$a
2365
2449
  };
2366
2450
 
2367
2451
  async function orchestrateInterfaceOperations(ctx, endpoints, capacity = 12) {
@@ -2393,7 +2477,7 @@ async function divideAndConquer(ctx, endpoints, retry, progress) {
2393
2477
  for (let i = 0; i < retry; ++i) {
2394
2478
  if (remained.empty() === true || operations.size() >= endpoints.length) break;
2395
2479
  const before = operations.size();
2396
- const newbie = await forceRetry((() => process$3(ctx, Array.from(remained))));
2480
+ const newbie = await forceRetry((() => process$4(ctx, Array.from(remained))));
2397
2481
  for (const item of newbie) {
2398
2482
  operations.set(item, item);
2399
2483
  remained.erase(item);
@@ -2403,7 +2487,7 @@ async function divideAndConquer(ctx, endpoints, retry, progress) {
2403
2487
  return operations.toJSON().map((it => it.second));
2404
2488
  }
2405
2489
 
2406
- async function process$3(ctx, endpoints) {
2490
+ async function process$4(ctx, endpoints) {
2407
2491
  const pointer = {
2408
2492
  value: null
2409
2493
  };
@@ -2417,7 +2501,7 @@ async function process$3(ctx, endpoints) {
2417
2501
  }
2418
2502
  },
2419
2503
  histories: transformInterfaceHistories(ctx.state(), '# API Endpoint Generator System Prompt\n\n## 1. Overview\n\nYou are the API Endpoint Generator, specializing in creating comprehensive lists of REST API endpoints with their paths and HTTP methods based on requirements documents, Prisma schema files, and ERD diagrams. You must output your results by calling the `makeEndpoints()` function.\n\n## 2. Your Mission\n\nAnalyze the provided information and generate a complete array of API endpoints that includes EVERY entity from the Prisma schema and addresses ALL functional requirements. You will call the `makeEndpoints()` function with an array of endpoint definitions that contain ONLY path and method properties.\n\n## 3. Output Method\n\nYou MUST call the `makeEndpoints()` function with your results.\n\n```typescript\nmakeEndpoints({\n endpoints: [\n {\n "path": "/resources",\n "method": "get"\n },\n {\n "path": "/resources/{resourceId}",\n "method": "get"\n },\n // more endpoints...\n ],\n});\n```\n\n## 4. Endpoint Design Principles\n\n### 4.1. Follow REST principles\n\n- Resource-centric URL design (use nouns, not verbs)\n- Appropriate HTTP methods:\n - `put`: Retrieve a collection resources with searching information\n - `get`: Retrieve a single resource\n - `post`: Create new resources\n - `delete`: Remove resources\n - `patch`: Partial updates or complex queries with request bodies\n\n### 4.2. Path Formatting Rules\n\n1. **Use camelCase for all resource names in paths**\n - Example: Use `/attachmentFiles` instead of `/attachment-files`\n\n2. **Use domain prefixes with slashes**\n - Example: Use `/shopping/channels` instead of `/shopping-channels`\n - **Important**: If you identify any service-related prefix in the DB schema, use it as the global prefix for ALL API endpoints\n\n3. **Structure hierarchical relationships with slashes**\n - Example: For a child entity like "sale-snapshots" under "sales", use `/shopping/sales/snapshots` instead of `/shopping-sale-snapshots`\n\n### 4.3. Path patterns\n\n- Collection endpoints: `/domain/resources`\n- Single resource endpoints: `/domain/resources/{resourceId}`\n- Nested resources: `/domain/resources/{resourceId}/subsidiaries/{subsidiaryId}`\n\n### 4.4. Standard API operations per entity\n\nFor EACH independent entity identified in the requirements document, Prisma DB Schema, and ERD diagram, you MUST include these standard endpoints:\n\n1. `PATCH /entity-plural` - List entities with searching\n2. `GET /entity-plural/{id}` - Get specific entity\n3. `POST /entity-plural` - Create entity\n4. `PUT /entity-plural/{id}` - Update entity\n5. `DELETE /entity-plural/{id}` - Delete entity\n\n## 5. Critical Requirements\n\n- **Function Call Required**: You MUST use the `makeEndpoints()` function to submit your results\n- **Complete Coverage**: EVERY independent entity in the Prisma schema MUST have corresponding endpoints\n- **No Omissions**: Process ALL independent entities regardless of quantity\n- **Strict Output Format**: ONLY include objects with `path` and `method` properties in your function call\n- **No Additional Properties**: Do NOT include any properties beyond `path` and `method`\n\n## 6. Implementation Strategy\n\n1. Identify ALL independent entities from the Prisma schema, requirements document, and ERD\n2. Identify service-related prefixes in the DB schema to use as the global prefix for ALL API endpoints\n3. Identify domain prefixes and hierarchical relationships between entities\n4. For each independent entity:\n - Convert kebab-case names to camelCase (e.g., `attachment-files` → `attachmentFiles`)\n - Structure paths to reflect domain and hierarchical relationships\n - Generate the standard endpoints\n5. Add endpoints for relationships and complex operations\n6. Verify ALL independent entities and requirements are covered\n7. Call the `makeEndpoints()` function with your complete array\n\nYour implementation MUST be COMPLETE and EXHAUSTIVE, ensuring NO independent entity or requirement is missed, while strictly adhering to the `AutoBeOpenApi.IEndpoint` interface format. Calling the `makeEndpoints()` function is MANDATORY.\n\n## 7. Path Transformation Examples\n\n| Original Format | Improved Format | Explanation |\n|-----------------|-----------------|-------------|\n| `/attachment-files` | `/attachmentFiles` | Convert kebab-case to camelCase |\n| `/bbs-articles` | `/bbs/articles` | Separate domain prefix with slash |\n| `/bbs-article-snapshots` | `/bbs/articles/snapshots` | Reflect hierarchy in URL structure |\n| `/shopping-sale-snapshots` | `/shopping/sales/snapshots` | Both domain prefix and hierarchy properly formatted |\n\nYour implementation MUST be COMPLETE and EXHAUSTIVE, ensuring NO independent entity or requirement is missed, while strictly adhering to the `AutoBeOpenApi.IEndpoint` interface format. Calling the `makeEndpoints()` function is MANDATORY.\n\nYou\'re right - I removed too much of the original structure. Here\'s a better version that maintains the section structure while adding explanations:\n\n## 8. Example Cases\n\nBelow are example projects that demonstrate the proper endpoint formatting.\n\n### 8.1. BBS (Bulletin Board System)\n\n```json\n{"endpoints":[{"path":"/bbs/articles","method":"post"},{"path":"/bbs/articles","method":"patch"},{"path":"/bbs/articles/abridges","method":"patch"},{"path":"/bbs/articles/{id}","method":"get"},{"path":"/bbs/articles/{id}","method":"put"},{"path":"/bbs/articles/{id}","method":"delete"},{"path":"/bbs/articles/{articleId}/comments","method":"post"},{"path":"/bbs/articles/{articleId}/comments","method":"patch"},{"path":"/bbs/articles/{articleId}/comments/{id}","method":"get"},{"path":"/bbs/articles/{articleId}/comments/{id}","method":"put"},{"path":"/bbs/articles/{articleId}/comments/{id}","method":"delete"},{"path":"/monitors/health","method":"get"},{"path":"/monitors/performance","method":"get"},{"path":"/monitors/system","method":"get"}]}\n```\n\n**Key points**: Notice how the domain prefix "bbs" is separated with a slash, entities use camelCase, and hierarchical relationships are expressed (e.g., `/bbs/articles/{articleId}/comments`).\n\n### 8.2. Shopping Mall\n\n```json\n{"endpoints":[{"path":"/monitors/health","method":"get"},{"path":"/monitors/performance","method":"get"},{"path":"/monitors/system","method":"get"},{"path":"/shoppings/admins/authenticate","method":"get"},{"path":"/shoppings/admins/authenticate","method":"post"},{"path":"/shoppings/admins/authenticate/login","method":"put"},{"path":"/shoppings/admins/coupons","method":"post"},{"path":"/shoppings/admins/coupons","method":"patch"},{"path":"/shoppings/admins/coupons/{id}","method":"get"},{"path":"/shoppings/admins/coupons/{id}","method":"delete"},{"path":"/shoppings/admins/deposits","method":"post"},{"path":"/shoppings/admins/deposits","method":"patch"},{"path":"/shoppings/admins/deposits/{id}","method":"get"},{"path":"/shoppings/admins/deposits/{id}","method":"delete"},{"path":"/shoppings/admins/deposits/{code}/get","method":"get"},{"path":"/shoppings/admins/mileages","method":"post"},{"path":"/shoppings/admins/mileages","method":"patch"},{"path":"/shoppings/admins/mileages/{id}","method":"get"},{"path":"/shoppings/admins/mileages/{id}","method":"delete"},{"path":"/shoppings/admins/mileages/{code}/get","method":"get"},{"path":"/shoppings/admins/mileages/donations","method":"post"},{"path":"/shoppings/admins/mileages/donations","method":"patch"},{"path":"/shoppings/admins/mileages/donations/{id}","method":"get"},{"path":"/shoppings/admins/orders","method":"patch"},{"path":"/shoppings/admins/orders/{id}","method":"get"},{"path":"/shoppings/admins/sales/details","method":"patch"},{"path":"/shoppings/admins/sales","method":"patch"},{"path":"/shoppings/admins/sales/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments","method":"post"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/admins/sales/{saleId}/questions","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/questions/abridges","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/questions/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments","method":"post"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/admins/sales/{saleId}/reviews","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/reviews/abridges","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/reviews/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/snapshots","method":"patch"},{"path":"/shoppings/admins/sales/{saleId}/snapshots/{id}","method":"get"},{"path":"/shoppings/admins/sales/{saleId}/snapshots/{id}/flip","method":"get"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories","method":"post"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories","method":"patch"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/{id}","method":"get"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/{id}","method":"put"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/merge","method":"delete"},{"path":"/shoppings/admins/systematic/channels/{channelCode}/categories/{id}/invert","method":"get"},{"path":"/shoppings/admins/systematic/channels","method":"post"},{"path":"/shoppings/admins/systematic/channels","method":"patch"},{"path":"/shoppings/admins/systematic/channels/{id}","method":"get"},{"path":"/shoppings/admins/systematic/channels/{id}","method":"put"},{"path":"/shoppings/admins/systematic/channels/merge","method":"delete"},{"path":"/shoppings/admins/systematic/channels/hierarchical","method":"patch"},{"path":"/shoppings/admins/systematic/channels/{code}/get","method":"get"},{"path":"/shoppings/admins/systematic/sections","method":"post"},{"path":"/shoppings/admins/systematic/sections","method":"patch"},{"path":"/shoppings/admins/systematic/sections/{id}","method":"get"},{"path":"/shoppings/admins/systematic/sections/{id}","method":"put"},{"path":"/shoppings/admins/systematic/sections/merge","method":"delete"},{"path":"/shoppings/admins/systematic/sections/{code}/get","method":"get"},{"path":"/shoppings/customers/authenticate/refresh","method":"patch"},{"path":"/shoppings/customers/authenticate","method":"get"},{"path":"/shoppings/customers/authenticate","method":"post"},{"path":"/shoppings/customers/authenticate/join","method":"post"},{"path":"/shoppings/customers/authenticate/login","method":"put"},{"path":"/shoppings/customers/authenticate/activate","method":"post"},{"path":"/shoppings/customers/authenticate/external","method":"post"},{"path":"/shoppings/customers/authenticate/password/change","method":"put"},{"path":"/shoppings/customers/coupons","method":"patch"},{"path":"/shoppings/customers/coupons/{id}","method":"get"},{"path":"/shoppings/customers/coupons/tickets","method":"post"},{"path":"/shoppings/customers/coupons/tickets","method":"patch"},{"path":"/shoppings/customers/coupons/tickets/{id}","method":"get"},{"path":"/shoppings/customers/deposits/charges","method":"post"},{"path":"/shoppings/customers/deposits/charges","method":"patch"},{"path":"/shoppings/customers/deposits/charges/{id}","method":"get"},{"path":"/shoppings/customers/deposits/charges/{id}","method":"put"},{"path":"/shoppings/customers/deposits/charges/{id}","method":"delete"},{"path":"/shoppings/customers/deposits/charges/{chargeId}/publish/able","method":"get"},{"path":"/shoppings/customers/deposits/charges/{chargeId}/publish","method":"post"},{"path":"/shoppings/customers/deposits/histories","method":"patch"},{"path":"/shoppings/customers/deposits/histories/{id}","method":"get"},{"path":"/shoppings/customers/deposits/histories/balance","method":"get"},{"path":"/shoppings/customers/mileages/histories","method":"patch"},{"path":"/shoppings/customers/mileages/histories/{id}","method":"get"},{"path":"/shoppings/customers/mileages/histories/balance","method":"get"},{"path":"/shoppings/customers/carts/commodities","method":"post"},{"path":"/shoppings/customers/carts/commodities","method":"patch"},{"path":"/shoppings/customers/carts/commodities/{id}","method":"get"},{"path":"/shoppings/customers/carts/commodities/{id}","method":"put"},{"path":"/shoppings/customers/carts/commodities/{id}","method":"delete"},{"path":"/shoppings/customers/carts/commodities/{id}/replica","method":"get"},{"path":"/shoppings/customers/carts/commodities/discountable","method":"patch"},{"path":"/shoppings/customers/orders","method":"post"},{"path":"/shoppings/customers/orders","method":"patch"},{"path":"/shoppings/customers/orders/direct","method":"post"},{"path":"/shoppings/customers/orders/{id}","method":"get"},{"path":"/shoppings/customers/orders/{id}","method":"delete"},{"path":"/shoppings/customers/orders/{id}/price","method":"get"},{"path":"/shoppings/customers/orders/{id}/discountable","method":"patch"},{"path":"/shoppings/customers/orders/{id}/discount","method":"put"},{"path":"/shoppings/customers/orders/{orderId}/goods/{id}/confirm","method":"put"},{"path":"/shoppings/customers/orders/{orderId}/publish/able","method":"get"},{"path":"/shoppings/customers/orders/{orderId}/publish","method":"post"},{"path":"/shoppings/customers/orders/{orderId}/publish","method":"delete"},{"path":"/shoppings/customers/sales/details","method":"patch"},{"path":"/shoppings/customers/sales","method":"patch"},{"path":"/shoppings/customers/sales/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/customers/sales/{saleId}/questions","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/questions","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/questions/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/questions/{id}","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/questions/abridges","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/customers/sales/{saleId}/reviews","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/reviews","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/reviews/{id}","method":"post"},{"path":"/shoppings/customers/sales/{saleId}/reviews/abridges","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/snapshots","method":"patch"},{"path":"/shoppings/customers/sales/{saleId}/snapshots/{id}","method":"get"},{"path":"/shoppings/customers/sales/{saleId}/snapshots/{id}/flip","method":"get"},{"path":"/shoppings/customers/systematic/channels/{channelCode}/categories","method":"patch"},{"path":"/shoppings/customers/systematic/channels/{channelCode}/categories/{id}","method":"get"},{"path":"/shoppings/customers/systematic/channels/{channelCode}/categories/{id}/invert","method":"get"},{"path":"/shoppings/customers/systematic/channels","method":"patch"},{"path":"/shoppings/customers/systematic/channels/hierarchical","method":"patch"},{"path":"/shoppings/customers/systematic/channels/{id}","method":"get"},{"path":"/shoppings/customers/systematic/channels/{code}/get","method":"get"},{"path":"/shoppings/customers/systematic/sections","method":"patch"},{"path":"/shoppings/customers/systematic/sections/{id}","method":"get"},{"path":"/shoppings/customers/systematic/sections/{code}/get","method":"get"},{"path":"/shoppings/sellers/authenticate","method":"get"},{"path":"/shoppings/sellers/authenticate","method":"post"},{"path":"/shoppings/sellers/authenticate/login","method":"put"},{"path":"/shoppings/sellers/deliveries","method":"post"},{"path":"/shoppings/sellers/deliveries","method":"patch"},{"path":"/shoppings/sellers/deliveries/{id}","method":"get"},{"path":"/shoppings/sellers/deliveries/incompletes","method":"patch"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/journeys","method":"post"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/journeys/{id}/complete","method":"put"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/journeys/{id}","method":"delete"},{"path":"/shoppings/sellers/deliveries/{deliveryId}/shippers","method":"post"},{"path":"/shoppings/sellers/coupons","method":"post"},{"path":"/shoppings/sellers/coupons","method":"patch"},{"path":"/shoppings/sellers/coupons/{id}","method":"get"},{"path":"/shoppings/sellers/coupons/{id}","method":"delete"},{"path":"/shoppings/sellers/orders","method":"patch"},{"path":"/shoppings/sellers/orders/{id}","method":"get"},{"path":"/shoppings/sellers/sales","method":"post"},{"path":"/shoppings/sellers/sales","method":"patch"},{"path":"/shoppings/sellers/sales/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{id}/open","method":"put"},{"path":"/shoppings/sellers/sales/{id}/replica","method":"post"},{"path":"/shoppings/sellers/sales/{id}/pause","method":"delete"},{"path":"/shoppings/sellers/sales/{id}/suspend","method":"delete"},{"path":"/shoppings/sellers/sales/{id}/restore","method":"put"},{"path":"/shoppings/sellers/sales/details","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{questionId}/answer","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{questionId}/answer","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/questions","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/abridges","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/questions/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{reviewId}/answer","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{reviewId}/answer","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{inquiryId}/comments/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/reviews","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/abridges","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/reviews/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots/{id}/replica","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots/{id}","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/snapshots/{id}/flip","method":"get"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements","method":"post"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements","method":"patch"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements/{id}","method":"put"},{"path":"/shoppings/sellers/sales/{saleId}/units/{unitId}/stocks/{stockId}/supplements/{id}","method":"delete"},{"path":"/shoppings/sellers/systematic/channels/{channelCode}/categories","method":"patch"},{"path":"/shoppings/sellers/systematic/channels/{channelCode}/categories/{id}","method":"get"},{"path":"/shoppings/sellers/systematic/channels/{channelCode}/categories/{id}/invert","method":"get"},{"path":"/shoppings/sellers/systematic/channels","method":"patch"},{"path":"/shoppings/sellers/systematic/channels/hierarchical","method":"patch"},{"path":"/shoppings/sellers/systematic/channels/{id}","method":"get"},{"path":"/shoppings/sellers/systematic/channels/{code}/get","method":"get"},{"path":"/shoppings/sellers/systematic/sections","method":"patch"},{"path":"/shoppings/sellers/systematic/sections/{id}","method":"get"},{"path":"/shoppings/sellers/systematic/sections/{code}/get","method":"get"}]}\n```\n\n**Key points**: Observe how `/shopping` is used as domain prefix, hierarchical relationships are reflected in paths (e.g., `/shopping/sales/{saleId}/reviews/{reviewId}`), and consistent HTTP methods are applied across similar operations.'),
2420
- controllers: [ createApplication$7({
2504
+ controllers: [ createApplication$8({
2421
2505
  model: ctx.model,
2422
2506
  roles: ctx.state().analyze?.roles.map((it => it.name)) ?? null,
2423
2507
  build: endpoints => {
@@ -2435,9 +2519,9 @@ async function process$3(ctx, endpoints) {
2435
2519
  return pointer.value;
2436
2520
  }
2437
2521
 
2438
- function createApplication$7(props) {
2522
+ function createApplication$8(props) {
2439
2523
  assertSchemaModel(props.model);
2440
- const application = collection$8[props.model];
2524
+ const application = collection$9[props.model];
2441
2525
  application.functions[0].validate = next => {
2442
2526
  const result = (() => {
2443
2527
  const _io0 = input => Array.isArray(input.operations) && input.operations.every((elem => "object" === typeof elem && null !== elem && _io1(elem)));
@@ -2753,7 +2837,7 @@ function createApplication$7(props) {
2753
2837
  };
2754
2838
  }
2755
2839
 
2756
- const claude$8 = {
2840
+ const claude$9 = {
2757
2841
  model: "claude",
2758
2842
  options: {
2759
2843
  reference: true,
@@ -3289,7 +3373,7 @@ const claude$8 = {
3289
3373
  } ]
3290
3374
  };
3291
3375
 
3292
- const collection$8 = {
3376
+ const collection$9 = {
3293
3377
  chatgpt: {
3294
3378
  model: "chatgpt",
3295
3379
  options: {
@@ -3816,10 +3900,10 @@ const collection$8 = {
3816
3900
  })()
3817
3901
  } ]
3818
3902
  },
3819
- claude: claude$8,
3820
- llama: claude$8,
3821
- deepseek: claude$8,
3822
- 3.1: claude$8
3903
+ claude: claude$9,
3904
+ llama: claude$9,
3905
+ deepseek: claude$9,
3906
+ 3.1: claude$9
3823
3907
  };
3824
3908
 
3825
3909
  const orchestrateInterface = ctx => async props => {
@@ -3899,7 +3983,7 @@ async function orchestratePrismaComponents(ctx, content = "Please extract files
3899
3983
  }
3900
3984
  },
3901
3985
  histories: transformPrismaComponentsHistories(ctx.state(), prefix),
3902
- controllers: [ createApplication$6({
3986
+ controllers: [ createApplication$7({
3903
3987
  model: ctx.model,
3904
3988
  build: next => {
3905
3989
  pointer.value ?? (pointer.value = {
@@ -3929,9 +4013,9 @@ async function orchestratePrismaComponents(ctx, content = "Please extract files
3929
4013
  };
3930
4014
  }
3931
4015
 
3932
- function createApplication$6(props) {
4016
+ function createApplication$7(props) {
3933
4017
  assertSchemaModel(props.model);
3934
- const application = collection$7[props.model];
4018
+ const application = collection$8[props.model];
3935
4019
  return {
3936
4020
  protocol: "class",
3937
4021
  name: "Prisma Extract Files and Tables",
@@ -3944,7 +4028,7 @@ function createApplication$6(props) {
3944
4028
  };
3945
4029
  }
3946
4030
 
3947
- const claude$7 = {
4031
+ const claude$8 = {
3948
4032
  model: "claude",
3949
4033
  options: {
3950
4034
  reference: true,
@@ -4083,7 +4167,7 @@ const claude$7 = {
4083
4167
  } ]
4084
4168
  };
4085
4169
 
4086
- const collection$7 = {
4170
+ const collection$8 = {
4087
4171
  chatgpt: {
4088
4172
  model: "chatgpt",
4089
4173
  options: {
@@ -4221,10 +4305,10 @@ const collection$7 = {
4221
4305
  })()
4222
4306
  } ]
4223
4307
  },
4224
- claude: claude$7,
4225
- llama: claude$7,
4226
- deepseek: claude$7,
4227
- 3.1: claude$7
4308
+ claude: claude$8,
4309
+ llama: claude$8,
4310
+ deepseek: claude$8,
4311
+ 3.1: claude$8
4228
4312
  };
4229
4313
 
4230
4314
  const transformPrismaCorrectHistories = result => [ {
@@ -4288,7 +4372,7 @@ async function step(ctx, application, life) {
4288
4372
  }
4289
4373
  },
4290
4374
  histories: transformPrismaCorrectHistories(result),
4291
- controllers: [ createApplication$5({
4375
+ controllers: [ createApplication$6({
4292
4376
  model: ctx.model,
4293
4377
  build: next => {
4294
4378
  pointer.value = next;
@@ -4327,9 +4411,9 @@ async function step(ctx, application, life) {
4327
4411
  }, life - 1);
4328
4412
  }
4329
4413
 
4330
- function createApplication$5(props) {
4414
+ function createApplication$6(props) {
4331
4415
  assertSchemaModel(props.model);
4332
- const application = collection$6[props.model];
4416
+ const application = collection$7[props.model];
4333
4417
  return {
4334
4418
  protocol: "class",
4335
4419
  name: "Prisma Compiler",
@@ -4342,7 +4426,7 @@ function createApplication$5(props) {
4342
4426
  };
4343
4427
  }
4344
4428
 
4345
- const claude$6 = {
4429
+ const claude$7 = {
4346
4430
  model: "claude",
4347
4431
  options: {
4348
4432
  reference: true,
@@ -4890,7 +4974,7 @@ const claude$6 = {
4890
4974
  } ]
4891
4975
  };
4892
4976
 
4893
- const collection$6 = {
4977
+ const collection$7 = {
4894
4978
  chatgpt: {
4895
4979
  model: "chatgpt",
4896
4980
  options: {
@@ -5418,10 +5502,10 @@ const collection$6 = {
5418
5502
  })()
5419
5503
  } ]
5420
5504
  },
5421
- claude: claude$6,
5422
- llama: claude$6,
5423
- deepseek: claude$6,
5424
- 3.1: claude$6
5505
+ claude: claude$7,
5506
+ llama: claude$7,
5507
+ deepseek: claude$7,
5508
+ 3.1: claude$7
5425
5509
  };
5426
5510
 
5427
5511
  const transformPrismaSchemaHistories = (requirementAnalysisReport, targetComponent, otherComponents) => [ {
@@ -5454,7 +5538,7 @@ async function orchestratePrismaSchemas(ctx, components) {
5454
5538
  return await Promise.all(components.map((async comp => {
5455
5539
  const targetComponent = comp;
5456
5540
  const otherComponents = components.filter((y => comp !== y));
5457
- const result = await forceRetry((() => process$2(ctx, targetComponent, otherComponents)));
5541
+ const result = await forceRetry((() => process$3(ctx, targetComponent, otherComponents)));
5458
5542
  const event = {
5459
5543
  type: "prismaSchemas",
5460
5544
  created_at: start.toISOString(),
@@ -5472,7 +5556,7 @@ async function orchestratePrismaSchemas(ctx, components) {
5472
5556
  })));
5473
5557
  }
5474
5558
 
5475
- async function process$2(ctx, targetComponent, otherComponents) {
5559
+ async function process$3(ctx, targetComponent, otherComponents) {
5476
5560
  const pointer = {
5477
5561
  value: null
5478
5562
  };
@@ -5486,7 +5570,7 @@ async function process$2(ctx, targetComponent, otherComponents) {
5486
5570
  }
5487
5571
  },
5488
5572
  histories: transformPrismaSchemaHistories(ctx.state().analyze.files, targetComponent, otherComponents),
5489
- controllers: [ createApplication$4(ctx, {
5573
+ controllers: [ createApplication$5(ctx, {
5490
5574
  targetComponent,
5491
5575
  otherComponents,
5492
5576
  build: next => {
@@ -5503,9 +5587,9 @@ async function process$2(ctx, targetComponent, otherComponents) {
5503
5587
  return pointer.value;
5504
5588
  }
5505
5589
 
5506
- function createApplication$4(ctx, props) {
5590
+ function createApplication$5(ctx, props) {
5507
5591
  assertSchemaModel(ctx.model);
5508
- const application = collection$5[ctx.model];
5592
+ const application = collection$6[ctx.model];
5509
5593
  return {
5510
5594
  protocol: "class",
5511
5595
  name: "Prisma Generator",
@@ -5518,7 +5602,7 @@ function createApplication$4(ctx, props) {
5518
5602
  };
5519
5603
  }
5520
5604
 
5521
- const claude$5 = {
5605
+ const claude$6 = {
5522
5606
  model: "claude",
5523
5607
  options: {
5524
5608
  reference: true,
@@ -6104,7 +6188,7 @@ const claude$5 = {
6104
6188
  } ]
6105
6189
  };
6106
6190
 
6107
- const collection$5 = {
6191
+ const collection$6 = {
6108
6192
  chatgpt: {
6109
6193
  model: "chatgpt",
6110
6194
  options: {
@@ -6670,10 +6754,10 @@ const collection$5 = {
6670
6754
  })()
6671
6755
  } ]
6672
6756
  },
6673
- claude: claude$5,
6674
- llama: claude$5,
6675
- deepseek: claude$5,
6676
- 3.1: claude$5
6757
+ claude: claude$6,
6758
+ llama: claude$6,
6759
+ deepseek: claude$6,
6760
+ 3.1: claude$6
6677
6761
  };
6678
6762
 
6679
6763
  const orchestratePrisma = ctx => async props => {
@@ -6723,48 +6807,547 @@ const orchestratePrisma = ctx => async props => {
6723
6807
  return history;
6724
6808
  };
6725
6809
 
6726
- const FAILED = Symbol("FAILED");
6810
+ const transformRealizeDecoratorHistories = (ctx, role) => [ {
6811
+ id: v4(),
6812
+ created_at: (new Date).toISOString(),
6813
+ type: "systemMessage",
6814
+ text: '# NestJS Authentication Provider & Decorator Generation AI Agent \n\nYou are a world-class NestJS expert and TypeScript developer. Your role is to automatically generate Provider functions and Decorators for JWT authentication based on given Role information and Prisma Schema. \n\n## Core Mission \n\nGenerate authentication Provider and Decorator code specialized for specific Roles based on Role information provided by users. \n\n## Input Information \n\n- **Role Name**: The authentication role to generate (e.g., admin, user, manager, etc.) \n- **Prisma Schema**: Database table information.\n\n## Code Generation Rules \n\n### 1. Provider Function Generation Rules \n\n- Function name: `{role}Authorize` format (e.g., adminAuthorize, userAuthorize) \n- Must use the `jwtAuthorize` function for JWT token verification \n- Verify payload type and check if `payload.type` matches the correct role \n- Query database using `MyGlobal.prisma.{tableName}` format to fetch **only the authorization model itself** - do not include relations or business logic models (no `include` statements for profile, etc.) \n- Verify that the user actually exists in the database \n- Function return type should be `{Role}Payload` interface \n- Return the `payload` variable whenever feasible in provider functions. \n- **Always check the Prisma schema for validation columns (e.g., `deleted_at`, status fields) within the authorization model and include them in the `where` clause to ensure the user is valid and active.** \n\n### 2. Payload Interface Generation Rules \n\n- Interface name: `{Role}Payload` format (e.g., AdminPayload, UserPayload) \n- Required fields: \n - `id: string & tags.Format<"uuid">`: User ID (UUID format) \n - `type: "{role}"`: Discriminator for role identification \n- Additional fields should be generated according to Role characteristics and "Prisma Schema" \n\n### 3. Decorator Generation Rules \n\n- Decorator name: `{Role}Auth` format (e.g., AdminAuth, UserAuth) \n- Use SwaggerCustomizer to add bearer token security schema to API documentation \n- Use createParamDecorator to implement actual authentication logic \n- Use Singleton pattern to manage decorator instances \n\n### 4. Code Style and Structure\n\n- Comply with TypeScript strict mode \n- Utilize NestJS Exception classes (ForbiddenException, UnauthorizedException) \n- Ensure type safety using typia tags \n- Add appropriate JSDoc comments \n\n## Reference Functions and Examples \n\n### JWT Authentication Function \n\n```typescript\n// path - src/authentications/jwtAuthorize.ts\nimport { ForbiddenException, UnauthorizedException } from "@nestjs/common";\nimport jwt from "jsonwebtoken";\n\nimport { MyGlobal } from "../MyGlobal";\n\nexport function jwtAuthorize(props: {\n request: {\n headers: { authorization?: string };\n };\n}) {\n if (!props.request.headers.authorization)\n throw new ForbiddenException("No token value exists");\n else if (\n props.request.headers.authorization.startsWith(BEARER_PREFIX) === false\n )\n throw new UnauthorizedException("Invalid token");\n\n // PARSE TOKEN\n try {\n const token: string = props.request.headers.authorization.substring(\n BEARER_PREFIX.length,\n );\n\n const verified = jwt.verify(token, MyGlobal.env.JWT_SECRET_KEY);\n\n return verified;\n } catch {\n throw new UnauthorizedException("Invalid token");\n }\n}\n\nconst BEARER_PREFIX = "Bearer ";\n``` \n\n### Provider Function Example \n\n```typescript\nimport { ForbiddenException } from "@nestjs/common";\n\nimport { MyGlobal } from "../MyGlobal";\nimport { jwtAuthorize } from "./jwtAuthorize";\nimport { AdminPayload } from "./types/AdminPayload";\n\nexport async function adminAuthorize(request: {\n headers: {\n authorization?: string;\n };\n}): Promise<AdminPayload> {\n const payload: AdminPayload = jwtAuthorize({ request }) as AdminPayload;\n\n if (payload.type !== "admin") {\n throw new ForbiddenException(`You\'re not ${payload.type}`);\n }\n\n const admin = await MyGlobal.prisma.admins.findFirst({\n where: {\n id: payload.id,\n user: {\n deleted_at: null,\n is_banned: false,\n },\n },\n });\n\n if (admin === null) {\n throw new ForbiddenException("You\'re not enrolled");\n }\n\n return payload;\n}\n``` \n\n### Decorator Example\n\n```typescript\nimport { SwaggerCustomizer } from "@nestia/core";\nimport { ExecutionContext, createParamDecorator } from "@nestjs/common";\nimport { Singleton } from "tstl";\n\nimport { adminAuthorize } from "../authentications/adminAuthorize";\n\nexport const AdminAuth =\n (): ParameterDecorator =>\n (\n target: object,\n propertyKey: string | symbol | undefined,\n parameterIndex: number,\n ): void => {\n SwaggerCustomizer((props) => {\n props.route.security ??= [];\n props.route.security.push({\n bearer: [],\n });\n })(target, propertyKey as string, undefined!);\n singleton.get()(target, propertyKey, parameterIndex);\n };\n\nconst singleton = new Singleton(() =>\n createParamDecorator(async (_0: unknown, ctx: ExecutionContext) => {\n const request = ctx.switchToHttp().getRequest();\n return adminAuthorize(request);\n })(),\n);\n``` \n\n### Decorator Type Example \n\nIn case of the columns related to Date type like `created_at`, `updated_at`, `deleted_at`, must use the `string & tags.Format<\'date-time\'>` Type instead of Date type. \n\n```typescript\nimport { tags } from "typia";\n\nexport interface AdminPayload {\n /**\n * Admin ID.\n */\n id: string & tags.Format<"uuid">;\n\n /**\n * Discriminator for the discriminated union type.\n */\n type: "admin";\n}\n``` \n\n## Output Format \n\nYou must provide your response in a structured JSON format containing the following nested structure: \n\n**provider**: An object containing the authentication Provider function configuration \n\n- **name**: The name of the authentication Provider function in `{role}Authorize` format (e.g., adminAuthorize, userAuthorize). This function verifies JWT tokens and returns user information for the specified role. \n- **code**: Complete TypeScript code for the authentication Provider function only. Must include JWT verification, role checking, database query logic, and proper import statements for the Payload interface.\n\n**decorator**: An object containing the authentication Decorator configuration \n\n- **name**: The name of the Decorator to be generated in `{Role}Auth` format (e.g., AdminAuth, UserAuth). The decorator name used in Controller method parameters. \n- **code**: Complete TypeScript code for the Decorator. Must include complete authentication decorator implementation using SwaggerCustomizer, createParamDecorator, and Singleton pattern.\n\n**decoratorType**: An object containing the Decorator Type configuration\n\n- **name**: The name of the Decorator Type in `{Role}Payload` format (e.g., AdminPayload, UserPayload). Used as the TypeScript type for the authenticated user data.\n- **code**: Complete TypeScript code for the Payload type interface. Must include proper field definitions with typia tags for type safety.\n\n## Work Process \n\n1. Analyze the input Role name \n2. Generate Provider function for the Role \n3. Define Payload interface \n4. Implement Decorator \n5. Verify that all code follows example patterns \n6. Generate response in specified format \n\n## Quality Standards \n\n- Ensure type safety \n- Follow NestJS conventions \n- Complete error handling \n- Code reusability \n- Complete documentation \n\nWhen users provide Role information, generate complete and practical authentication code according to the above rules.'
6815
+ }, {
6816
+ id: v4(),
6817
+ created_at: (new Date).toISOString(),
6818
+ type: "systemMessage",
6819
+ text: [ "## Role", "", role, "", "## Prisma Schema", "", JSON.stringify(ctx.state().prisma?.schemas, null, 2), "" ].join("\n")
6820
+ } ];
6727
6821
 
6728
- function pipe(a, ...fns) {
6729
- return fns.reduce(((prev, fn) => prev.then((result => {
6730
- if (result === FAILED) return FAILED;
6731
- return fn(result);
6732
- }))), Promise.resolve(a));
6733
- }
6822
+ const transformRealizeDecoratorCorrectHistories = (ctx, result, templateFiles, diagnostics) => [ {
6823
+ id: v4(),
6824
+ created_at: (new Date).toISOString(),
6825
+ type: "systemMessage",
6826
+ text: '# TypeScript Compiler Feedback Correction System \n\nYou are an expert TypeScript developer specializing in fixing compilation errors in NestJS authentication systems. Your task is to analyze TypeScript compilation diagnostics and correct the generated code to ensure it compiles successfully. \n\n## Your Role \n\nYou will receive: \n\n1. **Generated TypeScript Code** - Authentication provider and decorator implementations \n2. **Prisma Schema** - Available database table \n3. **File Paths** - Project structure for import resolution \n4. **Compile Errors** - TypeScript diagnostic information \n\nYour goal is to fix all compilation errors while maintaining the original functionality and structure. \n\n## Analysis Process \n\nFollow this systematic approach to fix compilation errors: \n\n### Step 1: Error Analysis \n\n- Examine each diagnostic error carefully \n- Identify the error type (import issues, type mismatches, missing properties, etc.) \n- Note the file location and specific line/character positions \n- Categorize errors by severity and interdependency \n\n### Step 2: Context Understanding\n\n- Review the available Prisma client mappings to understand database schema \n- Check file paths to ensure correct import statements \n- Validate that all referenced types and interfaces exist \n- Understand the relationship between provider and decorator implementations \n\n### Step 3: Root Cause Identification\n\n- Determine if errors are due to: \n - Incorrect Prisma table names (use Prisma Schema mapping) \n - Wrong import paths (use provided file paths) \n - Missing type definitions \n - Incorrect function signatures \n - Incompatible TypeScript syntax \n\n### Step 4: Systematic Correction \n\n- Fix errors in dependency order (types before implementations) \n- Ensure consistency between provider and decorator implementations \n- Maintain original naming conventions and patterns \n- Preserve all required functionality \n\n## Common Error Types and Solutions \n\n### Database Table Access Errors\n\n- **Problem**: `Property \'tableName\' does not exist on type \'PrismaClients\'` \n- **Solution**: Check `Prisma Schema` mapping for correct table names \n- **Example**: If error shows `admins` but model of prisma Schema shows `admin`, use `admin` \n\n### Import Path Errors \n\n- **Problem**: Module resolution failures \n- **Solution**: Use provided file paths to construct correct relative imports \n- **Example**: Adjust `./` vs `../` based on actual file structure \n\n### Type Definition Errors \n\n- **Problem**: Missing or incorrect type references \n- **Solution**: Ensure all interfaces and types are properly defined and exported \n- **Example**: Add missing `export` keywords or correct type names \n\n### Function Signature Mismatches\n\n- **Problem**: Parameter types don\'t match expected signatures \n- **Solution**: Align function parameters with NestJS and custom type requirements \n- **Example**: Ensure JWT payload types match expected structure \n\n## Code Correction Guidelines \n\n### 1. Preserve Original Structure \n\n- Keep the same function names and export patterns \n- Maintain the provider-decorator relationship \n- Preserve all required imports and dependencies \n\n### 2. Database Integration \n\n- Use exact table names from `Prisma Schema` mapping \n- Ensure proper async/await patterns for database queries \n- Maintain proper error handling for database operations \n\n### 3. Type Safety\n\n- Ensure all types are properly imported and defined \n- Use typia tags correctly for validation \n- Maintain strict TypeScript compliance \n\n### 4. NestJS Integration \n\n- Preserve decorator patterns and parameter injection \n- Maintain proper exception handling (ForbiddenException, UnauthorizedException) \n- Ensure Swagger integration remains intact \n\n## Output Format \n\nProvide your corrected code in the following JSON format: \n\n```json\n{\n "provider": {\n "name": "corrected_provider_name",\n "code": "corrected_provider_code"\n },\n "decorator": {\n "name": "corrected_decorator_name", \n "code": "corrected_decorator_code"\n }\n "decoratorType": {\n "name": "corrected_payload_type_name",\n "code": "corrected_payload_type_code"\n }\n}\n``` \n\n## Validation Checklist \n\nBefore submitting your corrections, verify: \n\n- [ ] All compilation errors are addressed \n- [ ] Database table names match Prisma Schema mapping \n- [ ] Import paths are correct based on file structure \n- [ ] All types are properly defined and exported \n- [ ] Function signatures match expected patterns \n- [ ] Error handling is preserved \n- [ ] Original functionality is maintained \n- [ ] Code follows TypeScript best practices \n\n## Response Process \n\n1. **First**, analyze all errors and identify patterns \n2. **Then**, explain your understanding of the issues \n3. **Next**, describe your correction strategy \n4. **Finally**, provide the corrected code in the specified JSON format \n\nRemember: Focus on fixing compilation errors while preserving the original authentication logic and NestJS integration patterns.'
6827
+ }, {
6828
+ id: v4(),
6829
+ created_at: (new Date).toISOString(),
6830
+ type: "assistantMessage",
6831
+ text: [ "## Generated TypeScript Code", "", "```json", `${JSON.stringify(result, null, 2)}`, "```", "", "## Prisma Schema", "", "```json", `${JSON.stringify(ctx.state().prisma?.schemas, null, 2)}`, "```", "", "## File Paths", "", Object.keys(templateFiles).map((path => `- ${path}`)).join("\n"), "", "## Compile Errors", "", "Fix the compilation error in the provided code.", "", "```json", JSON.stringify(diagnostics, null, 2), "```" ].join("\n")
6832
+ } ];
6734
6833
 
6735
- async function getTestScenarioArtifacts(ctx, scenario) {
6736
- const compiler = await ctx.compiler();
6737
- const document = filterDocument(scenario, ctx.state().interface.document);
6738
- const entries = Object.entries(await compiler.interface.write(document));
6739
- const filter = (prefix, exclude) => {
6740
- const result = entries.filter((([key]) => key.startsWith(prefix) === true));
6741
- return Object.fromEntries(exclude ? result.filter((([key]) => key.startsWith(exclude) === false)) : result);
6834
+ async function orchestrateRealizeDecorator(ctx) {
6835
+ const roles = ctx.state().interface?.document.components.authorization?.map((auth => auth.name)) ?? [];
6836
+ const decorators = [];
6837
+ let completed = 0;
6838
+ const templateFiles = {
6839
+ "src/MyGlobal.ts": await fs.readFile(path.join(__dirname, "../../../../../internals/template/realize/src/MyGlobal.ts"), "utf-8"),
6840
+ "src/authentications/jwtAuthorize.ts": await fs.readFile(path.join(__dirname, "../../../../../internals/template/realize/src/providers/jwtAuthorize.ts"), "utf-8")
6742
6841
  };
6743
- return {
6744
- document,
6745
- sdk: filter("src/api", "src/api/structures"),
6746
- dto: filter("src/api/structures"),
6747
- e2e: filter("test/features")
6842
+ const files = {
6843
+ ...templateFiles
6748
6844
  };
6845
+ await Promise.all(roles.map((async role => {
6846
+ const decorator = await process$2(ctx, role, templateFiles);
6847
+ files[`src/decorators/${decorator.decorator.name}.ts`] = decorator.decorator.code;
6848
+ files[`src/authentications/${decorator.provider.name}.ts`] = decorator.provider.code;
6849
+ files[`src/authentications/types/${decorator.decoratorType.name}.ts`] = decorator.decoratorType.code;
6850
+ decorators.push(decorator);
6851
+ const events = {
6852
+ type: "realizeDecorator",
6853
+ created_at: (new Date).toISOString(),
6854
+ files,
6855
+ completed: ++completed,
6856
+ total: roles.length,
6857
+ step: ctx.state().test?.step ?? 0
6858
+ };
6859
+ ctx.dispatch(events);
6860
+ })));
6861
+ return decorators;
6749
6862
  }
6750
6863
 
6751
- function filterDocument(scenario, document) {
6752
- const operations = document.operations.filter((op => scenario.endpoint.method === op.method && scenario.endpoint.path === op.path || scenario.dependencies.some((dp => dp.endpoint.method === op.method && dp.endpoint.path === op.path))));
6753
- const components = {
6754
- schemas: {}
6864
+ async function process$2(ctx, role, templateFiles) {
6865
+ const pointer = {
6866
+ value: null
6755
6867
  };
6756
- const visit = typeName => {
6757
- OpenApiTypeChecker.visit({
6758
- components: document.components,
6759
- schema: {
6760
- $ref: `#/components/schemas/${typeName}`
6761
- },
6762
- closure: s => {
6763
- if (OpenApiTypeChecker.isReference(s)) {
6764
- const key = s.$ref.split("/").pop();
6765
- components.schemas[key] = document.components.schemas[key];
6766
- }
6767
- }
6868
+ const agentica = new MicroAgentica({
6869
+ model: ctx.model,
6870
+ vendor: ctx.vendor,
6871
+ config: {
6872
+ ...ctx.config ?? {},
6873
+ executor: {
6874
+ describe: null
6875
+ }
6876
+ },
6877
+ histories: transformRealizeDecoratorHistories(ctx, role),
6878
+ controllers: [ createApplication$4({
6879
+ model: ctx.model,
6880
+ build: next => {
6881
+ pointer.value = next;
6882
+ }
6883
+ }) ]
6884
+ });
6885
+ enforceToolCall(agentica);
6886
+ await agentica.conversate("Create Authorization Provider and Decorator.").finally((() => {
6887
+ const tokenUsage = agentica.getTokenUsage();
6888
+ ctx.usage().record(tokenUsage, [ "realize" ]);
6889
+ }));
6890
+ if (pointer.value === null) throw new Error("Failed to create decorator.");
6891
+ const compiled = ctx.state().prisma?.compiled;
6892
+ const prismaClients = compiled?.type === "success" ? compiled.nodeModules : {};
6893
+ return await correctDecorator(ctx, pointer.value, prismaClients, templateFiles);
6894
+ }
6895
+
6896
+ async function correctDecorator(ctx, result, prismaClients, templateFiles, life = 4) {
6897
+ const files = {
6898
+ ...templateFiles,
6899
+ ...prismaClients,
6900
+ [`src/decorators/${result.decorator.name}.ts`]: result.decorator.code,
6901
+ [`src/authentications/${result.provider.name}.ts`]: result.provider.code,
6902
+ [`src/authentications/types/${result.decoratorType.name}.ts`]: result.decoratorType.code
6903
+ };
6904
+ const compiler = await ctx.compiler();
6905
+ const compiled = await compiler.typescript.compile({
6906
+ files
6907
+ });
6908
+ ctx.dispatch({
6909
+ type: "realizeDecoratorValidate",
6910
+ created_at: (new Date).toISOString(),
6911
+ result: compiled,
6912
+ files,
6913
+ step: ctx.state().test?.step ?? 0
6914
+ });
6915
+ if (compiled.type === "success") {
6916
+ return result;
6917
+ } else if (compiled.type === "exception" || life === 0) {
6918
+ return result;
6919
+ }
6920
+ const pointer = {
6921
+ value: null
6922
+ };
6923
+ const agentica = new MicroAgentica({
6924
+ model: ctx.model,
6925
+ vendor: ctx.vendor,
6926
+ config: {
6927
+ ...ctx.config ?? {},
6928
+ executor: {
6929
+ describe: null
6930
+ }
6931
+ },
6932
+ histories: transformRealizeDecoratorCorrectHistories(ctx, result, templateFiles, compiled.diagnostics),
6933
+ controllers: [ createApplication$4({
6934
+ model: ctx.model,
6935
+ build: next => {
6936
+ pointer.value = next;
6937
+ }
6938
+ }) ]
6939
+ });
6940
+ enforceToolCall(agentica);
6941
+ await agentica.conversate("Please correct the decorator and the provider.").finally((() => {
6942
+ const tokenUsage = agentica.getTokenUsage();
6943
+ ctx.usage().record(tokenUsage, [ "realize" ]);
6944
+ }));
6945
+ if (pointer.value === null) throw new Error("Failed to correct decorator.");
6946
+ const correctedFiles = {
6947
+ ...files,
6948
+ [`src/decorators/${pointer.value.decorator.name}.ts`]: pointer.value.decorator.code,
6949
+ [`src/authentications/${pointer.value.provider.name}.ts`]: pointer.value.provider.code,
6950
+ [`src/authentications/types/${pointer.value.decoratorType.name}.ts`]: pointer.value.decoratorType.code
6951
+ };
6952
+ ctx.dispatch({
6953
+ type: "realizeDecoratorCorrect",
6954
+ created_at: (new Date).toISOString(),
6955
+ files: correctedFiles,
6956
+ result: compiled,
6957
+ step: ctx.state().test?.step ?? 0
6958
+ });
6959
+ return await correctDecorator(ctx, pointer.value, prismaClients, templateFiles, life - 1);
6960
+ }
6961
+
6962
+ function createApplication$4(props) {
6963
+ assertSchemaModel(props.model);
6964
+ const application = collection$5[props.model];
6965
+ return {
6966
+ protocol: "class",
6967
+ name: "Create Decorator",
6968
+ application,
6969
+ execute: {
6970
+ createDecorator: next => {
6971
+ props.build(next);
6972
+ }
6973
+ }
6974
+ };
6975
+ }
6976
+
6977
+ const claude$5 = {
6978
+ model: "claude",
6979
+ options: {
6980
+ reference: true,
6981
+ separate: null
6982
+ },
6983
+ functions: [ {
6984
+ name: "createDecorator",
6985
+ parameters: {
6986
+ description: "Current Type: {@link IAutoBeRealizeDecoratorApplication.IProps}",
6987
+ type: "object",
6988
+ properties: {
6989
+ provider: {
6990
+ description: "Authentication Provider function configuration containing the function\nname and implementation code. The Provider handles JWT token\nverification, role validation, and database queries to authenticate\nusers.",
6991
+ $ref: "#/$defs/IAutoBeRealizeDecoratorApplication.IProvider"
6992
+ },
6993
+ decorator: {
6994
+ description: "Authentication Decorator configuration containing the decorator name and\nimplementation code. The Decorator integrates with NestJS parameter\ndecorators to automatically inject authenticated user data into\nController methods.",
6995
+ $ref: "#/$defs/IAutoBeRealizeDecoratorApplication.IDecorator"
6996
+ },
6997
+ decoratorType: {
6998
+ description: "Authentication Decorator Type configuration containing the decorator type\nname and implementation code. The Decorator Type is used to define the\nstructure of the authenticated user data that will be injected into\nController methods when using the decorator. It serves as the TypeScript\ntype for the parameter in Controller method signatures.",
6999
+ $ref: "#/$defs/IAutoBeRealizeDecoratorApplication.IDecoratorType"
7000
+ }
7001
+ },
7002
+ required: [ "provider", "decorator", "decoratorType" ],
7003
+ additionalProperties: false,
7004
+ $defs: {
7005
+ "IAutoBeRealizeDecoratorApplication.IProvider": {
7006
+ type: "object",
7007
+ properties: {
7008
+ name: {
7009
+ description: "The name of the authentication Provider function in {role}Authorize\nformat (e.g., adminAuthorize, userAuthorize). This function will be\ncalled by the decorator to verify JWT tokens and return authenticated\nuser information for the specified role.",
7010
+ type: "string"
7011
+ },
7012
+ code: {
7013
+ description: "Complete TypeScript code for the authentication Provider function and its\ncorresponding Payload interface. Must include: JWT token verification\nusing jwtAuthorize function, role type checking against payload.type,\ndatabase query using MyGlobal.prisma.{tableName} pattern to verify user\nexistence, proper error handling with ForbiddenException and\nUnauthorizedException, and the Payload interface definition with id (UUID\nformat) and type (role discriminator) fields using typia tags.",
7014
+ type: "string"
7015
+ }
7016
+ },
7017
+ required: [ "name", "code" ]
7018
+ },
7019
+ "IAutoBeRealizeDecoratorApplication.IDecorator": {
7020
+ type: "object",
7021
+ properties: {
7022
+ name: {
7023
+ description: "The name of the Decorator to be generated in {Role}Auth format (e.g.,\nAdminAuth, UserAuth). This decorator will be used as a parameter\ndecorator in Controller methods to automatically authenticate and\nauthorize users for the specific role, injecting the authenticated user\npayload as a method parameter.",
7024
+ type: "string"
7025
+ },
7026
+ code: {
7027
+ description: "Complete TypeScript code for the authentication Decorator implementation.\nMust include: SwaggerCustomizer integration to add bearer token security\nschema to API documentation, createParamDecorator implementation that\ncalls the corresponding Provider function for authentication, Singleton\npattern using tstl library for efficient decorator instance management,\nand proper TypeScript typing for the ParameterDecorator interface.",
7028
+ type: "string"
7029
+ }
7030
+ },
7031
+ required: [ "name", "code" ]
7032
+ },
7033
+ "IAutoBeRealizeDecoratorApplication.IDecoratorType": {
7034
+ type: "object",
7035
+ properties: {
7036
+ name: {
7037
+ description: "The name of the Decorator to be generated in {Role}Auth format (e.g.,\nAdminAuth, UserAuth). This decorator will be used as a parameter\ndecorator in Controller methods to automatically authenticate and\nauthorize users for the specific role, injecting the authenticated user\npayload as a method parameter.",
7038
+ type: "string"
7039
+ },
7040
+ code: {
7041
+ description: "The TypeScript code for the Payload type in {Role}Payload format (e.g.,\nAdminPayload, UserPayload). This interface defines the structure of the\nauthenticated user data that will be injected into Controller methods\nwhen using the decorator. It serves as the TypeScript type for the\nparameter in Controller method signatures.",
7042
+ type: "string"
7043
+ }
7044
+ },
7045
+ required: [ "name", "code" ]
7046
+ }
7047
+ }
7048
+ },
7049
+ validate: (() => {
7050
+ const _io0 = input => "object" === typeof input.provider && null !== input.provider && _io1(input.provider) && ("object" === typeof input.decorator && null !== input.decorator && _io2(input.decorator)) && ("object" === typeof input.decoratorType && null !== input.decoratorType && _io3(input.decoratorType));
7051
+ const _io1 = input => "string" === typeof input.name && "string" === typeof input.code;
7052
+ const _io2 = input => "string" === typeof input.name && "string" === typeof input.code;
7053
+ const _io3 = input => "string" === typeof input.name && "string" === typeof input.code;
7054
+ const _vo0 = (input, _path, _exceptionable = true) => [ ("object" === typeof input.provider && null !== input.provider || _report(_exceptionable, {
7055
+ path: _path + ".provider",
7056
+ expected: "IAutoBeRealizeDecoratorApplication.IProvider",
7057
+ value: input.provider
7058
+ })) && _vo1(input.provider, _path + ".provider", _exceptionable) || _report(_exceptionable, {
7059
+ path: _path + ".provider",
7060
+ expected: "IAutoBeRealizeDecoratorApplication.IProvider",
7061
+ value: input.provider
7062
+ }), ("object" === typeof input.decorator && null !== input.decorator || _report(_exceptionable, {
7063
+ path: _path + ".decorator",
7064
+ expected: "IAutoBeRealizeDecoratorApplication.IDecorator",
7065
+ value: input.decorator
7066
+ })) && _vo2(input.decorator, _path + ".decorator", _exceptionable) || _report(_exceptionable, {
7067
+ path: _path + ".decorator",
7068
+ expected: "IAutoBeRealizeDecoratorApplication.IDecorator",
7069
+ value: input.decorator
7070
+ }), ("object" === typeof input.decoratorType && null !== input.decoratorType || _report(_exceptionable, {
7071
+ path: _path + ".decoratorType",
7072
+ expected: "IAutoBeRealizeDecoratorApplication.IDecoratorType",
7073
+ value: input.decoratorType
7074
+ })) && _vo3(input.decoratorType, _path + ".decoratorType", _exceptionable) || _report(_exceptionable, {
7075
+ path: _path + ".decoratorType",
7076
+ expected: "IAutoBeRealizeDecoratorApplication.IDecoratorType",
7077
+ value: input.decoratorType
7078
+ }) ].every((flag => flag));
7079
+ const _vo1 = (input, _path, _exceptionable = true) => [ "string" === typeof input.name || _report(_exceptionable, {
7080
+ path: _path + ".name",
7081
+ expected: "string",
7082
+ value: input.name
7083
+ }), "string" === typeof input.code || _report(_exceptionable, {
7084
+ path: _path + ".code",
7085
+ expected: "string",
7086
+ value: input.code
7087
+ }) ].every((flag => flag));
7088
+ const _vo2 = (input, _path, _exceptionable = true) => [ "string" === typeof input.name || _report(_exceptionable, {
7089
+ path: _path + ".name",
7090
+ expected: "string",
7091
+ value: input.name
7092
+ }), "string" === typeof input.code || _report(_exceptionable, {
7093
+ path: _path + ".code",
7094
+ expected: "string",
7095
+ value: input.code
7096
+ }) ].every((flag => flag));
7097
+ const _vo3 = (input, _path, _exceptionable = true) => [ "string" === typeof input.name || _report(_exceptionable, {
7098
+ path: _path + ".name",
7099
+ expected: "string",
7100
+ value: input.name
7101
+ }), "string" === typeof input.code || _report(_exceptionable, {
7102
+ path: _path + ".code",
7103
+ expected: "string",
7104
+ value: input.code
7105
+ }) ].every((flag => flag));
7106
+ const __is = input => "object" === typeof input && null !== input && _io0(input);
7107
+ let errors;
7108
+ let _report;
7109
+ return input => {
7110
+ if (false === __is(input)) {
7111
+ errors = [];
7112
+ _report = __typia_transform__validateReport._validateReport(errors);
7113
+ ((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
7114
+ path: _path + "",
7115
+ expected: "IAutoBeRealizeDecoratorApplication.IProps",
7116
+ value: input
7117
+ })) && _vo0(input, _path + "", true) || _report(true, {
7118
+ path: _path + "",
7119
+ expected: "IAutoBeRealizeDecoratorApplication.IProps",
7120
+ value: input
7121
+ }))(input, "$input", true);
7122
+ const success = 0 === errors.length;
7123
+ return success ? {
7124
+ success,
7125
+ data: input
7126
+ } : {
7127
+ success,
7128
+ errors,
7129
+ data: input
7130
+ };
7131
+ }
7132
+ return {
7133
+ success: true,
7134
+ data: input
7135
+ };
7136
+ };
7137
+ })()
7138
+ } ]
7139
+ };
7140
+
7141
+ const collection$5 = {
7142
+ chatgpt: {
7143
+ model: "chatgpt",
7144
+ options: {
7145
+ reference: true,
7146
+ strict: false,
7147
+ separate: null
7148
+ },
7149
+ functions: [ {
7150
+ name: "createDecorator",
7151
+ parameters: {
7152
+ description: "Current Type: {@link IAutoBeRealizeDecoratorApplication.IProps}\n\n### Description of {@link provider} property:\n\n> Authentication Provider function configuration containing the function\n> name and implementation code. The Provider handles JWT token\n> verification, role validation, and database queries to authenticate\n> users.\n\n### Description of {@link decorator} property:\n\n> Authentication Decorator configuration containing the decorator name and\n> implementation code. The Decorator integrates with NestJS parameter\n> decorators to automatically inject authenticated user data into\n> Controller methods.\n\n### Description of {@link decoratorType} property:\n\n> Authentication Decorator Type configuration containing the decorator type\n> name and implementation code. The Decorator Type is used to define the\n> structure of the authenticated user data that will be injected into\n> Controller methods when using the decorator. It serves as the TypeScript\n> type for the parameter in Controller method signatures.",
7153
+ type: "object",
7154
+ properties: {
7155
+ provider: {
7156
+ $ref: "#/$defs/IAutoBeRealizeDecoratorApplication.IProvider"
7157
+ },
7158
+ decorator: {
7159
+ $ref: "#/$defs/IAutoBeRealizeDecoratorApplication.IDecorator"
7160
+ },
7161
+ decoratorType: {
7162
+ $ref: "#/$defs/IAutoBeRealizeDecoratorApplication.IDecoratorType"
7163
+ }
7164
+ },
7165
+ required: [ "provider", "decorator", "decoratorType" ],
7166
+ additionalProperties: false,
7167
+ $defs: {
7168
+ "IAutoBeRealizeDecoratorApplication.IProvider": {
7169
+ type: "object",
7170
+ properties: {
7171
+ name: {
7172
+ description: "The name of the authentication Provider function in {role}Authorize\nformat (e.g., adminAuthorize, userAuthorize). This function will be\ncalled by the decorator to verify JWT tokens and return authenticated\nuser information for the specified role.",
7173
+ type: "string"
7174
+ },
7175
+ code: {
7176
+ description: "Complete TypeScript code for the authentication Provider function and its\ncorresponding Payload interface. Must include: JWT token verification\nusing jwtAuthorize function, role type checking against payload.type,\ndatabase query using MyGlobal.prisma.{tableName} pattern to verify user\nexistence, proper error handling with ForbiddenException and\nUnauthorizedException, and the Payload interface definition with id (UUID\nformat) and type (role discriminator) fields using typia tags.",
7177
+ type: "string"
7178
+ }
7179
+ },
7180
+ required: [ "name", "code" ]
7181
+ },
7182
+ "IAutoBeRealizeDecoratorApplication.IDecorator": {
7183
+ type: "object",
7184
+ properties: {
7185
+ name: {
7186
+ description: "The name of the Decorator to be generated in {Role}Auth format (e.g.,\nAdminAuth, UserAuth). This decorator will be used as a parameter\ndecorator in Controller methods to automatically authenticate and\nauthorize users for the specific role, injecting the authenticated user\npayload as a method parameter.",
7187
+ type: "string"
7188
+ },
7189
+ code: {
7190
+ description: "Complete TypeScript code for the authentication Decorator implementation.\nMust include: SwaggerCustomizer integration to add bearer token security\nschema to API documentation, createParamDecorator implementation that\ncalls the corresponding Provider function for authentication, Singleton\npattern using tstl library for efficient decorator instance management,\nand proper TypeScript typing for the ParameterDecorator interface.",
7191
+ type: "string"
7192
+ }
7193
+ },
7194
+ required: [ "name", "code" ]
7195
+ },
7196
+ "IAutoBeRealizeDecoratorApplication.IDecoratorType": {
7197
+ type: "object",
7198
+ properties: {
7199
+ name: {
7200
+ description: "The name of the Decorator to be generated in {Role}Auth format (e.g.,\nAdminAuth, UserAuth). This decorator will be used as a parameter\ndecorator in Controller methods to automatically authenticate and\nauthorize users for the specific role, injecting the authenticated user\npayload as a method parameter.",
7201
+ type: "string"
7202
+ },
7203
+ code: {
7204
+ description: "The TypeScript code for the Payload type in {Role}Payload format (e.g.,\nAdminPayload, UserPayload). This interface defines the structure of the\nauthenticated user data that will be injected into Controller methods\nwhen using the decorator. It serves as the TypeScript type for the\nparameter in Controller method signatures.",
7205
+ type: "string"
7206
+ }
7207
+ },
7208
+ required: [ "name", "code" ]
7209
+ }
7210
+ }
7211
+ },
7212
+ validate: (() => {
7213
+ const _io0 = input => "object" === typeof input.provider && null !== input.provider && _io1(input.provider) && ("object" === typeof input.decorator && null !== input.decorator && _io2(input.decorator)) && ("object" === typeof input.decoratorType && null !== input.decoratorType && _io3(input.decoratorType));
7214
+ const _io1 = input => "string" === typeof input.name && "string" === typeof input.code;
7215
+ const _io2 = input => "string" === typeof input.name && "string" === typeof input.code;
7216
+ const _io3 = input => "string" === typeof input.name && "string" === typeof input.code;
7217
+ const _vo0 = (input, _path, _exceptionable = true) => [ ("object" === typeof input.provider && null !== input.provider || _report(_exceptionable, {
7218
+ path: _path + ".provider",
7219
+ expected: "IAutoBeRealizeDecoratorApplication.IProvider",
7220
+ value: input.provider
7221
+ })) && _vo1(input.provider, _path + ".provider", _exceptionable) || _report(_exceptionable, {
7222
+ path: _path + ".provider",
7223
+ expected: "IAutoBeRealizeDecoratorApplication.IProvider",
7224
+ value: input.provider
7225
+ }), ("object" === typeof input.decorator && null !== input.decorator || _report(_exceptionable, {
7226
+ path: _path + ".decorator",
7227
+ expected: "IAutoBeRealizeDecoratorApplication.IDecorator",
7228
+ value: input.decorator
7229
+ })) && _vo2(input.decorator, _path + ".decorator", _exceptionable) || _report(_exceptionable, {
7230
+ path: _path + ".decorator",
7231
+ expected: "IAutoBeRealizeDecoratorApplication.IDecorator",
7232
+ value: input.decorator
7233
+ }), ("object" === typeof input.decoratorType && null !== input.decoratorType || _report(_exceptionable, {
7234
+ path: _path + ".decoratorType",
7235
+ expected: "IAutoBeRealizeDecoratorApplication.IDecoratorType",
7236
+ value: input.decoratorType
7237
+ })) && _vo3(input.decoratorType, _path + ".decoratorType", _exceptionable) || _report(_exceptionable, {
7238
+ path: _path + ".decoratorType",
7239
+ expected: "IAutoBeRealizeDecoratorApplication.IDecoratorType",
7240
+ value: input.decoratorType
7241
+ }) ].every((flag => flag));
7242
+ const _vo1 = (input, _path, _exceptionable = true) => [ "string" === typeof input.name || _report(_exceptionable, {
7243
+ path: _path + ".name",
7244
+ expected: "string",
7245
+ value: input.name
7246
+ }), "string" === typeof input.code || _report(_exceptionable, {
7247
+ path: _path + ".code",
7248
+ expected: "string",
7249
+ value: input.code
7250
+ }) ].every((flag => flag));
7251
+ const _vo2 = (input, _path, _exceptionable = true) => [ "string" === typeof input.name || _report(_exceptionable, {
7252
+ path: _path + ".name",
7253
+ expected: "string",
7254
+ value: input.name
7255
+ }), "string" === typeof input.code || _report(_exceptionable, {
7256
+ path: _path + ".code",
7257
+ expected: "string",
7258
+ value: input.code
7259
+ }) ].every((flag => flag));
7260
+ const _vo3 = (input, _path, _exceptionable = true) => [ "string" === typeof input.name || _report(_exceptionable, {
7261
+ path: _path + ".name",
7262
+ expected: "string",
7263
+ value: input.name
7264
+ }), "string" === typeof input.code || _report(_exceptionable, {
7265
+ path: _path + ".code",
7266
+ expected: "string",
7267
+ value: input.code
7268
+ }) ].every((flag => flag));
7269
+ const __is = input => "object" === typeof input && null !== input && _io0(input);
7270
+ let errors;
7271
+ let _report;
7272
+ return input => {
7273
+ if (false === __is(input)) {
7274
+ errors = [];
7275
+ _report = __typia_transform__validateReport._validateReport(errors);
7276
+ ((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
7277
+ path: _path + "",
7278
+ expected: "IAutoBeRealizeDecoratorApplication.IProps",
7279
+ value: input
7280
+ })) && _vo0(input, _path + "", true) || _report(true, {
7281
+ path: _path + "",
7282
+ expected: "IAutoBeRealizeDecoratorApplication.IProps",
7283
+ value: input
7284
+ }))(input, "$input", true);
7285
+ const success = 0 === errors.length;
7286
+ return success ? {
7287
+ success,
7288
+ data: input
7289
+ } : {
7290
+ success,
7291
+ errors,
7292
+ data: input
7293
+ };
7294
+ }
7295
+ return {
7296
+ success: true,
7297
+ data: input
7298
+ };
7299
+ };
7300
+ })()
7301
+ } ]
7302
+ },
7303
+ claude: claude$5,
7304
+ llama: claude$5,
7305
+ deepseek: claude$5,
7306
+ 3.1: claude$5
7307
+ };
7308
+
7309
+ const FAILED = Symbol("FAILED");
7310
+
7311
+ function pipe(a, ...fns) {
7312
+ return fns.reduce(((prev, fn) => prev.then((result => {
7313
+ if (result === FAILED) return FAILED;
7314
+ return fn(result);
7315
+ }))), Promise.resolve(a));
7316
+ }
7317
+
7318
+ async function getTestScenarioArtifacts(ctx, scenario) {
7319
+ const compiler = await ctx.compiler();
7320
+ const document = filterDocument(scenario, ctx.state().interface.document);
7321
+ const entries = Object.entries(await compiler.interface.write(document));
7322
+ const filter = (prefix, exclude) => {
7323
+ const result = entries.filter((([key]) => key.startsWith(prefix) === true));
7324
+ return Object.fromEntries(exclude ? result.filter((([key]) => key.startsWith(exclude) === false)) : result);
7325
+ };
7326
+ return {
7327
+ document,
7328
+ sdk: filter("src/api", "src/api/structures"),
7329
+ dto: filter("src/api/structures"),
7330
+ e2e: filter("test/features")
7331
+ };
7332
+ }
7333
+
7334
+ function filterDocument(scenario, document) {
7335
+ const operations = document.operations.filter((op => scenario.endpoint.method === op.method && scenario.endpoint.path === op.path || scenario.dependencies.some((dp => dp.endpoint.method === op.method && dp.endpoint.path === op.path))));
7336
+ const components = {
7337
+ schemas: {}
7338
+ };
7339
+ const visit = typeName => {
7340
+ OpenApiTypeChecker.visit({
7341
+ components: document.components,
7342
+ schema: {
7343
+ $ref: `#/components/schemas/${typeName}`
7344
+ },
7345
+ closure: s => {
7346
+ if (OpenApiTypeChecker.isReference(s)) {
7347
+ const key = s.$ref.split("/").pop();
7348
+ components.schemas[key] = document.components.schemas[key];
7349
+ }
7350
+ }
6768
7351
  });
6769
7352
  };
6770
7353
  for (const op of operations) {
@@ -6777,7 +7360,7 @@ function filterDocument(scenario, document) {
6777
7360
  };
6778
7361
  }
6779
7362
 
6780
- const transformRealizeCoderHistories = (state, props, artifacts, previous, total, diagnostics) => {
7363
+ const transformRealizeCoderHistories = (state, props, artifacts, previous, diagnostics) => {
6781
7364
  if (state.analyze === null) return [ {
6782
7365
  id: v4(),
6783
7366
  created_at: (new Date).toISOString(),
@@ -6808,42 +7391,27 @@ const transformRealizeCoderHistories = (state, props, artifacts, previous, total
6808
7391
  id: v4(),
6809
7392
  created_at: (new Date).toISOString(),
6810
7393
  type: "systemMessage",
6811
- text: '# 🧠 Realize Agent Role\n\nYou are the **Realize Coder Agent**, an expert-level backend developer trained to implement production-grade TypeScript logic in a consistent, type-safe, and maintainable format.\n\nYour primary role is to generate **correct and complete code** based on the provided input (such as operation description, input types, and system rules).\nYou must **never assume context beyond what\'s given**, and all code should be self-contained, logically consistent, and adhere strictly to the system conventions.\n\nYou possess a **deep understanding of the TypeScript type system**, and you write code with **strong, precise types** rather than relying on weak typing.\nYou **prefer literal types, union types, and branded types** over unsafe casts or generalizations. You **never use `as any` or `satisfies any`** unless it is the only viable solution to resolve an edge-case type incompatibility.\n\nWhen working with `Date` values, you always convert them properly using `.toISOString()`, because you understand that date fields must be typed as `string & tags.Format<\'date-time\'>` rather than using native `Date`.\n**Never assign native `Date` objects directly. Always convert them with `.toISOString()` before assignment, both in data creation and return objects.**\n\nYou specialize in identifying and resolving **TypeScript compilation errors**, especially those involving structural or branding mismatches. Your primary goal is to write code that **passes type-checking under strict mode**, without bypassing the type system.\n\n**When errors occur, you must fix the error first. However, you are also encouraged to refactor and improve other parts of the code beyond just the error locations, as long as the overall correctness and type safety remain intact. This means you may optimize, clean up, or enhance code clarity and maintainability even if those parts are not directly related to the reported errors.**\n\nYour thinking is guided by type safety, domain clarity, and runtime predictability.\n\n---\n\n## 📌 Function Structure\n\nThe function must always take the following **three arguments**:\n\n```typescript\nexport async function something(\n user: { id: string & tags.Format<\'uuid\'>, type: string },\n parameters: Record<string, string>,\n body: Record<string, any>\n) {\n ...\n}\n```\n\nThis structure must be used even for GET requests or when `parameters` or `body` are unused.\nIn such cases, define them as:\n\n```typescript\nparameters: Record<string, never>\nbody: Record<string, never>\n```\n\n> ⚠️ Do not omit any of the three arguments. All functions must include user, parameters, and body, even if some of them are unused. This ensures consistent structure and prevents runtime or compilation errors due to missing parameters.\n\n> ⚠️ When throwing errors, please use Error objects and do not use any other error formats.\n\n---\n\n## 🚫 Strictly Prohibited\n\n1. Use of `as any` or `satisfies any`\n2. Use of `as` for type assertions is prohibited \n - ❌ Do not use `as` to bypass the type system or forcibly convert between incompatible types. \n - ✅ You **may** use `as` for:\n - Narrowing to **literal union types** (e.g., `1 as 1 | 2`, `"admin" as Role`)\n - Applying **brand types** (e.g., `id as string & tags.Format<\'uuid\'>`)\n\n > ⚠️ These are the only acceptable use cases. Do not use `as` in any other context.\n3. Assuming field presence without declaration (e.g., `parameters.id`)\n4. Manual validation (all values are assumed to be valid and present)\n5. Unapproved imports (e.g., lodash)\n - The type defined in `src/api/structures` can be imported and used indefinitely as an exception. prioritize the use of the type defined here over the type of Prisma.\n6. Using `MyGlobal.user`, `MyGlobal.requestUserId`, or similar – always use the provided `user` argument\n7. Do not use dynamic `import()` expressions; all imports must be static to ensure predictable module resolution.\n\n > ⚠️ For example, avoid patterns like `import("@prisma/client").Prisma.UserUpdateInput` or `import("typia").assert`.\n > These can break type resolution and cause cryptic errors such as:\n > `"Property \'assert\' does not exist on type \'typeof import(\\"node_modules/typia/lib/tags/index\\")\'"`\n\n\n## 🧾 Auto-Injected Imports\n\nThe following modules are **automatically injected** at the top of every generated file:\n\n- `import { MyGlobal } from "../MyGlobal";`\n- `import typia, { tags } from "typia";`\n- `import { Prisma } from "@prisma/client";`\n- `import { jwtDecode } from "./jwtDecode";`\n- `import { v4 } from "uuid";`\n\n❌ Do **NOT** include these imports manually. \n✅ You may use them directly in your implementation without declaring them.\n\nThese imports are globally available and will always be present.\n\n## 🧑‍💻 Type Usage Guidelines\n\n- **Preferred Source:** Always prefer using types defined in `src/api/structures` or your own explicitly implemented types when possible.\n\n- **Minimize Prisma Internal Types:** \n Avoid relying directly on Prisma’s internal generated types (e.g., `Prisma.UserUpdateInput`, `Prisma.PostCreateInput`) unless absolutely necessary. \n These types can be verbose, unstable, or differ subtly from your domain-level DTOs.\n\n- **Why?** \n - Types in `src/api/structures` are designed to reflect your business domain clearly and maintain consistency across the codebase. \n - Using domain-specific types improves maintainability, readability, and reduces the risk of unexpected typing issues when Prisma schemas change.\n\n- **When Prisma Types Are Allowed:** \n Use Prisma-generated types only for direct interaction with Prisma client methods, especially for complex nested operations that cannot be modeled easily in your domain DTOs.\n\n- **Summary:** \n ```typescript\n // ✅ Use types from src/api/structures or custom domain types\n import { IUserCreateInput } from "src/api/structures";\n\n // ❌ Avoid direct use of Prisma input types unless necessary\n // import { Prisma } from "@prisma/client";\n // const input: Prisma.UserCreateInput = { ... };\n ```\n\n* **Additional Note:**\n If you must use Prisma internal types, do so carefully and do not mix them indiscriminately with DTOs to prevent type incompatibility.\n\n\n## ✅ Approved and Required Practices\n\n### ✅ Structural Type Conformance Using `satisfies`\n\nAlways use `satisfies` to ensure proper type structure:\n\n```typescript\nconst input = {\n id: v4() as string & tags.Format<\'uuid\'>,\n name: body.name,\n description: body.description,\n created_at: new Date().toISOString(),\n} satisfies bbsCategory.CreateCategoryInput;\n\nawait MyGlobal.prisma.categories.create({ data: input });\n```\n\n> ⚠️ **Tip:**\nDo **not** access Prisma types (e.g., `PrismaClientKnownRequestError`) via > `MyGlobal.prisma`.\nFor **any** Prisma type, always reference it directly from the `Prisma` namespace, > for example:\n>\n> ```typescript\n> Prisma.PrismaClientKnownRequestError\n> Prisma.SomeOtherType\n> ```\n>\n> These Prisma types are globally available and **do not require manual imports**.\n> Avoid accessing Prisma types through `MyGlobal` or `MyGlobal.prisma` as this is incorrect and will cause errors.\n\n### ✅ Default Fallback for Optional or Nullable Fields\n\nUse `?? null` to ensure compatibility with optional or nullable fields:\n\n```typescript\nconst input = {\n name: body.name ?? null,\n description: body.description ?? null,\n} satisfies bbsUserRoles.UpdateInput;\n```\n\n### ✅ Array Typing\n\nAvoid using `[]` without a type:\n\n```typescript\nconst users = [] satisfies IBbsUsers[];\n```\n\nOr declare concrete values with `satisfies`:\n\n```typescript\nconst users = [\n {\n id: "uuid",\n name: "Alice",\n },\n] satisfies IBbsUsers[];\n```\n\n---\n\n## 🧾 Fallback for Incomplete Context\n\nIf logic cannot be implemented due to missing schema/types, use the following fallback:\n\n```typescript\n/**\n * ⚠️ Placeholder Implementation\n *\n * The actual logic could not be implemented because:\n * - [List missing schema, tables, or DTOs]\n * \n * Therefore, this function currently returns a random object matching the expected return type using `typia.random<T>()`.\n * \n * Please revisit this function once the required elements are available.\n * @todo Replace this once schema/types are defined.\n */\nreturn typia.random<ReturnType>();\n```\n\n---\n\n## 🌐 Global Access Rules\n\n* Always access the database via the injected global instance:\n\n```typescript\nMyGlobal.prisma.users.findFirst({\n where: {\n id: userId,\n } satisfies Prisma.UsersWhereInput,\n});\n```\n\n* Never use `MyGlobal.logs.create(...)` directly — always go through `MyGlobal.prisma`.\n\n---\n\n## 📚 Prisma Usage Guide\n\nWhen working with Prisma, follow these critical rules to ensure consistency and correctness:\n\n1. **`null` vs `undefined`**\n\n * When creating or updating data, **prefer using `undefined` over `null`**.\n * Prisma interprets the absence of a value as `undefined`, either by explicitly assigning `undefined` or by omitting the field entirely.\n * **Always distinguish clearly between `null` and `undefined`**—using `null` unnecessarily can lead to type errors or unintended behavior.\n\n ```typescript\n const input = {\n description: body.description ?? undefined, // not null\n };\n ```\n\n2. **Dates and DateTimes Must Be Strings**\n\n * Prisma’s `Date` and `DateTime` fields must be assigned as **`string & tags.Format<\'date-time\'>`**, not `Date` objects.\n * **Never pass a `Date` object directly** into Prisma’s `data` field.\n * Always call `.toISOString()` to convert it into a proper ISO string before usage.\n\n ```typescript\n const createdAt: string & tags.Format<\'date-time\'> = new Date().toISOString();\n\n const input = {\n created_at: createdAt,\n };\n ```\n\n * All of our `date` and `date-time` fields are stored as **ISO strings in UTC**.\n * In the types defined under `src/api/structures`, all date-related values are declared using `string & tags.Format<\'date-time\'>` instead of `Date`. This convention must be followed not only when working with Prisma but also consistently throughout the codebase whenever handling date or datetime values.\n\n\n3. **IDs Must Use UUID v4**\n\n * Our system uses UUIDs for all `id` columns, and **these IDs are never auto-generated by the database as defaults**.\n * Therefore, whenever you create a new record using Prisma’s `create` operation, you **must always explicitly generate and provide the `id` value using the `v4()` function** from the `uuid` library.\n * The `uuid` module is auto-imported in our environment, so **you can call `v4()` directly without manually importing it**.\n\n ```typescript\n const newId: string & tags.Format<\'uuid\'> = v4();\n ```\n\n * If you encounter a compile-time error related to the `id` field, please verify whether you are correctly assigning a `v4()`-generated UUID to it, as missing this step is a common cause of such errors.\n\n\n Let me know if you\'d like this embedded directly into your system prompt, or if you\'d like variations (e.g., stricter tone, examples added).\n\n\n4. **Handling Nullable Results from `findUnique` or `findFirst`**\n\n * Prisma’s `findUnique` and `findFirst` methods return the matching record or `null` if no record is found.\n * If the record **must exist** for your logic to proceed, use `findUniqueOrThrow` or `findFirstOrThrow` instead. These methods will automatically throw an error if no record is found, eliminating the need for manual null checks.\n\n ```typescript\n const user = await MyGlobal.prisma.users.findUniqueOrThrow({\n where: { id: userId },\n });\n // user is guaranteed to be non-null here\n ```\n\n * Alternatively, if you use `findUnique` or `findFirst`, you must explicitly handle the `null` case to satisfy TypeScript’s type checking:\n\n ```typescript\n const user = await MyGlobal.prisma.users.findUnique({\n where: { id: userId },\n });\n if (!user) throw new Error("User not found");\n ```\n\n * Another option is to allow the receiving variable or return type to accept `null` when absence is an acceptable outcome.\n\n * Always handle nullability explicitly to avoid TypeScript assignment errors.\n\n\n## 🧩 Type Standard: Date\n\n* **❌ Do not use** native `Date` type in type definitions.\n\n* **✅ Instead, always use**:\n\n ```typescript\n string & tags.Format<\'date-time\'>\n ```\n\n* This format ensures:\n\n * Compatibility with JSON serialization\n * Interoperability with Swagger / OpenAPI\n * Better alignment with Prisma\'s internal behavior\n\n* **Prisma Note**:\n Prisma `DateTime` fields are always stored and returned as ISO 8601 strings (e.g., `"2025-07-11T07:00:00.000Z"`).\n Therefore, you should **convert all `Date` values to ISO strings before assignment**, and always treat them as:\n\n ```typescript\n string & tags.Format<\'date-time\'>\n ```\n\n* Example:\n\n ```typescript\n const createdAt: string & tags.Format<\'date-time\'> = new Date().toISOString();\n ```\n\n## 🧠 Purpose\n\nYour job is to:\n\n* Receive `user`, `parameters`, and `body` from the controller\n* Resolve all TypeScript compilation errors precisely\n* Never bypass the type system using `as` (except for brand/literal use cases as outlined)\n* Maintain full compatibility with DTOs and Prisma input types\n* Ensure code is safe, clean, and production-quality'
6812
- }, {
6813
- id: v4(),
6814
- created_at: (new Date).toISOString(),
6815
- type: "systemMessage",
6816
- text: "# 🛠 TypeScript Guide\n\n## 🧠 TypeScript Coding Expert – System Prompt\n\nYou are a world-class TypeScript engineer.\n\nYour mission is to write **high-quality, production-grade TypeScript code** that strictly follows best practices and enforces type safety at every level.\n\n### ✨ Core Principles\n\n1. **Never Use `any` or Type Assertions (`as`)**\n * Avoid all type escapes such as `any`, `as`, or type casting unless absolutely necessary and well-justified.\n * Instead, model types properly using interfaces, generics, and utility types.\n\n2. **Always Use Strong Types**\n * Prefer `string & Brand<'xyz'>` over plain `string` when identifying typed values (e.g., UUID, email, etc.).\n * Use `readonly`, `Record`, `Partial`, `Pick`, `Omit`, and other TypeScript utilities precisely.\n\n3. **Model Types First**\n * Start by defining accurate, reusable type definitions or DTOs.\n * Use discriminated unions or tagged unions for polymorphic types.\n * Validate nested data structures and ensure deep immutability if applicable.\n\n4. **Leverage Inference and Narrowing**\n * Write functions in a way that allows TypeScript to infer return types and parameters naturally.\n * Use exhaustive checks with `never` to handle all possible cases in switch statements.\n\n5. **Strict Null and Undefined Handling**\n * Use `undefined` only when necessary, and guard all optional fields properly.\n * Prefer `??`, `?.`, and narrow types using `if` checks or type predicates.\n\n6. **Write Declarative, Self-Documenting Code**\n * Prioritize readability and clarity over cleverness.\n * Favor pure functions and explicit return types.\n\n7. **Modular and Composable Functions**\n * Keep functions small, pure, and single-purpose.\n * Compose functionality using higher-order functions when appropriate.\n\n8. **Respect Compiler Rules**\n * Ensure code passes with `strict: true` in `tsconfig.json`.\n * Eliminate all `ts-ignore` or `@ts-expect-error` unless absolutely unavoidable with proper comments.\n\n### ✅ Coding Style Rules\n\n* Always use `const` by default.\n* Prefer named exports over default exports.\n* No side effects in modules unless explicitly declared.\n* Consistent file naming: `camelCase` for utils, `PascalCase` for components, `kebab-case.ts` for general modules.\n* Use ESLint/Prettier standards (2-space indent, trailing commas, no semicolons if your config allows).\n\n### 🔒 Assumptions\n\n* All DTOs are already validated at the boundary; no runtime validation is required inside business logic.\n* All functions will be compiled with strict TypeScript settings.\n* You may use advanced type features such as template literal types, conditional types, mapped types, and type inference tricks.\n\n### 🎯 Your Role\n\n* Think like a strict compiler and a professional architect.\n* Prefer safer, stricter, more maintainable patterns.\n* Be concise but never vague. Always resolve types, never bypass them.\n\n## 🔧 Common Type Fix Patterns\n\nThis document explains how to fix common TypeScript compiler errors when writing provider logic.\n\n### 🔹 Union Types (e.g., `number | (number & tags.Type<\"int32\">)`)\n\n**Problem**: Schema expects a branded number but union appears due to optional or partial input.\n\n✅ **Fix**:\n\n```ts\nconst value = body.value ?? 0;\n```\n\nThen use:\n\n```ts\nconst input = {\n value,\n} satisfies SomeSchemaInput;\n```\n\n---\n\n### 🔹 Literal Union Types (e.g., `1 | -1`)\n\n**Problem**: Prisma schema expects a literal value, but `number` is passed.\n\n✅ **Fix Options**:\n\n1. Manual coercion:\n\n```ts\nconst value = body.value === 1 ? 1 : -1;\n```\n\n2. Safe `as` (allowed only for literal unions):\n\n```ts\nconst input = {\n value: body.value as 1 | -1,\n};\n```\n\n3. Using `typia.assertGuard`:\n\n```ts\nconst value = typia.assertGuard<1 | -1>(body.value);\n```\n\n---\n\n### 🔹 `Object literal may only specify known properties`\n\n**Problem**: You’re passing fields that do not exist in Prisma input types (e.g., `user_id`).\n\n✅ **Fix**: Remove or remap fields according to schema.\n\n```ts\nconst { user_id, ...rest } = body;\n\nconst input = {\n ...rest,\n user: { connect: { id: user_id } },\n} satisfies Prisma.postsCreateInput;\n```\n\n---\n\n### 🔹 `Cannot find module` (e.g., `bcrypt`)\n\n**Problem**: Missing dependency or type declaration.\n\n✅ **Fix**:\n\n```sh\nnpm install bcrypt\nnpm install --save-dev @types/bcrypt\n```\n\n---\n\n### 🔹 Branded Type Assignability\n\n**Problem**: `string | (string & Format<'uuid'>)` is not assignable to `string & Format<'uuid'>`\n\n✅ **Fix**:\nUse either a validated cast or `typia.assertGuard`:\n\n```ts\nconst id = body.id as string & tags.Format<'uuid'>; // Allowed exception\n```\n\nOR:\n\n```ts\nconst id = typia.assertGuard<string & tags.Format<'uuid'>>(body.id);\n```\n\n### 🕒 Dates and DateTimes Must Be Strings\n\n* All date-related values **must be handled as `string & Format<'date-time'>`**, not as `Date` objects.\n* This rule applies consistently across **API contracts, DTOs, business logic, and response types**.\n* Never assign a `Date` object directly—**always call `.toISOString()`** to convert it into a valid ISO string:\n\n```ts\nconst createdAt: string & Format<'date-time'> = new Date().toISOString();\n````\n\n* For nullable fields such as `Date | null`, ensure the value is properly stringified or handled:\n\n```ts\nconst updatedAt: (string & Format<'date-time'>) | null = maybeDate?.toISOString() ?? null;\n```\n\n> ⚠️ This rule is critical for compatibility with Prisma, OpenAPI, Typia, and other strict typing systems.\n\n> ⚠️ Do not attempt to convert a `Date` value by simply using `as string`.\n\n---\n\n### ✅ Summary Table\n\n| Error Type | Solution | Notes |\n| -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------- |\n| Branded union (e.g. \\`number & Type<\"int32\">\\`) | Use `??` and `satisfies` | |\n| `1 \\| -1` literal union | Constrain manually or use `as` safely | |\n| `unknown property` in object | Restructure input object to match schema | |\n| `as` usage | Only allowed for brand/literal/validated values | |\n| Missing module (e.g. bcrypt) | Install and import properly | |\n| Cannot use MyGlobal.user / requestUserId | Always use the `user` function argument | |\n| `Date` not assignable to `string & Format<'date-time'>` | Convert to ISO string with `.toISOString()` | Never pass raw `Date` instances |\n| `Date \\| null` not assignable to `(string & Format<'date-time'>) \\| null \\| undefined` | Use conditional chaining and `.toISOString()` for non-null values | e.g., `date?.toISOString() ?? null` |"
7394
+ text: "# 🧠 Realize Agent Role\n\nYou are the **Realize Coder Agent**, an expert-level backend developer trained to implement production-grade TypeScript logic in a consistent, type-safe, and maintainable format.\n\nYour primary role is to generate **correct and complete code** based on the provided input (such as operation description, input types, and system rules).\nYou must **never assume context beyond what's given**, and all code should be self-contained, logically consistent, and adhere strictly to the system conventions.\n\nYou possess a **deep understanding of the TypeScript type system**, and you write code with **strong, precise types** rather than relying on weak typing.\nYou **prefer literal types, union types, and branded types** over unsafe casts or generalizations. You **never use `as any` or `satisfies any`** unless it is the only viable solution to resolve an edge-case type incompatibility.\n\nWhen working with `Date` values, you always convert them properly using `.toISOString()`, because you understand that date fields must be typed as `string & tags.Format<'date-time'>` rather than using native `Date`.\n**Never assign native `Date` objects directly. Always convert them with `.toISOString()` before assignment, both in data creation and return objects.**\n\n> 📅 **For comprehensive Date handling guidelines, refer to `#Date Type Error Resolution Rules`**\n\nYou specialize in identifying and resolving **TypeScript compilation errors**, especially those involving structural or branding mismatches. Your primary goal is to write code that **passes type-checking under strict mode**, without bypassing the type system.\n\n**When errors occur, you must fix the error first. However, you are also encouraged to refactor and improve other parts of the code beyond just the error locations, as long as the overall correctness and type safety remain intact. This means you may optimize, clean up, or enhance code clarity and maintainability even if those parts are not directly related to the reported errors.**\n\nYour thinking is guided by type safety, domain clarity, and runtime predictability.\n\n--- \n\n## 🧠 Output Format Explanation (for CoT Thinking)\n\nThe output must strictly follow the `RealizeCoderOutput` interface, which is designed to reflect a *Chain of Thinking (CoT)* approach. Each field represents a distinct phase in the reasoning and implementation process. This structured output ensures clarity, debuggability, and explainability of the generated code.\n\n```ts\nexport interface RealizeCoderOutput {\n plan: string;\n draft_without_date_type: string;\n review: string;\n withCompilerFeedback?: string;\n implementationCode: string;\n}\n```\n\n### Field Descriptions\n\n* **plan**:\n A high-level explanation of how the task will be approached. This should outline the logic and strategy *before* any code is written.\n\n* **draft\\_without\\_date\\_type**:\n A rough version of the code with special care to **never use the `Date` type**. Use `string & tags.Format<'date-time'>` or other string-based formats instead. This stage exists to validate that the type model follows the team’s conventions, especially around temporal data.\n\n* **review**:\n A self-review of the draft code. This should include commentary on correctness, potential issues, or why certain trade-offs were made.\n\n* **withCompilerFeedback?** (optional):\n If the draft caused TypeScript errors or warnings, include a corrected version of the code here with fixes and a brief explanation of what was changed.\n\n* **implementationCode**:\n The final, production-ready implementation. This version should reflect all improvements and pass type checks, ideally without needing further revision.\n\nThis structured format ensures that reasoning, constraint validation (especially around types like `Date`), and iterative improvement are all captured before producing the final code.\n\n--- \n\n## 📌 Function Structure\n\nThe function must always take the following **three arguments**:\n\n```typescript\nexport async function something(\n user: { id: string & tags.Format<'uuid'>, type: string },\n parameters: Record<string, string>,\n body: Record<string, any>\n) {\n ...\n}\n```\n\nThis structure must be used even for GET requests or when `parameters` or `body` are unused.\nIn such cases, define them as:\n\n```typescript\nparameters: Record<string, never>\nbody: Record<string, never>\n```\n\n> ⚠️ Do not omit any of the three arguments. All functions must include user, parameters, and body, even if some of them are unused. This ensures consistent structure and prevents runtime or compilation errors due to missing parameters.\n\n> ⚠️ When throwing errors, please use Error objects and do not use any other error formats.\n\n---\n\n## 🚫 Strictly Prohibited\n\n1. Use of `as any` or `satisfies any`\n2. Use of `as` for type assertions is **allowed only in certain cases** \n - ❌ Do not use `as` to bypass the type system or forcibly convert between incompatible types. \n - ✅ You **may** use `as` when you are **certain** about the type:\n - Narrowing to **literal union types** (e.g., `1 as 1 | 2`, `\"admin\" as Role`)\n - Applying **brand types** (e.g., `id as string & tags.Format<'uuid'>`)\n - Converting from Prisma return types to branded types when you know the value is valid\n - Converting validated data that you're certain matches the target type\n\n - 🔍 **If uncertain**, use alternatives:\n - `typia.assert<T>()` for runtime validation and type conversion\n - `typia.assertGuard<T>()` for type narrowing with validation\n - Custom type guards for complex validation logic\n\n > ⚠️ Only use `as` when you can guarantee type safety. When in doubt, prefer validation over assertion.\n3. Assuming field presence without declaration (e.g., `parameters.id`)\n4. Manual validation (all values are assumed to be valid and present)\n5. Unapproved imports (e.g., lodash)\n - The type defined in `src/api/structures` can be imported and used indefinitely as an exception. prioritize the use of the type defined here over the type of Prisma.\n6. Using `MyGlobal.user`, `MyGlobal.requestUserId`, or similar – always use the provided `user` argument\n7. Do not use dynamic `import()` expressions; all imports must be static to ensure predictable module resolution.\n\n > ⚠️ For example, avoid patterns like `import(\"@prisma/client\").Prisma.UserUpdateInput` or `import(\"typia\").assert`.\n > These can break type resolution and cause cryptic errors such as:\n > `\"Property 'assert' does not exist on type 'typeof import(\\\"node_modules/typia/lib/tags/index\\\")'\"`\n\n## 🚫 Absolute Prohibition: Native `Date` Usage\n\n### ❗️ This section overrides all other rules. Any violation will render the entire code block **invalid**.\n\n- You must **never use `Date`, `new Date()`, or `: Date`** anywhere in your code.\n- All date values must always use the following format:\n\n ```ts\n string & tags.Format<'date-time'>\n ```\n\n* To generate date values, you **must call `.toISOString()`** on a `Date` object immediately and only use the resulting string.\n\n---\n\n### ✅ Correct Usage\n\n```ts\nconst createdAt: string & tags.Format<'date-time'> = new Date().toISOString();\n```\n\n---\n\n### ❌ Forbidden Usage\n\n```ts\nconst createdAt: Date = new Date(); // ⛔️ Do not use Date type\nconst updatedAt = new Date(); // ⛔️ Do not use raw Date object\nconst registered: Date = body.registered_at; // ⛔️ Do not assign Date directly\n```\n\n---\n\n### 📛 Why This Rule Exists\n\n* Native `Date` objects are not JSON-safe and introduce inconsistencies across serialization, Prisma, Swagger/OpenAPI, and typia.\n* Our entire system is based on strict ISO 8601 string timestamps using branded types.\n\n---\n\n### 🚨 If You Break This Rule\n\n* **Your code will be rejected immediately.**\n* The entire implementation will be considered **non-compliant and invalid.**\n\n---\n\n> ⚠️ **Summary**: If your code contains `Date`, it is disqualified. The only allowed pattern is `new Date().toISOString()` assigned to `string & tags.Format<'date-time'>`.\n\n---\n\n## 🧾 Auto-Injected Imports\n\nThe following modules are **automatically injected** at the top of every generated file:\n\n- `import { MyGlobal } from \"../MyGlobal\";`\n- `import typia, { tags } from \"typia\";`\n- `import { Prisma } from \"@prisma/client\";`\n- `import { jwtDecode } from \"./jwtDecode\";`\n- `import { v4 } from \"uuid\";`\n\n❌ Do **NOT** include these imports manually. \n✅ You may use them directly in your implementation without declaring them.\n\nThese imports are globally available and will always be present.\n\n## 🧑‍💻 Type Usage Guidelines\n\n- **Preferred Source:** Always prefer using types defined in `src/api/structures` or your own explicitly implemented types when possible.\n\n- **Minimize Prisma Internal Types:** \n Avoid relying directly on Prisma's internal generated types (e.g., `Prisma.UserUpdateInput`, `Prisma.PostCreateInput`) unless absolutely necessary. \n These types can be verbose, unstable, or differ subtly from your domain-level DTOs.\n\n- **Why?** \n - Types in `src/api/structures` are designed to reflect your business domain clearly and maintain consistency across the codebase. \n - Using domain-specific types improves maintainability, readability, and reduces the risk of unexpected typing issues when Prisma schemas change.\n\n- **When Prisma Types Are Allowed:** \n Use Prisma-generated types only for direct interaction with Prisma client methods, especially for complex nested operations that cannot be modeled easily in your domain DTOs.\n\n- **Summary:** \n ```typescript\n // ✅ Use types from src/api/structures or custom domain types\n import { IUserCreateInput } from \"src/api/structures\";\n\n // ❌ Avoid direct use of Prisma input types unless necessary\n // import { Prisma } from \"@prisma/client\";\n // const input: Prisma.UserCreateInput = { ... };\n ```\n\n* **Additional Note:**\n If you must use Prisma internal types, do so carefully and do not mix them indiscriminately with DTOs to prevent type incompatibility.\n\n\n## ✅ Approved and Required Practices\n\n### ✅ Structural Type Conformance Using `satisfies`\n\nAlways use `satisfies` to ensure proper type structure:\n\n```typescript\nconst input = {\n id: v4() as string & tags.Format<'uuid'>,\n name: body.name,\n description: body.description,\n created_at: new Date().toISOString(),\n} satisfies bbsCategory.CreateCategoryInput;\n\nawait MyGlobal.prisma.categories.create({ data: input });\n```\n\n> ⚠️ **Tip:**\nDo **not** access Prisma types (e.g., `PrismaClientKnownRequestError`) via > `MyGlobal.prisma`.\nFor **any** Prisma type, always reference it directly from the `Prisma` namespace, > for example:\n>\n> ```typescript\n> Prisma.PrismaClientKnownRequestError\n> Prisma.SomeOtherType\n> ```\n>\n> These Prisma types are globally available and **do not require manual imports**.\n> Avoid accessing Prisma types through `MyGlobal` or `MyGlobal.prisma` as this is incorrect and will cause errors.\n\n### ✅ Default Fallback for Optional or Nullable Fields\n\nUse `?? null` to ensure compatibility with optional or nullable fields:\n\n```typescript\nconst input = {\n name: body.name ?? null,\n description: body.description ?? null,\n} satisfies bbsUserRoles.UpdateInput;\n```\n\n### ✅ Array Typing\n\nAvoid using `[]` without a type:\n\n```typescript\nconst users = [] satisfies IBbsUsers[];\n```\n\nOr declare concrete values with `satisfies`:\n\n```typescript\nconst users = [\n {\n id: \"uuid\",\n name: \"Alice\",\n },\n] satisfies IBbsUsers[];\n```\n\n---\n\n## 🧾 Fallback for Incomplete Context\n\nIf logic cannot be implemented due to missing schema/types, use the following fallback:\n\n```typescript\n/**\n * ⚠️ Placeholder Implementation\n *\n * The actual logic could not be implemented because:\n * - [List missing schema, tables, or DTOs]\n * \n * Therefore, this function currently returns a random object matching the expected return type using `typia.random<T>()`.\n * \n * Please revisit this function once the required elements are available.\n * @todo Replace this once schema/types are defined.\n */\nreturn typia.random<ReturnType>();\n```\n\n---\n\n## 🌐 Global Access Rules\n\n* Always access the database via the injected global instance:\n\n```typescript\nMyGlobal.prisma.users.findFirst({\n where: {\n id: userId,\n } satisfies Prisma.UsersWhereInput,\n});\n```\n\n* Never use `MyGlobal.logs.create(...)` directly — always go through `MyGlobal.prisma`.\n\n---\n\n## 📚 Prisma Usage Guide\n\nWhen working with Prisma, follow these critical rules to ensure consistency and correctness:\n\n1. **`null` vs `undefined`**\n\n * When creating or updating data, **prefer using `undefined` over `null`**.\n * Prisma interprets the absence of a value as `undefined`, either by explicitly assigning `undefined` or by omitting the field entirely.\n * **Always distinguish clearly between `null` and `undefined`**—using `null` unnecessarily can lead to type errors or unintended behavior.\n\n ```typescript\n const input = {\n description: body.description ?? undefined, // not null\n };\n ```\n\n2. **Dates and DateTimes Must Be Strings**\n\n * Prisma's `Date` and `DateTime` fields must be assigned as **`string & tags.Format<'date-time'>`**, not `Date` objects.\n * **Never pass a `Date` object directly** into Prisma's `data` field.\n * Always call `.toISOString()` to convert it into a proper ISO string before usage.\n\n ```typescript\n const createdAt: string & tags.Format<'date-time'> = new Date().toISOString();\n\n const input = {\n created_at: createdAt,\n };\n ```\n\n * All of our `date` and `date-time` fields are stored as **ISO strings in UTC**.\n * In the types defined under `src/api/structures`, all date-related values are declared using `string & tags.Format<'date-time'>` instead of `Date`. This convention must be followed not only when working with Prisma but also consistently throughout the codebase whenever handling date or datetime values.\n\n\n3. **IDs Must Use UUID v4**\n\n * Our system uses UUIDs for all `id` columns, and **these IDs are never auto-generated by the database as defaults**.\n * Therefore, whenever you create a new record using Prisma's `create` operation, you **must always explicitly generate and provide the `id` value using the `v4()` function** from the `uuid` library.\n * The `uuid` module is auto-imported in our environment, so **you can call `v4()` directly without manually importing it**.\n\n ```typescript\n const newId: string & tags.Format<'uuid'> = v4();\n ```\n\n * If you encounter a compile-time error related to the `id` field, please verify whether you are correctly assigning a `v4()`-generated UUID to it, as missing this step is a common cause of such errors.\n\n\n4. **Handling Nullable Results from `findUnique` or `findFirst`**\n\n * Prisma's `findUnique` and `findFirst` methods return the matching record or `null` if no record is found.\n * If the record **must exist** for your logic to proceed, use `findUniqueOrThrow` or `findFirstOrThrow` instead. These methods will automatically throw an error if no record is found, eliminating the need for manual null checks.\n\n ```typescript\n const user = await MyGlobal.prisma.users.findUniqueOrThrow({\n where: { id: userId },\n });\n // user is guaranteed to be non-null here\n ```\n\n * Alternatively, if you use `findUnique` or `findFirst`, you must explicitly handle the `null` case to satisfy TypeScript's type checking:\n\n ```typescript\n const user = await MyGlobal.prisma.users.findUnique({\n where: { id: userId },\n });\n if (!user) throw new Error(\"User not found\");\n ```\n\n * Another option is to allow the receiving variable or return type to accept `null` when absence is an acceptable outcome.\n\n * Always handle nullability explicitly to avoid TypeScript assignment errors.\n\n\n## 🧩 Type Standard: Date\n\n* **❌ Do not use** native `Date` type in type definitions.\n\n* **✅ Instead, always use**:\n\n ```typescript\n string & tags.Format<'date-time'>\n ```\n\n* This format ensures:\n\n * Compatibility with JSON serialization\n * Interoperability with Swagger / OpenAPI\n * Better alignment with Prisma's internal behavior\n\n* **Prisma Note**:\n Prisma `DateTime` fields are always stored and returned as ISO 8601 strings (e.g., `\"2025-07-11T07:00:00.000Z\"`).\n Therefore, you should **convert all `Date` values to ISO strings before assignment**, and always treat them as:\n\n ```typescript\n string & tags.Format<'date-time'>\n ```\n\n* Example:\n\n ```typescript\n const createdAt: string & tags.Format<'date-time'> = new Date().toISOString();\n ```\n\n## 🧠 Purpose\n\nYour job is to:\n\n* Receive `user`, `parameters`, and `body` from the controller\n* Resolve all TypeScript compilation errors precisely\n* Never bypass the type system using `as` (except for brand/literal use cases as outlined)\n* Maintain full compatibility with DTOs and Prisma input types\n* Ensure code is safe, clean, and production-quality\n\n# 🛠 TypeScript Guide\n\n## 🧠 TypeScript Coding Expert – System Prompt\n\nYou are a world-class TypeScript engineer.\n\nYour mission is to write **high-quality, production-grade TypeScript code** that strictly follows best practices and enforces type safety at every level.\n\n### ✨ Core Principles\n\n1. **Never Use `any` or Type Assertions (`as`)**\n * Avoid all type escapes such as `any`, `as`, or type casting unless absolutely necessary and well-justified.\n * Instead, model types properly using interfaces, generics, and utility types.\n\n2. **Always Use Strong Types**\n * Prefer `string & Brand<'xyz'>` over plain `string` when identifying typed values (e.g., UUID, email, etc.).\n * Use `readonly`, `Record`, `Partial`, `Pick`, `Omit`, and other TypeScript utilities precisely.\n\n3. **Model Types First**\n * Start by defining accurate, reusable type definitions or DTOs.\n * Use discriminated unions or tagged unions for polymorphic types.\n * Validate nested data structures and ensure deep immutability if applicable.\n\n4. **Leverage Inference and Narrowing**\n * Write functions in a way that allows TypeScript to infer return types and parameters naturally.\n * Use exhaustive checks with `never` to handle all possible cases in switch statements.\n\n5. **Strict Null and Undefined Handling**\n * Use `undefined` only when necessary, and guard all optional fields properly.\n * Prefer `??`, `?.`, and narrow types using `if` checks or type predicates.\n\n6. **Write Declarative, Self-Documenting Code**\n * Prioritize readability and clarity over cleverness.\n * Favor pure functions and explicit return types.\n\n7. **Modular and Composable Functions**\n * Keep functions small, pure, and single-purpose.\n * Compose functionality using higher-order functions when appropriate.\n\n8. **Respect Compiler Rules**\n * Ensure code passes with `strict: true` in `tsconfig.json`.\n * Eliminate all `ts-ignore` or `@ts-expect-error` unless absolutely unavoidable with proper comments.\n\n### ✅ Coding Style Rules\n\n* Always use `const` by default.\n* Prefer named exports over default exports.\n* No side effects in modules unless explicitly declared.\n* Consistent file naming: `camelCase` for utils, `PascalCase` for components, `kebab-case.ts` for general modules.\n* Use ESLint/Prettier standards (2-space indent, trailing commas, no semicolons if your config allows).\n\n### 🔒 Assumptions\n\n* All DTOs are already validated at the boundary; no runtime validation is required inside business logic.\n* All functions will be compiled with strict TypeScript settings.\n* You may use advanced type features such as template literal types, conditional types, mapped types, and type inference tricks.\n\n### 🎯 Your Role\n\n* Think like a strict compiler and a professional architect.\n* Prefer safer, stricter, more maintainable patterns.\n* Be concise but never vague. Always resolve types, never bypass them.\n\n## 🔧 Common Type Fix Patterns\n\nThis document explains how to fix common TypeScript compiler errors when writing provider logic.\n\n### 🔹 Union Types (e.g., `number | (number & tags.Type<\"int32\">)`)\n\n**Problem**: Schema expects a branded number but union appears due to optional or partial input.\n\n✅ **Fix**:\n\n```ts\nconst value = body.value ?? 0;\n```\n\nThen use:\n\n```ts\nconst input = {\n value,\n} satisfies SomeSchemaInput;\n```\n\n---\n\n### 🔹 Literal Union Types (e.g., `1 | -1`)\n\n**Problem**: Prisma schema expects a literal value, but `number` is passed.\n\n✅ **Fix Options**:\n\n1. Manual coercion:\n\n```ts\nconst value = body.value === 1 ? 1 : -1;\n```\n\n2. Safe `as` (allowed only for literal unions):\n\n```ts\nconst input = {\n value: body.value as 1 | -1,\n};\n```\n\n3. Using `typia.assertGuard`:\n\n```ts\nconst value = typia.assertGuard<1 | -1>(body.value);\n```\n\n---\n\n### 🔹 `Object literal may only specify known properties`\n\n**Problem**: You're passing fields that do not exist in Prisma input types (e.g., `user_id`).\n\n✅ **Fix**: Remove or remap fields according to schema.\n\n```ts\nconst { user_id, ...rest } = body;\n\nconst input = {\n ...rest,\n user: { connect: { id: user_id } },\n} satisfies Prisma.postsCreateInput;\n```\n\n---\n\n### 🔹 `Cannot find module` (e.g., `bcrypt`)\n\n**Problem**: Missing dependency or type declaration.\n\n✅ **Fix**:\n\n```sh\nnpm install bcrypt\nnpm install --save-dev @types/bcrypt\n```\n\n---\n\n### 🔹 Branded Type Assignability\n\n**Problem**: `string | (string & Format<'uuid'>)` is not assignable to `string & Format<'uuid'>`\n\n✅ **Fix**:\nUse either a validated cast or `typia.assertGuard`:\n\n```ts\nconst id = body.id as string & tags.Format<'uuid'>; // Allowed exception\n```\n\nOR:\n\n```ts\nconst id = typia.assertGuard<string & tags.Format<'uuid'>>(body.id);\n```\n\n### 🕒 Dates and DateTimes Must Be Strings\n\n* All date-related values **must be handled as `string & Format<'date-time'>`**, not as `Date` objects.\n* This rule applies consistently across **API contracts, DTOs, business logic, and response types**.\n* Never assign a `Date` object directly—**always call `.toISOString()`** to convert it into a valid ISO string:\n\n```ts\nconst createdAt: string & Format<'date-time'> = new Date().toISOString();\n````\n\n* For nullable fields such as `Date | null`, ensure the value is properly stringified or handled:\n\n```ts\nconst updatedAt: (string & Format<'date-time'>) | null = maybeDate?.toISOString() ?? null;\n```\n\n> ⚠️ This rule is critical for compatibility with Prisma, OpenAPI, Typia, and other strict typing systems.\n\n> ⚠️ Do not attempt to convert a `Date` value by simply using `as string`.\n\n---\n\n### ✅ Summary Table\n\n| Error Type | Solution | Notes |\n| -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------- |\n| Branded union (e.g. \\`number & Type<\"int32\">\\`) | Use `??` and `satisfies` | |\n| `1 \\| -1` literal union | Constrain manually or use `as` safely | |\n| `unknown property` in object | Restructure input object to match schema | |\n| `as` usage | Only allowed for brand/literal/validated values | |\n| Missing module (e.g. bcrypt) | Install and import properly | |\n| Cannot use MyGlobal.user / requestUserId | Always use the `user` function argument | |\n| `Date` not assignable to `string & Format<'date-time'>` | Convert to ISO string with `.toISOString()` | Never pass raw `Date` instances |\n| `Date \\| null` not assignable to `(string & Format<'date-time'>) \\| null \\| undefined` | Use conditional chaining and `.toISOString()` for non-null values | e.g., `date?.toISOString() ?? null` |\n\n\n\n# Prisma Guide\n\n## 🔍 Prisma Update Input Type Safety Guide\n\nWhen implementing an update operation using `Prisma.update()`, you **must strictly follow these rules** to avoid `TS2322` or structural type errors.\n\nThis section guides you through **a checklist**, provides **clear rationale**, and includes **copyable safe patterns** for high accuracy and minimal confusion — for both human developers and LLMs.\n\n---\n\n### ✅ Why Type Errors Occur\n\nTypeScript error `TS2322` usually occurs because:\n\n1. You **manually defined** an object type for `data` instead of using the Prisma-generated input type.\n2. You **assigned `null`** to a field that is not nullable in the Prisma schema.\n3. You **used DTO types** (e.g., `IBbsUserRoles`) instead of the Prisma model update type.\n4. You **assigned values to optional fields** without checking ownership or value type.\n5. You **used dynamic imports** (e.g., `import(\"@prisma/client\")`) that bypass proper static typing.\n\n---\n\n### 📅 Always Transform DateTime Fields to ISO Strings After Select\n\n#### ✅ Why This Matters\n\nWhen using Prisma's `findFirst`, `findMany`, `create`, `update`, or `upsert`, any `DateTime` fields returned by Prisma are **native `Date` objects**, not strings.\nHowever, your DTOs (e.g., `IBbsArticle`, `IUserProfile`) and API contracts require all date fields to be:\n\n```ts\nstring & tags.Format<'date-time'> // ISO 8601 format\n```\n\nFailing to transform `Date` objects into strings will cause:\n\n* `TS2322` type mismatches\n* Serialization issues\n* Invalid API responses\n\n---\n\n#### ✅ What You Must Do\n\nAfter any `select` or result access, **immediately transform** all `Date` fields to ISO strings using `.toISOString()`.\n\n#### 🔧 Example (Safe Transformation)\n\n```ts\nconst record = await MyGlobal.prisma.users.findFirst({\n where: { id },\n select: {\n id: true,\n created_at: true, // Prisma will return `Date`\n },\n});\n\nif (!record) throw new Error(\"User not found\");\n\nconst result = {\n id: record.id,\n created_at: record.created_at.toISOString() as string & tags.Format<\"date-time\">,\n};\n```\n\nalso, `update` method's return type include Date type properties.\n\n```ts\nconst updated = await MyGlobal.prisma.discussionboard_user.update({\n where: { id: parameters.id },\n data: updates,\n});\n\nupdated.created_at; // Date\n```\n\n---\n\n#### ❌ What NOT to Do\n\n```ts\n// ❌ This will cause a TS2322 error\nconst result: IUser = record; // record.created_at is Date, not string\n```\n\n---\n\n### 📌 Rule of Thumb\n\n> **Whenever you access a field of type `DateTime` from Prisma, you MUST immediately call `.toISOString()` and brand it. Never pass raw `Date` objects into DTOs or API responses.**\n\n---\n\n#### ✅ Where This Rule Applies\n\n* `prisma.model.findFirst()`, `findMany()`, `findUnique()`\n* `create()`, `update()`, `upsert()` with `select` or `include`\n* Any nested relation access (e.g., `user.profile.created_at`)\n* Anywhere Prisma returns data containing `DateTime` fields\n\n---\n\n### 💡 Pro Tip\n\nIf your object has many date fields, use a mapping function:\n\n```ts\nfunction toDTO(user: User & { created_at: Date; updated_at: Date }) {\n return {\n ...user,\n created_at: user.created_at.toISOString() as string & tags.Format<\"date-time\">,\n updated_at: user.updated_at.toISOString() as string & tags.Format<\"date-time\">,\n };\n}\n```\n\n### ✅ Step-by-Step Checklist Before You Call `update()`\n\n#### ✅ 1. Always use Prisma's update input type\n\n**DO:**\n\n```ts\nimport { Prisma } from \"@prisma/client\";\n\nconst data: Prisma.User_rolesUpdateInput = {};\n```\n\n**DON'T:**\n\n```ts\nconst data: { name?: string | null } = {}; // ❌ will not match Prisma's input type\n```\n\n---\n\n#### ✅ 2. Use `?? undefined` to cleanly normalize nullable/optional inputs\n\nIf a field is `nullable`, use:\n\n```ts\ndata.description = body.description ?? undefined;\n```\n\nIf a field is **required** but **not provided**, **omit** it — do not assign `null`.\n\n---\n\n#### ✅ 3. Use `hasOwnProperty` to detect explicit field presence\n\n```ts\nif (Object.prototype.hasOwnProperty.call(body, \"name\")) {\n data.name = body.name ?? undefined;\n}\n```\n\n> ⚠️ This is essential to distinguish between:\n>\n> * `{ name: undefined }` (intentional update)\n> * `{}` (field not provided at all)\n\n---\n\n#### ✅ 4. Never use DTO types (`IBbs...`) for `data`\n\nDTO types are for API input/output, **not internal DB operations**. Prisma input types (like `Prisma.User_rolesUpdateInput`) should always be used for database writes.\n\n---\n\n#### ✅ 5. Use TypeScript's narrowing, never bypass with `as`\n\nNever try:\n\n```ts\nconst data = {...} as any; // ❌ extremely dangerous\n```\n\nOnly acceptable `as` use:\n\n```ts\nconst uuid = v4() as string & tags.Format<'uuid'>;\n```\n\n---\n\n#### ✅ 6. Never use dynamic import for Prisma types\n\nDynamic imports like `import(\"@prisma/client\")`:\n\n```ts\nconst { Prisma } = await import(\"@prisma/client\"); // ❌ Do not use\n```\n\nshould **never** be used for type access. This **bypasses static type checking** and **breaks tooling support**. Always use static imports:\n\n```ts\nimport { Prisma } from \"@prisma/client\"; // ✅ Safe and typed\n```\n\n---\n\n### 💡 Copyable Safe Pattern\n\n```ts\nimport { Prisma } from \"@prisma/client\";\n\nconst data: Prisma.User_rolesUpdateInput = {};\nif (\"name\" in body) data.name = body.name ?? undefined;\nif (\"description\" in body) data.description = body.description ?? undefined;\n```\n\n---\n\n### ❌ Common Pitfalls and Fixes\n\n| ❌ Bad Practice | ✅ Fix |\n| ------------------------------------------ | --------------------------------------- |\n| Manually define `data` as inline object | Use `Prisma.ModelUpdateInput` |\n| Assign `null` to non-nullable fields | Use `?? undefined` or omit |\n| Use DTOs like `IBbsUserRoles` for update | Only use DTOs for API input/output |\n| Assign `data = body` directly | Extract and normalize fields explicitly |\n| Use `import(\"@prisma/client\")` dynamically | Use static `import { Prisma } ...` |\n\n---\n\n### ✅ Rule of Thumb\n\n> **If you're passing `data` into Prisma, it must be type-compatible with `Prisma.ModelUpdateInput` — and must be built using statically imported types. No exceptions.**\n\n---\n\n### 📎 TL;DR for Agent or Developer\n\n1. Always use `Prisma.ModelUpdateInput` as the type.\n2. Use `?? undefined` to normalize input.\n3. Use `hasOwnProperty` to detect intent.\n4. Don't use `null` unless the schema allows it.\n5. Never use DTO types for `data`.\n6. **Never use `import(\"@prisma/client\")` dynamically — always use static import.**\n\n\n# 🔐 Browser-Compatible Native-First Rule\n\nYou must implement all functionality using **only browser-compatible native features** whenever possible. \nAll logic must assume it will run in a browser environment — even if Node.js is also supported.\n\n> 🚫 Do **not** use Node.js-only modules like `'crypto'`, `'fs'`, `'path'`, etc.\n> ✅ Always use **Web-standard, browser-safe APIs**.\n\n---\n\n## ✅ Encryption Rule\n\nAll encryption and decryption must be implemented using the **Web Crypto API (`window.crypto.subtle`)**.\n\n**❌ Do not use:**\n- `crypto` (Node.js built-in)\n- `crypto-js`, `bcrypt`, `libsodium`, or any other third-party crypto libraries\n\n**✅ Only use:**\n- `window.crypto.subtle` and `window.crypto.getRandomValues`\n\n```ts\n// Example: AES-GCM encryption in the browser\nconst key = await crypto.subtle.generateKey(\n { name: 'AES-GCM', length: 256 },\n true,\n ['encrypt', 'decrypt']\n);\n\nconst iv = crypto.getRandomValues(new Uint8Array(12));\n\nconst encoded = new TextEncoder().encode('hello world');\nconst encrypted = await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv },\n key,\n encoded\n);\n````\n\n---\n\n## ✅ General API Rule\n\nYou must avoid Node.js-specific or third-party libraries. All implementations must be fully functional in **browser environments**, using **web-standard APIs** only.\n\n| Use Case | ❌ Do Not Use (Node.js / External) | ✅ Use Instead (Browser-safe) |\n| --------------- | ------------------------------------------------- | ------------------------------------------ |\n| UUID Generation | `uuid` package, `crypto.randomUUID()` (Node only) | `crypto.randomUUID()` (browser supported) |\n| HTTP Requests | `axios`, `node-fetch` | `fetch` |\n| Timing / Delay | `sleep-promise`, `delay` | `setTimeout`, `await new Promise(...)` |\n| Hashing | `crypto.createHash()` (Node.js) | `crypto.subtle.digest()` |\n| Compression | `zlib`, `adm-zip`, `archiver` | `CompressionStream`, `DecompressionStream` |\n| File Handling | `fs`, `fs-extra` | `File`, `Blob`, `FileReader`, `Streams` |\n\n---\n\n## 🧷 Summary\n\n* ✅ Use only APIs that work natively in **browsers**.\n* 🚫 Do not use Node.js-only modules or platform-specific packages.\n* ❌ Avoid third-party libraries unless there's **no equivalent** browser-native solution.\n* 🧭 If your logic must run both in Node.js and the browser, **the browser must always be the lowest common denominator**—ensure everything works in the browser first.\n\n\n# Date Type Error Resolution Rules\n\nYou are specialized in fixing Date-related TypeScript compilation errors in the codebase. These errors typically occur when native `Date` objects are incorrectly assigned to fields that expect `string & tags.Format<'date-time'>`.\n\n## Common Date Type Errors\n\n### Error Pattern 1: Direct Date Assignment\n```\nType 'Date' is not assignable to type 'string & Format<\"date-time\">'\n```\n\n### Error Pattern 2: Date Object in Return Values \n```\nType 'Date' is not assignable to type 'string & Format<\"date-time\">'\n```\n\n### Error Pattern 3: Nullable Date Assignment\n```\nType 'Date | null' is not assignable to type '(string & Format<\"date-time\">) | null | undefined'\n```\n\n### Error Pattern 4: Date Type Conversion Issues\n```\nConversion of type 'Date' to type 'string & Format<\"date-time\">' may be a mistake\n```\n\n### Error Pattern 5: Null to Date-Time String Conversion\n```\nConversion of type 'null' to type 'string & Format<\"date-time\">' may be a mistake\n```\n\n### Error Pattern 6: Field Property Existence Errors\n```\nObject literal may only specify known properties, and 'user_id' does not exist in type 'CreateInput'\nProperty 'field_name' does not exist on type 'UpdateInput'. Did you mean 'related_field'?\n```\n\n## Mandatory Resolution Rules\n\n### Rule 1: Never Use Native Date Objects\n**❌ NEVER do this:**\n```typescript\nconst data = {\n created_at: new Date(),\n updated_at: someDate,\n deleted_at: record.deleted_at, // if record.deleted_at is Date\n};\n```\n\n**✅ ALWAYS do this:**\n```typescript\nconst data = {\n created_at: new Date().toISOString(),\n updated_at: someDate.toISOString(),\n deleted_at: record.deleted_at?.toISOString() ?? null,\n};\n```\n\n### Rule 2: Convert All Date Fields in Data Objects\nWhen creating or updating records, ALL date fields must be converted:\n\n```typescript\n// Correct approach for create operations\nconst input = {\n id: v4() as string & tags.Format<'uuid'>,\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n deleted_at: body.deleted_at ? new Date(body.deleted_at).toISOString() : null,\n} satisfies SomeCreateInput;\n```\n\n### Rule 3: Convert Date Fields in Return Objects\nWhen returning data to API responses, ensure all date fields are strings:\n\n```typescript\n// Convert dates in return objects\nreturn {\n id: record.id,\n name: record.name,\n created_at: record.created_at, // Already string from Prisma\n updated_at: record.updated_at, // Already string from Prisma\n processed_at: processedDate.toISOString(), // Convert if Date object\n};\n```\n\n### Rule 4: Handle Nullable Dates Properly\nFor optional or nullable date fields:\n\n```typescript\n// Handle nullable dates\nconst data = {\n deleted_at: deletedDate ? deletedDate.toISOString() : null,\n expired_at: expiryDate?.toISOString() ?? undefined,\n};\n```\n\n### Rule 5: Type All Date Variables Correctly\nAlways type date variables as strings, not Date objects:\n\n```typescript\n// Correct typing\nconst now: string & tags.Format<'date-time'> = new Date().toISOString();\nconst createdAt: string & tags.Format<'date-time'> = record.created_at;\n\n// ❌ Never do this\nconst now: Date = new Date();\n```\n\n### Rule 6: Handle Null Values in Date Assignments\nWhen dealing with null values that need to be converted to date strings:\n\n```typescript\n// ✅ Proper null handling for date fields\nconst data = {\n deleted_at: deletedDate ? deletedDate.toISOString() : null,\n expired_at: expiry ? new Date(expiry).toISOString() : undefined,\n};\n\n// ❌ Never assign null directly to date-time fields expecting strings\nconst data = {\n deleted_at: null as string & tags.Format<'date-time'>, // Wrong!\n};\n```\n\n### Rule 7: Verify Field Existence Before Assignment\nAlways check if fields exist in the target type before assigning:\n\n```typescript\n// ✅ Check schema definition first, remove non-existent fields\nconst updateData = {\n // removed user_id because it doesn't exist in UpdateInput\n name: body.name,\n updated_at: new Date().toISOString(),\n} satisfies SomeUpdateInput;\n\n// ❌ Don't force assign non-existent fields\nconst updateData = {\n user_id: userId, // This field doesn't exist in the type!\n name: body.name,\n};\n```\n\n### Rule 8: Handle Relational Field Names Correctly\nWhen you see \"Did you mean\" errors, use the suggested field name:\n\n```typescript\n// ❌ Wrong field name\nconst data = {\n followed_user_id: userId,\n reporting_user_id: reporterId,\n};\n\n// ✅ Use correct relational field names\nconst data = {\n followed_user: { connect: { id: userId } },\n reporting_user: { connect: { id: reporterId } },\n};\n```\n\n## 🔧 Automatic Fixes for Specific Error Patterns\n\n### Fix Pattern 1: Property Assignment Errors\nWhen you see errors like:\n```\nProperty 'created_at' does not exist on type 'UpdateInput'\nProperty 'updated_at' does not exist on type 'UpdateInput' \nProperty 'deleted_at' does not exist on type 'UpdateInput'\n```\n\n**Resolution:**\n1. Check if the field actually exists in the type definition\n2. If it doesn't exist, remove the assignment\n3. If it exists but has wrong type, convert Date to string using `.toISOString()`\n\n### Fix Pattern 2: Object Literal Property Errors\nWhen you see:\n```\nObject literal may only specify known properties, and 'deleted_at' does not exist\n```\n\n**Resolution:**\n1. Verify the property exists in the target type\n2. If not, remove the property from the object literal\n3. If yes, ensure proper type conversion with `.toISOString()`\n\n### Fix Pattern 3: Return Type Mismatches\nWhen return objects have Date type mismatches:\n\n**Resolution:**\n```typescript\n// Convert all Date fields in responses\nreturn {\n ...otherFields,\n created_at: record.created_at, // Prisma already returns string\n updated_at: record.updated_at, // Prisma already returns string\n last_accessed: lastAccessTime.toISOString(), // Convert Date objects\n};\n```\n\n### Fix Pattern 4: Null Conversion Errors\nWhen you see:\n```\nConversion of type 'null' to type 'string & Format<\"date-time\">' may be a mistake\n```\n\n**Resolution:**\n```typescript\n// ✅ Proper null handling\nconst data = {\n deleted_at: deletedDate ? deletedDate.toISOString() : null,\n // OR use undefined if field is optional\n expired_at: expiryDate?.toISOString() ?? undefined,\n};\n\n// ❌ Don't force convert null\nconst data = {\n deleted_at: null as string & tags.Format<'date-time'>,\n};\n```\n\n### Fix Pattern 5: Field Name Mismatch Errors\nWhen you see \"Did you mean\" suggestions:\n```\nProperty 'followed_user_id' does not exist. Did you mean 'followed_user'?\nProperty 'reporting_user_id' does not exist. Did you mean 'reporting_user'?\n```\n\n**Resolution:**\n```typescript\n// ✅ Use relational connects instead of ID fields\nconst data = {\n followed_user: { connect: { id: parameters.id } },\n reporting_user: { connect: { id: user.id } },\n report: { connect: { id: body.report_id } },\n};\n\n// ❌ Don't use direct ID assignments for relations\nconst data = {\n followed_user_id: parameters.id,\n reporting_user_id: user.id,\n};\n```\n\n## 🎯 TransformRealizeCoderHistories Integration\n\nWhen fixing Date-related errors in the TransformRealizeCoderHistories process:\n\n1. **Identify all Date-related compilation errors** in the error list\n2. **Apply systematic conversion** using `.toISOString()` for all Date assignments\n3. **Verify field existence** in target types before assignment\n4. **Remove non-existent fields** rather than forcing assignments\n5. **Maintain type safety** by using `satisfies` with proper types\n\n## Critical Reminders\n\n- **NEVER use `as any` or type assertions** to bypass Date type errors\n- **ALWAYS convert Date objects to ISO strings** before assignment\n- **Prisma DateTime fields are stored as ISO strings**, not Date objects\n- **All date fields in API structures use `string & tags.Format<'date-time'>`**\n- **Handle nullable dates with proper null checking** using `?.toISOString() ?? null`\n\nThis systematic approach ensures that all Date-related TypeScript errors are resolved correctly while maintaining type safety and consistency across the codebase.\n\n# Typia Guide\n\nWhen defining validation rules for input or response structures using `typia`, you **must** utilize `tags` exclusively through the `tags` namespace provided by the `typia` module. This ensures strict type safety, clarity, and compatibility with automated code generation and schema extraction.\nFor example, to use `tags.Format<'uuid'>`, you must reference it as `tags.Format`, not simply `Format`.\n\n## ✅ Correct Usage Examples\n\n```ts\nexport interface IUser {\n username: string & tags.MinLength<3> & tags.MaxLength<20>;\n email: string & tags.Format<\"email\">;\n age: number & tags.Type<\"uint32\"> & tags.Minimum<18>;\n}\n```\n\n## ❌ Invalid Usage Examples\n\n```ts\nexport interface IUser {\n username: string & MinLength<3> & MaxLength<20>;\n email: string & Format<\"email\">;\n age: number & Type<\"uint32\"> & Minimum<18>;\n}\n```\n\n---\n\n## 🛡️ `typia.assert` vs `typia.assertGuard`\n\n`typia` provides two main runtime validation utilities: `assert` and `assertGuard`.\nBoth serve to validate runtime data against a TypeScript type, but their **behavior and return types differ**, which can influence which one to use depending on your use case.\n\n### 🔍 `typia.assert<T>(input): T`\n\n* Validates that `input` conforms to type `T`.\n* If invalid, throws a detailed exception.\n* **Returns** the parsed and validated input as type `T`.\n* Ideal when you want **to validate and use the result immediately**.\n\n**Example:**\n\n```ts\nconst user = typia.assert<IUser>(input); // user is of type IUser\n```\n\n---\n\n### 🧪 `typia.assertGuard<T>(input): void`\n\n* Validates that `input` conforms to type `T`.\n* If invalid, throws an exception like `assert`.\n* **Does not return anything** (`void` return type).\n* Acts like a **type guard** for the input **within the scope**.\n* Useful when you want to narrow the type **for subsequent logic**, but **don't need to reassign the value**.\n\n**Example:**\n\n```ts\ntypia.assertGuard<IUser>(input); // input is now treated as IUser\n\n// input can be used safely as IUser here\nconsole.log(input.username);\n```\n\n### 📎 Appendix – `assert` vs `assertGuard`\n\n```ts\n/**\n * Asserts a value type.\n *\n * Asserts a parametric value type and throws a {@link TypeGuardError} with detailed\n * reason, if the parametric value is not following the type `T`. Otherwise, the\n * value is following the type `T`, just input parameter would be returned.\n *\n * If what you want is not asserting but just knowing whether the parametric value is\n * following the type `T` or not, you can choose the {@link is} function instead.\n * Otherwise you want to know all the errors, {@link validate} is the way to go.\n * Also, if you want to automatically cast the parametric value to the type `T`\n * when no problem (perform the assertion guard of type).\n *\n * On the other and, if you don't want to allow any superfluous property that is not\n * enrolled to the type `T`, you can use {@link assertEquals} function instead.\n *\n * @template T Type of the input value\n * @param input A value to be asserted\n * @param errorFactory Custom error factory. Default is `TypeGuardError`\n * @returns Parametric input value\n * @throws A {@link TypeGuardError} instance with detailed reason\n *\n * @author Jeongho Nam - https://github.com/samchon\n */\nexport declare function assert<T>(input: T, errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error)): T;\n/**\n * Asserts a value type.\n *\n * Asserts a parametric value type and throws a {@link TypeGuardError} with detailed\n * reason, if the parametric value is not following the type `T`. Otherwise, the\n * value is following the type `T`, just input parameter would be returned.\n *\n * If what you want is not asserting but just knowing whether the parametric value is\n * following the type `T` or not, you can choose the {@link is} function instead.\n * Otherwise, you want to know all the errors, {@link validate} is the way to go.\n *\n * On the other and, if you don't want to allow any superfluous property that is not\n * enrolled to the type `T`, you can use {@link assertEquals} function instead.\n *\n * @template T Type of the input value\n * @param input A value to be asserted\n * @param errorFactory Custom error factory. Default is `TypeGuardError`\n * @returns Parametric input value casted as `T`\n * @throws A {@link TypeGuardError} instance with detailed reason\n *\n * @author Jeongho Nam - https://github.com/samchon\n */\nexport declare function assert<T>(input: unknown, errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error)): T;\n/**\n * Assertion guard of a value type.\n *\n * Asserts a parametric value type and throws a {@link TypeGuardError} with detailed\n * reason, if the parametric value is not following the type `T`. Otherwise, the\n * value is following the type `T`, nothing would be returned, but the input value\n * would be automatically casted to the type `T`. This is the concept of\n * \"Assertion Guard\" of a value type.\n *\n * If what you want is not asserting but just knowing whether the parametric value is\n * following the type `T` or not, you can choose the {@link is} function instead.\n * Otherwise you want to know all the errors, {@link validate} is the way to go.\n * Also, if you want to returns the parametric value when no problem, you can use\n * {@link assert} function instead.\n *\n * On the other and, if you don't want to allow any superfluous property that is not\n * enrolled to the type `T`, you can use {@link assertGuardEquals} function instead.\n *\n * @template T Type of the input value\n * @param input A value to be asserted\n * @param errorFactory Custom error factory. Default is `TypeGuardError`\n * @throws A {@link TypeGuardError} instance with detailed reason\n *\n * @author Jeongho Nam - https://github.com/samchon\n */\nexport declare function assertGuard<T>(input: T, errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error)): asserts input is T;\n/**\n * Assertion guard of a value type.\n *\n * Asserts a parametric value type and throws a {@link TypeGuardError} with detailed\n * reason, if the parametric value is not following the type `T`. Otherwise, the\n * value is following the type `T`, nothing would be returned, but the input value\n * would be automatically casted to the type `T`. This is the concept of\n * \"Assertion Guard\" of a value type.\n *\n * If what you want is not asserting but just knowing whether the parametric value is\n * following the type `T` or not, you can choose the {@link is} function instead.\n * Otherwise you want to know all the errors, {@link validate} is the way to go.\n * Also, if you want to returns the parametric value when no problem, you can use\n * {@link assert} function instead.\n *\n * On the other and, if you don't want to allow any superfluous property that is not\n * enrolled to the type `T`, you can use {@link assertGuardEquals} function instead.\n *\n * @template T Type of the input value\n * @param input A value to be asserted\n * @param errorFactory Custom error factory. Default is `TypeGuardError`\n * @throws A {@link TypeGuardError} instance with detailed reason\n *\n * @author Jeongho Nam - https://github.com/samchon\n */\nexport declare function assertGuard<T>(input: unknown, errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error)): asserts input is T;\n\n```\n\n### Handling Typia Assertion Errors for JsonSchemaPlugin Format Mismatches\n\n- These errors occur because a value typed as `number & Type<\"int32\">` is being assigned where `number & Type<\"int32\"> & typia.tags.JsonSchemaPlugin<{ format: \"uint32\" }>` is expected.\n- The root cause is a mismatch between signed (`int32`) and unsigned (`uint32`) integer formats.\n- To resolve these, use **typia.tags.assert** to explicitly assert or validate the value conforms to the expected `uint32` format.\n- Example:\n\n```ts\nconst value = getValue(); // type: number & tags.Type<\"int32\">\n\ntags.assert<number & tags.Type<\"int32\"> & tags.JsonSchemaPlugin<{ format: \"uint32\" }>>(value);\n\n// Now `value` is guaranteed to conform to the expected unsigned 32-bit integer type.\n```\n\n* Always use typia.tags' `assert` or related functions for runtime validation and to satisfy TypeScript's type checker.\n* This approach ensures type safety without compromising runtime correctness.\n\n---\n\n### ✅ Summary: Which Should I Use?\n\n| Use Case | Recommended API |\n| ------------------------------------ | ------------------------ |\n| Validate and return typed value | `typia.assert<T>()` |\n| Narrow type without reassigning | `typia.assertGuard<T>()` |\n| Use validated object directly | `typia.assert<T>()` |\n| Use input inside a conditional block | `typia.assertGuard<T>()` |\n\n> **Note:** Since `assertGuard` returns `void`, if you need **both type narrowing and a returned value**, `assert` is the better choice.\n\n---\n\n## 🏷️ Typia Tags Declaration – Explanation & Usage Guide\n\nYou can use the following tags from Typia to annotate your types for additional semantic meaning, validation constraints, or schema generation.\n\n| Tag | Purpose |\n| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `Constant` | Enforces the value to be a specific constant. Useful for literal values.<br>→ `string & tags.Constant<'active'>` |\n| `ContentMediaType` | Specifies the media type of content (e.g., `application/json`, `text/plain`). |\n| `Default` | Declares a default value to be used when the field is not provided.<br>**Note:** This is a schema-level hint, not runtime logic. |\n| `Example` | Declares a single example value to help with documentation tools like Swagger. |\n| `Examples` | Declares multiple example values. |\n| `ExclusiveMaximum` | Similar to `Maximum`, but the value must be **strictly less than** the given limit. |\n| `ExclusiveMinimum` | Similar to `Minimum`, but the value must be **strictly greater than** the given limit. |\n| `Format` | Specifies a semantic format for a value, such as:<br>→ `email`, `uuid`, `date-time`, `url`, etc.<br>✅ Used heavily across our codebase.<br>e.g., `string & tags.Format<'uuid'>` |\n| `JsonSchemaPlugin` | Allows adding plugin-specific schema behaviors. Rarely needed. |\n| `Maximum` | Specifies the maximum value (inclusive) for a number.<br>e.g., `number & tags.Maximum<100>` |\n| `MaxItems` | Specifies the maximum number of elements in an array. |\n| `MaxLength` | Specifies the maximum string length.<br>e.g., `string & tags.MaxLength<50>` |\n| `Minimum` | Specifies the minimum value (inclusive) for a number. |\n| `MinItems` | Specifies the minimum number of array items. |\n| `MinLength` | Specifies the minimum string length. |\n| `MultipleOf` | The value must be a multiple of the given number.<br>e.g., `number & tags.MultipleOf<5>` |\n| `Pattern` | Applies a regular expression pattern to a string.<br>e.g., `string & tags.Pattern<'^[a-z]+>` |\n| `Sequence` | Used for sequential fields like auto-incrementing IDs. |\n| `TagBase` | Internal utility tag – typically not used directly. |\n| `Type` | Used to enforce a type name in JSON Schema generation. |\n| `UniqueItems` | Ensures all elements in an array are unique. |\n\n---\n\n### ✅ Examples\n\n```ts\ntype UserId = string & tags.Format<'uuid'>;\ntype LimitedString = string & tags.MinLength<5> & tags.MaxLength<20>;\ntype SmallNumber = number & tags.Minimum<1> & tags.Maximum<10>;\ntype ConstantStatus = string & tags.Constant<'active'>;\ntype Email = string & tags.Format<'email'>;\n```\n\n---\n\n### 🔒 Typia Tag Usage Notes\n\n* Tags are used at the **type level**, not runtime.\n* They are especially useful when:\n\n * Generating OpenAPI / Swagger schemas\n * Enforcing validation contracts across API boundaries\n * Using `typia.assert`, `typia.validate`, or `typia.random`\n\n> ⚠️ **Never use these tags directly for logic branching in code.** They are strictly for static type and schema purposes."
6817
7395
  }, {
6818
7396
  id: v4(),
6819
7397
  created_at: (new Date).toISOString(),
6820
7398
  type: "systemMessage",
6821
- text: "# Prisma Guide\n\n## 🔍 Prisma Update Input Type Safety Guide\n\nWhen implementing an update operation using `Prisma.update()`, you **must strictly follow these rules** to avoid `TS2322` or structural type errors.\n\nThis section guides you through **a checklist**, provides **clear rationale**, and includes **copyable safe patterns** for high accuracy and minimal confusion — for both human developers and LLMs.\n\n---\n\n### Why Type Errors Occur\n\nTypeScript error `TS2322` usually occurs because:\n\n1. You **manually defined** an object type for `data` instead of using the Prisma-generated input type.\n2. You **assigned `null`** to a field that is not nullable in the Prisma schema.\n3. You **used DTO types** (e.g., `IBbsUserRoles`) instead of the Prisma model update type.\n4. You **assigned values to optional fields** without checking ownership or value type.\n\n---\n\n### ✅ Step-by-Step Checklist Before You Call `update()`\n\n#### ✅ 1. Always use Prisma's update input type\n\n**DO:**\n\n```ts\nconst data: Prisma.User_rolesUpdateInput = {};\n```\n\n**DON'T:**\n\n```ts\nconst data: { name?: string | null } = {}; // ❌ will not match Prisma's input type\n```\n\n---\n\n#### 2. Use `?? undefined` to cleanly normalize nullable/optional inputs\n\nIf a field is `nullable`, use:\n\n```ts\ndata.description = body.description ?? undefined;\n```\n\nIf a field is **required** but **not provided**, **omit** it — do not assign `null`.\n\n---\n\n#### 3. Use `hasOwnProperty` to detect explicit field presence\n\n```ts\nif (Object.prototype.hasOwnProperty.call(body, \"name\")) {\n data.name = body.name ?? undefined;\n}\n```\n\n> ⚠️ This is essential to distinguish between:\n>\n> * `{ name: undefined }` (intentional update)\n> * `{}` (field not provided at all)\n\n---\n\n#### 4. Never use DTO types (`IBbs...`) for `data`\n\nDTO types are for API input/output, **not internal DB operations**. Prisma input types (like `Prisma.User_rolesUpdateInput`) should always be used for database writes.\n\n---\n\n#### 5. Use TypeScript’s narrowing, never bypass with `as`\n\nNever try:\n\n```ts\nconst data = {...} as any; // extremely dangerous\n```\n\nOnly acceptable `as` use:\n\n```ts\nconst uuid = v4() as string & tags.Format<'uuid'>;\n```\n\n---\n\n### 💡 Copyable Safe Pattern\n\n```ts\nconst data: Prisma.User_rolesUpdateInput = {};\nif (\"name\" in body) data.name = body.name ?? undefined;\nif (\"description\" in body) data.description = body.description ?? undefined;\n```\n\n> 🧠 This avoids errors by:\n>\n> * Using the exact type expected by Prisma\n> * Avoiding `null` on non-nullable fields\n> * Treating `undefined` as “do not update”\n\n---\n\n### Common Pitfalls and Fixes\n\n| ❌ Bad Practice | ✅ Fix |\n| ---------------------------------------- | --------------------------------------- |\n| Manually define `data` as inline object | Use `Prisma.ModelUpdateInput` |\n| Assign `null` to non-nullable fields | Use `?? undefined` or omit |\n| Use DTOs like `IBbsUserRoles` for update | Only use DTOs for API input/output |\n| Assign `data = body` directly | Extract and normalize fields explicitly |\n\n---\n\n### ✅ Rule of Thumb\n\n> **If you're passing `data` into Prisma, it must be type-compatible with `Prisma.ModelUpdateInput` no exceptions.**\n\n---\n\n### 📎 TL;DR for Agent or Developer\n\n1. Always use `Prisma.ModelUpdateInput` as the type.\n2. Use `?? undefined` to normalize input.\n3. Use `hasOwnProperty` to detect intent.\n4. Don’t use `null` unless the schema allows it.\n5. Never use DTO types for `data`."
6822
- }, {
6823
- id: v4(),
6824
- created_at: (new Date).toISOString(),
6825
- type: "systemMessage",
6826
- text: "## 🔐 Browser-Compatible Native-First Rule\n\nYou must implement all functionality using **only browser-compatible native features** whenever possible. \nAll logic must assume it will run in a browser environment — even if Node.js is also supported.\n\n> 🚫 Do **not** use Node.js-only modules like `'crypto'`, `'fs'`, `'path'`, etc.\n> ✅ Always use **Web-standard, browser-safe APIs**.\n\n---\n\n### ✅ Encryption Rule\n\nAll encryption and decryption must be implemented using the **Web Crypto API (`window.crypto.subtle`)**.\n\n**❌ Do not use:**\n- `crypto` (Node.js built-in)\n- `crypto-js`, `bcrypt`, `libsodium`, or any other third-party crypto libraries\n\n**✅ Only use:**\n- `window.crypto.subtle` and `window.crypto.getRandomValues`\n\n```ts\n// Example: AES-GCM encryption in the browser\nconst key = await crypto.subtle.generateKey(\n { name: 'AES-GCM', length: 256 },\n true,\n ['encrypt', 'decrypt']\n);\n\nconst iv = crypto.getRandomValues(new Uint8Array(12));\n\nconst encoded = new TextEncoder().encode('hello world');\nconst encrypted = await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv },\n key,\n encoded\n);\n````\n\n---\n\n### ✅ General API Rule\n\nYou must avoid Node.js-specific or third-party libraries. All implementations must be fully functional in **browser environments**, using **web-standard APIs** only.\n\n| Use Case | ❌ Do Not Use (Node.js / External) | ✅ Use Instead (Browser-safe) |\n| --------------- | ------------------------------------------------- | ------------------------------------------ |\n| UUID Generation | `uuid` package, `crypto.randomUUID()` (Node only) | `crypto.randomUUID()` (browser supported) |\n| HTTP Requests | `axios`, `node-fetch` | `fetch` |\n| Timing / Delay | `sleep-promise`, `delay` | `setTimeout`, `await new Promise(...)` |\n| Hashing | `crypto.createHash()` (Node.js) | `crypto.subtle.digest()` |\n| Compression | `zlib`, `adm-zip`, `archiver` | `CompressionStream`, `DecompressionStream` |\n| File Handling | `fs`, `fs-extra` | `File`, `Blob`, `FileReader`, `Streams` |\n\n---\n\n### 🧷 Summary\n\n* ✅ Use only APIs that work natively in **browsers**.\n* 🚫 Do not use Node.js-only modules or platform-specific packages.\n* ❌ Avoid third-party libraries unless there's **no equivalent** browser-native solution.\n* 🧭 If your logic must run both in Node.js and the browser, **the browser must always be the lowest common denominator**—ensure everything works in the browser first."
6827
- }, {
6828
- id: v4(),
6829
- created_at: (new Date).toISOString(),
6830
- type: "systemMessage",
6831
- text: '# Typia Guide\n\nWhen defining validation rules for input or response structures using `typia`, you **must** utilize `tags` exclusively through the `tags` namespace provided by the `typia` module. This ensures strict type safety, clarity, and compatibility with automated code generation and schema extraction.\nFor example, to use `tags.Format<\'uuid\'>`, you must reference it as `tags.Format`, not simply `Format`.\n\n## ✅ Correct Usage Examples\n\n```ts\nexport interface IUser {\n username: string & tags.MinLength<3> & tags.MaxLength<20>;\n email: string & tags.Format<"email">;\n age: number & tags.Type<"uint32"> & tags.Minimum<18>;\n}\n```\n\n## ❌ Invalid Usage Examples\n\n```ts\nexport interface IUser {\n username: string & MinLength<3> & MaxLength<20>;\n email: string & Format<"email">;\n age: number & Type<"uint32"> & Minimum<18>;\n}\n```\n\n---\n\n## 🛡️ `typia.assert` vs `typia.assertGuard`\n\n`typia` provides two main runtime validation utilities: `assert` and `assertGuard`.\nBoth serve to validate runtime data against a TypeScript type, but their **behavior and return types differ**, which can influence which one to use depending on your use case.\n\n### 🔍 `typia.assert<T>(input): T`\n\n* Validates that `input` conforms to type `T`.\n* If invalid, throws a detailed exception.\n* **Returns** the parsed and validated input as type `T`.\n* Ideal when you want **to validate and use the result immediately**.\n\n**Example:**\n\n```ts\nconst user = typia.assert<IUser>(input); // user is of type IUser\n```\n\n---\n\n### 🧪 `typia.assertGuard<T>(input): void`\n\n* Validates that `input` conforms to type `T`.\n* If invalid, throws an exception like `assert`.\n* **Does not return anything** (`void` return type).\n* Acts like a **type guard** for the input **within the scope**.\n* Useful when you want to narrow the type **for subsequent logic**, but **don\'t need to reassign the value**.\n\n**Example:**\n\n```ts\ntypia.assertGuard<IUser>(input); // input is now treated as IUser\n\n// input can be used safely as IUser here\nconsole.log(input.username);\n```\n\n### 📎 Appendix – `assert` vs `assertGuard`\n\n```ts\n/**\n * Asserts a value type.\n *\n * Asserts a parametric value type and throws a {@link TypeGuardError} with detailed\n * reason, if the parametric value is not following the type `T`. Otherwise, the\n * value is following the type `T`, just input parameter would be returned.\n *\n * If what you want is not asserting but just knowing whether the parametric value is\n * following the type `T` or not, you can choose the {@link is} function instead.\n * Otherwise you want to know all the errors, {@link validate} is the way to go.\n * Also, if you want to automatically cast the parametric value to the type `T`\n * when no problem (perform the assertion guard of type).\n *\n * On the other and, if you don\'t want to allow any superfluous property that is not\n * enrolled to the type `T`, you can use {@link assertEquals} function instead.\n *\n * @template T Type of the input value\n * @param input A value to be asserted\n * @param errorFactory Custom error factory. Default is `TypeGuardError`\n * @returns Parametric input value\n * @throws A {@link TypeGuardError} instance with detailed reason\n *\n * @author Jeongho Nam - https://github.com/samchon\n */\nexport declare function assert<T>(input: T, errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error)): T;\n/**\n * Asserts a value type.\n *\n * Asserts a parametric value type and throws a {@link TypeGuardError} with detailed\n * reason, if the parametric value is not following the type `T`. Otherwise, the\n * value is following the type `T`, just input parameter would be returned.\n *\n * If what you want is not asserting but just knowing whether the parametric value is\n * following the type `T` or not, you can choose the {@link is} function instead.\n * Otherwise, you want to know all the errors, {@link validate} is the way to go.\n *\n * On the other and, if you don\'t want to allow any superfluous property that is not\n * enrolled to the type `T`, you can use {@link assertEquals} function instead.\n *\n * @template T Type of the input value\n * @param input A value to be asserted\n * @param errorFactory Custom error factory. Default is `TypeGuardError`\n * @returns Parametric input value casted as `T`\n * @throws A {@link TypeGuardError} instance with detailed reason\n *\n * @author Jeongho Nam - https://github.com/samchon\n */\nexport declare function assert<T>(input: unknown, errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error)): T;\n/**\n * Assertion guard of a value type.\n *\n * Asserts a parametric value type and throws a {@link TypeGuardError} with detailed\n * reason, if the parametric value is not following the type `T`. Otherwise, the\n * value is following the type `T`, nothing would be returned, but the input value\n * would be automatically casted to the type `T`. This is the concept of\n * "Assertion Guard" of a value type.\n *\n * If what you want is not asserting but just knowing whether the parametric value is\n * following the type `T` or not, you can choose the {@link is} function instead.\n * Otherwise you want to know all the errors, {@link validate} is the way to go.\n * Also, if you want to returns the parametric value when no problem, you can use\n * {@link assert} function instead.\n *\n * On the other and, if you don\'t want to allow any superfluous property that is not\n * enrolled to the type `T`, you can use {@link assertGuardEquals} function instead.\n *\n * @template T Type of the input value\n * @param input A value to be asserted\n * @param errorFactory Custom error factory. Default is `TypeGuardError`\n * @throws A {@link TypeGuardError} instance with detailed reason\n *\n * @author Jeongho Nam - https://github.com/samchon\n */\nexport declare function assertGuard<T>(input: T, errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error)): asserts input is T;\n/**\n * Assertion guard of a value type.\n *\n * Asserts a parametric value type and throws a {@link TypeGuardError} with detailed\n * reason, if the parametric value is not following the type `T`. Otherwise, the\n * value is following the type `T`, nothing would be returned, but the input value\n * would be automatically casted to the type `T`. This is the concept of\n * "Assertion Guard" of a value type.\n *\n * If what you want is not asserting but just knowing whether the parametric value is\n * following the type `T` or not, you can choose the {@link is} function instead.\n * Otherwise you want to know all the errors, {@link validate} is the way to go.\n * Also, if you want to returns the parametric value when no problem, you can use\n * {@link assert} function instead.\n *\n * On the other and, if you don\'t want to allow any superfluous property that is not\n * enrolled to the type `T`, you can use {@link assertGuardEquals} function instead.\n *\n * @template T Type of the input value\n * @param input A value to be asserted\n * @param errorFactory Custom error factory. Default is `TypeGuardError`\n * @throws A {@link TypeGuardError} instance with detailed reason\n *\n * @author Jeongho Nam - https://github.com/samchon\n */\nexport declare function assertGuard<T>(input: unknown, errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error)): asserts input is T;\n\n```\n\n### Handling Typia Assertion Errors for JsonSchemaPlugin Format Mismatches\n\n- These errors occur because a value typed as `number & Type<"int32">` is being assigned where `number & Type<"int32"> & typia.tags.JsonSchemaPlugin<{ format: "uint32" }>` is expected.\n- The root cause is a mismatch between signed (`int32`) and unsigned (`uint32`) integer formats.\n- To resolve these, use **typia.tags.assert** to explicitly assert or validate the value conforms to the expected `uint32` format.\n- Example:\n\n```ts\nconst value = getValue(); // type: number & tags.Type<"int32">\n\ntags.assert<number & tags.Type<"int32"> & tags.JsonSchemaPlugin<{ format: "uint32" }>>(value);\n\n// Now `value` is guaranteed to conform to the expected unsigned 32-bit integer type.\n```\n\n* Always use typia.tags’ `assert` or related functions for runtime validation and to satisfy TypeScript’s type checker.\n* This approach ensures type safety without compromising runtime correctness.\n\n---\n\n### ✅ Summary: Which Should I Use?\n\n| Use Case | Recommended API |\n| ------------------------------------ | ------------------------ |\n| Validate and return typed value | `typia.assert<T>()` |\n| Narrow type without reassigning | `typia.assertGuard<T>()` |\n| Use validated object directly | `typia.assert<T>()` |\n| Use input inside a conditional block | `typia.assertGuard<T>()` |\n\n> **Note:** Since `assertGuard` returns `void`, if you need **both type narrowing and a returned value**, `assert` is the better choice.\n\n---\n\n## 🏷️ Typia Tags Declaration – Explanation & Usage Guide\n\nYou can use the following tags from Typia to annotate your types for additional semantic meaning, validation constraints, or schema generation.\n\n| Tag | Purpose |\n| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `Constant` | Enforces the value to be a specific constant. Useful for literal values.<br>→ `string & tags.Constant<\'active\'>` |\n| `ContentMediaType` | Specifies the media type of content (e.g., `application/json`, `text/plain`). |\n| `Default` | Declares a default value to be used when the field is not provided.<br>**Note:** This is a schema-level hint, not runtime logic. |\n| `Example` | Declares a single example value to help with documentation tools like Swagger. |\n| `Examples` | Declares multiple example values. |\n| `ExclusiveMaximum` | Similar to `Maximum`, but the value must be **strictly less than** the given limit. |\n| `ExclusiveMinimum` | Similar to `Minimum`, but the value must be **strictly greater than** the given limit. |\n| `Format` | Specifies a semantic format for a value, such as:<br>→ `email`, `uuid`, `date-time`, `url`, etc.<br>✅ Used heavily across our codebase.<br>e.g., `string & tags.Format<\'uuid\'>` |\n| `JsonSchemaPlugin` | Allows adding plugin-specific schema behaviors. Rarely needed. |\n| `Maximum` | Specifies the maximum value (inclusive) for a number.<br>e.g., `number & tags.Maximum<100>` |\n| `MaxItems` | Specifies the maximum number of elements in an array. |\n| `MaxLength` | Specifies the maximum string length.<br>e.g., `string & tags.MaxLength<50>` |\n| `Minimum` | Specifies the minimum value (inclusive) for a number. |\n| `MinItems` | Specifies the minimum number of array items. |\n| `MinLength` | Specifies the minimum string length. |\n| `MultipleOf` | The value must be a multiple of the given number.<br>e.g., `number & tags.MultipleOf<5>` |\n| `Pattern` | Applies a regular expression pattern to a string.<br>e.g., `string & tags.Pattern<\'^[a-z]+$\'>` |\n| `Sequence` | Used for sequential fields like auto-incrementing IDs. |\n| `TagBase` | Internal utility tag – typically not used directly. |\n| `Type` | Used to enforce a type name in JSON Schema generation. |\n| `UniqueItems` | Ensures all elements in an array are unique. |\n\n---\n\n### ✅ Examples\n\n```ts\ntype UserId = string & tags.Format<\'uuid\'>;\ntype LimitedString = string & tags.MinLength<5> & tags.MaxLength<20>;\ntype SmallNumber = number & tags.Minimum<1> & tags.Maximum<10>;\ntype ConstantStatus = string & tags.Constant<\'active\'>;\ntype Email = string & tags.Format<\'email\'>;\n```\n\n---\n\n### 🔒 Typia Tag Usage Notes\n\n* Tags are used at the **type level**, not runtime.\n* They are especially useful when:\n\n * Generating OpenAPI / Swagger schemas\n * Enforcing validation contracts across API boundaries\n * Using `typia.assert`, `typia.validate`, or `typia.random`\n\n> ⚠️ **Never use these tags directly for logic branching in code.** They are strictly for static type and schema purposes.'
6832
- }, {
6833
- id: v4(),
6834
- created_at: (new Date).toISOString(),
6835
- type: "systemMessage",
6836
- text: "# Prisma Schemas\n```json\n{prisma_schemas}\n```\n# ℹ️ How to Use the Above Prisma Schemas\n- These Prisma schemas are extracted from your actual `schema.prisma` file.\n- You must always consult the schema when writing any `update`, `create`, or `select` logic.\n- Pay special attention to:\n 1. **Which fields are required, optional, or nullable**\n 2. **Which fields are scalar vs. relation fields** (e.g., `role_id` vs. `role`)\n 3. **Which fields can be updated directly** (scalar fields) vs. **indirectly** (via `connect`, `disconnect`, `set` in nested relation objects)\n- For relation fields like `user_role_id`, do not assign it directly — instead, use the relation name (e.g., `role: { connect: { id: ... } }`).\n- The type definitions generated by Prisma (e.g., `Prisma.UserUpdateInput`) are based directly on this schema — they **exclude computed/derived fields** and may treat relations differently.\n- When in doubt, cross-reference your assignment logic with this schema to avoid `TS2322`, `TS2339`, and other structural typing errors.\n- ❗Never assume a field exists in the update input just because it appears in the model. Some fields are only present in `createInput`, or must be updated through relations.\n\n# SDK\n\nThe following is the SDK for the API. Based on the information provided by this SDK, you must write code that maps the SDK-provided parameters directly into the `parameters` and `body` properties of the provider function response.\nIf there are no parameters, define `parameters` as `Record<string, never>`. Similarly, if there is no body, define `body` as `Record<string, never>`.\n**Every function must be implemented to accept both `parameters` and `body`, without exception.**\nIf any required type information is referenced in the SDK, refer to the definitions in the DTO section.\n\n```json\n{artifacts_sdk}\n```\n\n# DTO\nif you want to import this files, write this: 'import { something } from '../api/structures/something';'\n\n```json\n{artifacts_dto}\n```\n# Document\n```json\n{artifacts_document}\n```".replaceAll(`{prisma_schemas}`, JSON.stringify(state.prisma.schemas)).replaceAll(`{artifacts_sdk}`, JSON.stringify(artifacts.sdk)).replaceAll(`{artifacts_dto}`, JSON.stringify(artifacts.dto)).replaceAll(`{artifacts_document}`, JSON.stringify(artifacts.document))
7399
+ text: "# Prisma Schemas\n```json\n{prisma_schemas}\n```\n# ℹ️ How to Use the Above Prisma Schemas\n- These Prisma schemas are extracted from your actual `schema.prisma` file.\n- You must always consult the schema when writing any `update`, `create`, or `select` logic.\n- Pay special attention to:\n 1. **Which fields are required, optional, or nullable**\n 2. **Which fields are scalar vs. relation fields** (e.g., `role_id` vs. `role`)\n 3. **Which fields can be updated directly** (scalar fields) vs. **indirectly** (via `connect`, `disconnect`, `set` in nested relation objects)\n- For relation fields like `user_role_id`, do not assign it directly instead, use the relation name (e.g., `role: { connect: { id: ... } }`).\n- The type definitions generated by Prisma (e.g., `Prisma.UserUpdateInput`) are based directly on this schema they **exclude computed/derived fields** and may treat relations differently.\n- When in doubt, cross-reference your assignment logic with this schema to avoid `TS2322`, `TS2339`, and other structural typing errors.\n- ❗Never assume a field exists in the update input just because it appears in the model. Some fields are only present in `createInput`, or must be updated through relations.\n\n# SDK\n\nThe following is the SDK for the API. Based on the information provided by this SDK, you must write code that maps the SDK-provided parameters directly into the `parameters` and `body` properties of the provider function response.\nIf there are no parameters, define `parameters` as `Record<string, never>`. Similarly, if there is no body, define `body` as `Record<string, never>`.\n**Every function must be implemented to accept both `parameters` and `body`, without exception.**\nIf any required type information is referenced in the SDK, refer to the definitions in the DTO section.\n\n```json\n{artifacts_sdk}\n```\n\n# DTO\nif you want to import this files, write this: 'import { something } from '../api/structures/something';'\n\n```json\n{artifacts_dto}\n```\n# Document\n```json\n{artifacts_document}\n```".replaceAll(`{prisma_schemas}`, JSON.stringify(state.prisma.schemas)).replaceAll(`{artifacts_sdk}`, JSON.stringify(artifacts.sdk)).replaceAll(`{artifacts_dto}`, JSON.stringify(artifacts.dto))
6837
7400
  }, ...previous !== null ? [ {
6838
7401
  id: v4(),
6839
7402
  created_at: (new Date).toISOString(),
6840
7403
  type: "assistantMessage",
6841
- text: "The code you previously wrote is as follows:\n```typescript\n{code}\n```\n\n```json\n{total_diagnostics}\n```\n\nThe list above shows all known errors.\nYou are currently editing the code, and based on your changes, the errors from this attempt are as follows:\n```json\n{current_diagnostics}\n```\n\n💡 Note:\n- If an error appears **only in the current errors** and not in the full list above, it is a **newly introduced error**.\n- If an error appears **only in the full list** and not in the current errors, it means it has been **fixed**.\n\n💡 **Tip Regarding Date Type Errors**\n\nIf you encounter errors related to the `Date` type, a common fix is to call the `.toISOString()` method on the `Date` object and treat it as a `string`.\nThis approach resolves most type-related issues.\nPlease note that in our defined types—especially in properties involving dates—and in all `Date` or `DateTime` fields from Prisma,\n**dates must be handled as `string` values**, not as native `Date` objects.\nAlways ensure date values conform to the expected format:\n\n```ts\nstring & tags.Format<'date-time'>\n```\n\n```ts\n// If there is some Date type property...\nDateProp.toISOString(); // GOOD!\nDateProp as string; // BAD!\n```".replaceAll(`{code}`, previous).replaceAll("{total_diagnostics}", JSON.stringify(total)).replaceAll("{current_diagnostics}", JSON.stringify(diagnostics))
7404
+ text: "# List of compilation errors in this file\n\nYou are currently editing the code, and based on your changes, the errors from this attempt are as follows:\n\n```json\n{current_diagnostics}\n```\n\n💡 Note:\n- If an error appears **only in the current errors** and not in the full list above, it is a **newly introduced error**.\n- If an error appears **only in the full list** and not in the current errors, it means it has been **fixed**.\n\n💡 **Tip Regarding Date Type Errors**\n\nIf you encounter errors related to the `Date` type, a common fix is to call the `.toISOString()` method on the `Date` object and treat it as a `string`.\nThis approach resolves most type-related issues.\nPlease note that in our defined types—especially in properties involving dates—and in all `Date` or `DateTime` fields from Prisma,\n**dates must be handled as `string` values**, not as native `Date` objects.\nAlways ensure date values conform to the expected format:\n\n```ts\nstring & tags.Format<'date-time'>\n```\n\n```ts\n// If there is some Date type property...\nDateProp.toISOString(); // GOOD!\nDateProp as string; // BAD!\n```".replaceAll(`{code}`, previous).replaceAll("{current_diagnostics}", JSON.stringify(diagnostics))
6842
7405
  } ] : [], {
6843
7406
  id: v4(),
6844
7407
  created_at: (new Date).toISOString(),
6845
7408
  type: "systemMessage",
6846
7409
  text: [ previous ? "Modify the previous code to reflect the following operation." : "Write new code based on the following operation.", "```json", JSON.stringify(props), "```" ].join("\n")
7410
+ }, {
7411
+ id: v4(),
7412
+ created_at: (new Date).toISOString(),
7413
+ type: "assistantMessage",
7414
+ text: [ `I understand your request.`, ``, `To summarize:`, `- I must **never use the native \`Date\` type** in any code or type definitions.`, `- Instead, all date and datetime values must be handled as \`string & tags.Format<'date-time'>\`.`, `- This rule is **strict** and applies everywhere, including domain types, API inputs/outputs, and Prisma models.`, `- Even if a library or tool returns a \`Date\`, I must convert it to the correct string format before use.`, ``, `Especially regarding the \`Date\` type: I understand that using it can lead to type inconsistency and runtime issues, so I will completely avoid it in all circumstances.`, ``, `I'll make sure to follow all these rules strictly. Let’s proceed with this in mind.` ].join("\n")
6847
7415
  } ];
6848
7416
  };
6849
7417
 
@@ -6870,16 +7438,18 @@ const orchestrateRealizeCoder = async (ctx, operation, props, previous, total, d
6870
7438
  vendor: ctx.vendor,
6871
7439
  config: {
6872
7440
  ...ctx.config,
7441
+ backoffStrategy: randomBackoffStrategy,
6873
7442
  executor: {
6874
7443
  describe: null
6875
7444
  }
6876
7445
  },
6877
- histories: transformRealizeCoderHistories(ctx.state(), props, artifacts, previous, total, diagnostics)
7446
+ histories: transformRealizeCoderHistories(ctx.state(), props, artifacts, previous, diagnostics)
6878
7447
  });
6879
7448
  enforceToolCall(agent);
6880
- await agent.conversate("Write code.");
6881
- const tokenUsage = agent.getTokenUsage();
6882
- ctx.usage().record(tokenUsage, [ "realize" ]);
7449
+ await randomBackoffRetry((() => agent.conversate([ `Write complete, production-ready TypeScript code that strictly follows these rules:`, "", `1. Do **not** use the native \`Date\` type anywhere.`, `2. All date or datetime values must be written as \`string & tags.Format<'date-time'>\`.`, `3. UUIDs must be generated using \`v4()\` and typed as \`string & tags.Format<'uuid'>\`.`, `4. Do not use \`as\` for type assertions — resolve types properly.`, `5. All functions must be fully typed with clear parameter and return types.`, `6. Do not skip validations or default values where necessary.`, `7. Follow functional, immutable, and consistent code structure.`, "", `Use \`@nestia/e2e\` test structure if relevant.` ].join("\n")))).finally((() => {
7450
+ const tokenUsage = agent.getTokenUsage();
7451
+ ctx.usage().record(tokenUsage, [ "realize" ]);
7452
+ }));
6883
7453
  if (pointer.value === null) {
6884
7454
  return FAILED;
6885
7455
  }
@@ -6940,11 +7510,14 @@ const claude$4 = {
6940
7510
  type: "object",
6941
7511
  properties: {
6942
7512
  filename: {
6943
- description: 'The name of the file to be generated (e.g., "user.create.ts")',
6944
7513
  type: "string"
6945
7514
  },
6946
7515
  plan: {
6947
- description: "🧠 Provider Function Implementation Plan\n\nThis field outlines the strategic plan for implementing the provider\nfunction according to the Realize Coder Agent specification. Before\nwriting the actual code, think through the logic and structure.\n\nThe plan must consider:\n\n- 🧩 Required business entities (e.g., users, posts, logs) and their\n relationships\n- 🛠 Operations needed to fulfill the business scenario (e.g., fetch,\n create, update)\n- 🔄 Data dependencies between steps (e.g., use userId to fetch related\n data)\n- ✅ Validation points (based on business rules, not field presence)\n- 🚧 Error and edge cases that must be handled explicitly (e.g., missing\n records)\n- 🏗 Structure: always a single `async function`, using only `parameters`\n and `body`\n\n⚠️ Important Constraints:\n\n- Do NOT perform input validation — assume `parameters` and `body` are\n already valid\n- Use `typia.random<T>()` with an explanatory comment if logic can't be\n implemented\n- Never use `any` or make assumptions without sufficient context\n- Use only allowed imports — DTOs and Prisma types\n- Use `MyGlobal.prisma` for DB access and respect Prisma typing rules\n\n⚠️ TypeScript-specific considerations:\n\n- Do **not** use native `Date` objects directly; convert all dates with\n `.toISOString()`\n- Use `string & tags.Format<'date-time'>` for all date/time typed fields\n- Prefer `satisfies` for DTO conformance instead of unsafe `as` casts\n- Avoid weak typing such as `any`, `as any`, or `satisfies any`\n- Use branded types (e.g., `tags.Format<'uuid'>`) and literal unions where\n applicable\n\n✅ Example Structure:\n\n```ts\nexport async function doSomething(\n user: { id: string & tags.Format<\"uuid\">; type: string },\n parameters: IParams,\n body: IBody\n): Promise<IReturn> {\n const { id } = parameters;\n const { name } = body;\n const user = await MyGlobal.prisma.users.findFirst({ where: { id } });\n if (!user) throw new Error(\"User not found\");\n ...\n return result;\n}\n```\n\n🔥 Error Handling Plan:\n\nIf an error is expected or encountered during implementation:\n\n- Clearly document the error message(s) and TypeScript error codes.\n- Analyze the root cause (e.g., type mismatch, missing field, nullability\n issue).\n- Define concrete steps to resolve the issue, such as:\n\n - Adjusting type declarations or using Prisma-generated input types.\n - Using `?? undefined` to normalize nullable fields.\n - Applying correct relation handling (e.g., `connect` instead of direct\n foreign key assignment).\n - Ensuring `Date` fields use `.toISOString()` and branded types.\n- Include fallback or workaround plans if a direct fix is complex.\n- If no error is present, simply omit this section.\n\nThis plan ensures the function will:\n\n- Respect the global architecture and coding conventions\n- Be safe, predictable, and aligned with upstream logic",
7516
+ description: "🧠 Provider Function Implementation Plan\n\nThis field outlines the strategic plan for implementing the provider\nfunction according to the Realize Coder Agent specification. Before\nwriting the actual code, think through the logic and structure.\n\nThe plan must consider:\n\n- 🧩 Required business entities (e.g., users, posts, logs) and their\n relationships\n- 🛠 Operations needed to fulfill the business scenario (e.g., fetch,\n create, update)\n- 🔄 Data dependencies between steps (e.g., use userId to fetch related\n data)\n- ✅ Validation points (based on business rules, not field presence)\n- 🚧 Error and edge cases that must be handled explicitly (e.g., missing\n records)\n- 🏗 Structure: always a single `async function`, using only `parameters`\n and `body`\n\n⚠️ Important Constraints:\n\n- Do NOT perform input validation — assume `parameters` and `body` are\n already valid\n- Use `typia.random<T>()` with an explanatory comment if logic can't be\n implemented\n- Never use `any` or make assumptions without sufficient context\n- Use only allowed imports — DTOs and Prisma types\n- Use `MyGlobal.prisma` for DB access and respect Prisma typing rules\n\n⚠️ TypeScript-specific considerations:\n\n- Do **not** use native `Date` objects directly; always convert all dates\n to ISO strings with `.toISOString()` and brand as `string &\n tags.Format<'date-time'>`. This rule applies throughout all phases.\n- Prefer `satisfies` for DTO conformance instead of unsafe `as` casts\n- Avoid weak typing such as `any`, `as any`, or `satisfies any`\n- Use branded types (e.g., `tags.Format<'uuid'>`) and literal unions where\n applicable\n\n✅ Example Structure:\n\n```ts\nexport async function doSomething(\n user: { id: string & tags.Format<\"uuid\">; type: string },\n parameters: IParams,\n body: IBody\n): Promise<IReturn> {\n const { id } = parameters;\n const { name } = body;\n const user = await MyGlobal.prisma.users.findFirst({ where: { id } });\n if (!user) throw new Error(\"User not found\");\n ...\n return result;\n}\n```\n\n🔥 Error Handling Plan:\n\nIf an error is expected or encountered during implementation:\n\n- Clearly document the error message(s) and TypeScript error codes.\n- Analyze the root cause (e.g., type mismatch, missing field, nullability\n issue).\n- Define concrete steps to resolve the issue, such as:\n\n - Adjusting type declarations or using Prisma-generated input types.\n - Using `?? undefined` to normalize nullable fields.\n - Applying correct relation handling (e.g., `connect` instead of direct\n foreign key assignment).\n - Ensuring all date fields use `.toISOString()` and proper branding.\n- Include fallback or workaround plans if a direct fix is complex.\n- If no error is present, simply omit this section.\n\nThis plan ensures the function will:\n\n- Respect the global architecture and coding conventions\n- Be safe, predictable, and aligned with upstream logic",
7517
+ type: "string"
7518
+ },
7519
+ draft_without_date_type: {
7520
+ description: "✏️ Phase 1: Draft code\n\nThis is the initial drafting phase where you outline the basic skeleton\nof the function.\n\n- The function signature must correctly include `user`, `parameters`, and\n `body` arguments.\n- Design the main flow of business logic, such as DB fetches and early\n returns based on conditions.\n- Mark any incomplete or missing parts clearly with placeholders (e.g.,\n comments or temporary values).\n\n⚠️ Import rules:\n\n- Do NOT add any new import statements manually.\n- All necessary imports are provided globally or by the system\n automatically.\n- Writing import statements directly is prohibited and may cause compile\n errors. If import errors occur, check your environment configuration.\n\n✅ Requirements:\n\n- Avoid using the `any` type at all costs to ensure type safety.\n- Do NOT assign native `Date` objects directly; always convert dates using\n `.toISOString()` before assignment and apply proper branding.\n- Maintain a single-function structure; avoid using classes.",
6948
7521
  type: "string"
6949
7522
  },
6950
7523
  review: {
@@ -6952,21 +7525,21 @@ const claude$4 = {
6952
7525
  type: "string"
6953
7526
  },
6954
7527
  withCompilerFeedback: {
6955
- description: "🛠 Phase 3: With compiler feedback (optional)\n\nA correction pass that applies fixes for compile-time errors that arose\nduring the review stage (if any).\n\n✅ Must:\n\n- Resolve all TypeScript errors without using `as any`\n- Provide safe brand casting only if required (e.g., `as string &\n tags.Format<'uuid'>`)",
7528
+ description: "🛠 Phase 3: With compiler feedback (optional)\n\nA correction pass that applies fixes for compile-time errors that arose\nduring the review stage (if any).\n\n✅ Must:\n\n- Only include this field if TypeScript errors are detected in the Review\n phase.\n- Resolve all TypeScript errors without using `as any`.\n- Provide safe brand casting only if required (e.g., `as string &\n tags.Format<'uuid'>`).",
6956
7529
  type: "string"
6957
7530
  },
6958
7531
  implementationCode: {
6959
- description: "✅ Phase 4: Final implementation\n\nThe complete and fully correct TypeScript function implementation.\n\n- Passes strict type checking without errors.\n- Uses only safe branding or literal type assertions.\n- Converts all Date values properly to ISO string format.\n- Follows DTO structures using `satisfies`.\n- Avoids any weak typing such as `any`, `as any`, or `satisfies any`.\n- Uses only allowed imports (e.g., from `src/api/structures` and\n `MyGlobal.prisma`).\n\n⚠️ Prohibited Practices:\n\n- Do NOT add or modify import statements manually. Imports are handled\n automatically by the system.\n- Do NOT use `any`, `as any`, or `satisfies any` to bypass type checking.\n- Do NOT assign native `Date` objects directly; always convert them to ISO\n strings with `.toISOString()`.\n- Do NOT use unsafe type assertions except for safe branding or literal\n narrowing.\n- Do NOT write code outside the single async function structure (e.g., no\n classes or multiple functions).\n- Do NOT perform any input validation — assume all inputs are already\n validated.\n- Do NOT use dynamic import expressions (`import()`); all imports must be\n static.\n- Do NOT rely on DTO types for database update input; always use\n Prisma-generated input types.",
7532
+ description: "✅ Phase 4: Final implementation\n\nThe complete and fully correct TypeScript function implementation.\n\n- Passes strict type checking without errors.\n- Uses only safe branding or literal type assertions.\n- Converts all date values properly to ISO string format.\n- Follows DTO structures using `satisfies`.\n- Avoids any weak typing such as `any`, `as any`, or `satisfies any`.\n- Uses only allowed imports (e.g., from `src/api/structures` and\n `MyGlobal.prisma`).\n\n⚠️ Prohibited Practices:\n\n- Do NOT add or modify import statements manually. Imports are handled\n automatically by the system.\n- Do NOT use `any`, `as any`, or `satisfies any` to bypass type checking.\n- Do NOT assign native `Date` objects directly; always convert them to ISO\n strings with `.toISOString()`.\n- Do NOT use unsafe type assertions except for safe branding or literal\n narrowing.\n- Do NOT write code outside the single async function structure (e.g., no\n classes or multiple functions).\n- Do NOT perform any input validation — assume all inputs are already\n validated.\n- Do NOT use dynamic import expressions (`import()`); all imports must be\n static.\n- Do NOT rely on DTO types for database update input; always use\n Prisma-generated input types.",
6960
7533
  type: "string"
6961
7534
  }
6962
7535
  },
6963
- required: [ "filename", "plan", "review", "implementationCode" ]
7536
+ required: [ "filename", "plan", "draft_without_date_type", "review", "implementationCode" ]
6964
7537
  }
6965
7538
  }
6966
7539
  },
6967
7540
  validate: (() => {
6968
7541
  const _io0 = input => "object" === typeof input.output && null !== input.output && _io1(input.output);
6969
- const _io1 = input => "string" === typeof input.filename && "string" === typeof input.plan && "string" === typeof input.review && (undefined === input.withCompilerFeedback || "string" === typeof input.withCompilerFeedback) && "string" === typeof input.implementationCode;
7542
+ const _io1 = input => "string" === typeof input.filename && "string" === typeof input.plan && "string" === typeof input.draft_without_date_type && "string" === typeof input.review && (undefined === input.withCompilerFeedback || "string" === typeof input.withCompilerFeedback) && "string" === typeof input.implementationCode;
6970
7543
  const _vo0 = (input, _path, _exceptionable = true) => [ ("object" === typeof input.output && null !== input.output || _report(_exceptionable, {
6971
7544
  path: _path + ".output",
6972
7545
  expected: "IAutoBeRealizeCoderApplication.RealizeCoderOutput",
@@ -6984,6 +7557,10 @@ const claude$4 = {
6984
7557
  path: _path + ".plan",
6985
7558
  expected: "string",
6986
7559
  value: input.plan
7560
+ }), "string" === typeof input.draft_without_date_type || _report(_exceptionable, {
7561
+ path: _path + ".draft_without_date_type",
7562
+ expected: "string",
7563
+ value: input.draft_without_date_type
6987
7564
  }), "string" === typeof input.review || _report(_exceptionable, {
6988
7565
  path: _path + ".review",
6989
7566
  expected: "string",
@@ -7058,11 +7635,14 @@ const collection$4 = {
7058
7635
  type: "object",
7059
7636
  properties: {
7060
7637
  filename: {
7061
- description: 'The name of the file to be generated (e.g., "user.create.ts")',
7062
7638
  type: "string"
7063
7639
  },
7064
7640
  plan: {
7065
- description: "🧠 Provider Function Implementation Plan\n\nThis field outlines the strategic plan for implementing the provider\nfunction according to the Realize Coder Agent specification. Before\nwriting the actual code, think through the logic and structure.\n\nThe plan must consider:\n\n- 🧩 Required business entities (e.g., users, posts, logs) and their\n relationships\n- 🛠 Operations needed to fulfill the business scenario (e.g., fetch,\n create, update)\n- 🔄 Data dependencies between steps (e.g., use userId to fetch related\n data)\n- ✅ Validation points (based on business rules, not field presence)\n- 🚧 Error and edge cases that must be handled explicitly (e.g., missing\n records)\n- 🏗 Structure: always a single `async function`, using only `parameters`\n and `body`\n\n⚠️ Important Constraints:\n\n- Do NOT perform input validation — assume `parameters` and `body` are\n already valid\n- Use `typia.random<T>()` with an explanatory comment if logic can't be\n implemented\n- Never use `any` or make assumptions without sufficient context\n- Use only allowed imports — DTOs and Prisma types\n- Use `MyGlobal.prisma` for DB access and respect Prisma typing rules\n\n⚠️ TypeScript-specific considerations:\n\n- Do **not** use native `Date` objects directly; convert all dates with\n `.toISOString()`\n- Use `string & tags.Format<'date-time'>` for all date/time typed fields\n- Prefer `satisfies` for DTO conformance instead of unsafe `as` casts\n- Avoid weak typing such as `any`, `as any`, or `satisfies any`\n- Use branded types (e.g., `tags.Format<'uuid'>`) and literal unions where\n applicable\n\n✅ Example Structure:\n\n```ts\nexport async function doSomething(\n user: { id: string & tags.Format<\"uuid\">; type: string },\n parameters: IParams,\n body: IBody\n): Promise<IReturn> {\n const { id } = parameters;\n const { name } = body;\n const user = await MyGlobal.prisma.users.findFirst({ where: { id } });\n if (!user) throw new Error(\"User not found\");\n ...\n return result;\n}\n```\n\n🔥 Error Handling Plan:\n\nIf an error is expected or encountered during implementation:\n\n- Clearly document the error message(s) and TypeScript error codes.\n- Analyze the root cause (e.g., type mismatch, missing field, nullability\n issue).\n- Define concrete steps to resolve the issue, such as:\n\n - Adjusting type declarations or using Prisma-generated input types.\n - Using `?? undefined` to normalize nullable fields.\n - Applying correct relation handling (e.g., `connect` instead of direct\n foreign key assignment).\n - Ensuring `Date` fields use `.toISOString()` and branded types.\n- Include fallback or workaround plans if a direct fix is complex.\n- If no error is present, simply omit this section.\n\nThis plan ensures the function will:\n\n- Respect the global architecture and coding conventions\n- Be safe, predictable, and aligned with upstream logic",
7641
+ description: "🧠 Provider Function Implementation Plan\n\nThis field outlines the strategic plan for implementing the provider\nfunction according to the Realize Coder Agent specification. Before\nwriting the actual code, think through the logic and structure.\n\nThe plan must consider:\n\n- 🧩 Required business entities (e.g., users, posts, logs) and their\n relationships\n- 🛠 Operations needed to fulfill the business scenario (e.g., fetch,\n create, update)\n- 🔄 Data dependencies between steps (e.g., use userId to fetch related\n data)\n- ✅ Validation points (based on business rules, not field presence)\n- 🚧 Error and edge cases that must be handled explicitly (e.g., missing\n records)\n- 🏗 Structure: always a single `async function`, using only `parameters`\n and `body`\n\n⚠️ Important Constraints:\n\n- Do NOT perform input validation — assume `parameters` and `body` are\n already valid\n- Use `typia.random<T>()` with an explanatory comment if logic can't be\n implemented\n- Never use `any` or make assumptions without sufficient context\n- Use only allowed imports — DTOs and Prisma types\n- Use `MyGlobal.prisma` for DB access and respect Prisma typing rules\n\n⚠️ TypeScript-specific considerations:\n\n- Do **not** use native `Date` objects directly; always convert all dates\n to ISO strings with `.toISOString()` and brand as `string &\n tags.Format<'date-time'>`. This rule applies throughout all phases.\n- Prefer `satisfies` for DTO conformance instead of unsafe `as` casts\n- Avoid weak typing such as `any`, `as any`, or `satisfies any`\n- Use branded types (e.g., `tags.Format<'uuid'>`) and literal unions where\n applicable\n\n✅ Example Structure:\n\n```ts\nexport async function doSomething(\n user: { id: string & tags.Format<\"uuid\">; type: string },\n parameters: IParams,\n body: IBody\n): Promise<IReturn> {\n const { id } = parameters;\n const { name } = body;\n const user = await MyGlobal.prisma.users.findFirst({ where: { id } });\n if (!user) throw new Error(\"User not found\");\n ...\n return result;\n}\n```\n\n🔥 Error Handling Plan:\n\nIf an error is expected or encountered during implementation:\n\n- Clearly document the error message(s) and TypeScript error codes.\n- Analyze the root cause (e.g., type mismatch, missing field, nullability\n issue).\n- Define concrete steps to resolve the issue, such as:\n\n - Adjusting type declarations or using Prisma-generated input types.\n - Using `?? undefined` to normalize nullable fields.\n - Applying correct relation handling (e.g., `connect` instead of direct\n foreign key assignment).\n - Ensuring all date fields use `.toISOString()` and proper branding.\n- Include fallback or workaround plans if a direct fix is complex.\n- If no error is present, simply omit this section.\n\nThis plan ensures the function will:\n\n- Respect the global architecture and coding conventions\n- Be safe, predictable, and aligned with upstream logic",
7642
+ type: "string"
7643
+ },
7644
+ draft_without_date_type: {
7645
+ description: "✏️ Phase 1: Draft code\n\nThis is the initial drafting phase where you outline the basic skeleton\nof the function.\n\n- The function signature must correctly include `user`, `parameters`, and\n `body` arguments.\n- Design the main flow of business logic, such as DB fetches and early\n returns based on conditions.\n- Mark any incomplete or missing parts clearly with placeholders (e.g.,\n comments or temporary values).\n\n⚠️ Import rules:\n\n- Do NOT add any new import statements manually.\n- All necessary imports are provided globally or by the system\n automatically.\n- Writing import statements directly is prohibited and may cause compile\n errors. If import errors occur, check your environment configuration.\n\n✅ Requirements:\n\n- Avoid using the `any` type at all costs to ensure type safety.\n- Do NOT assign native `Date` objects directly; always convert dates using\n `.toISOString()` before assignment and apply proper branding.\n- Maintain a single-function structure; avoid using classes.",
7066
7646
  type: "string"
7067
7647
  },
7068
7648
  review: {
@@ -7070,21 +7650,21 @@ const collection$4 = {
7070
7650
  type: "string"
7071
7651
  },
7072
7652
  withCompilerFeedback: {
7073
- description: "🛠 Phase 3: With compiler feedback (optional)\n\nA correction pass that applies fixes for compile-time errors that arose\nduring the review stage (if any).\n\n✅ Must:\n\n- Resolve all TypeScript errors without using `as any`\n- Provide safe brand casting only if required (e.g., `as string &\n tags.Format<'uuid'>`)",
7653
+ description: "🛠 Phase 3: With compiler feedback (optional)\n\nA correction pass that applies fixes for compile-time errors that arose\nduring the review stage (if any).\n\n✅ Must:\n\n- Only include this field if TypeScript errors are detected in the Review\n phase.\n- Resolve all TypeScript errors without using `as any`.\n- Provide safe brand casting only if required (e.g., `as string &\n tags.Format<'uuid'>`).",
7074
7654
  type: "string"
7075
7655
  },
7076
7656
  implementationCode: {
7077
- description: "✅ Phase 4: Final implementation\n\nThe complete and fully correct TypeScript function implementation.\n\n- Passes strict type checking without errors.\n- Uses only safe branding or literal type assertions.\n- Converts all Date values properly to ISO string format.\n- Follows DTO structures using `satisfies`.\n- Avoids any weak typing such as `any`, `as any`, or `satisfies any`.\n- Uses only allowed imports (e.g., from `src/api/structures` and\n `MyGlobal.prisma`).\n\n⚠️ Prohibited Practices:\n\n- Do NOT add or modify import statements manually. Imports are handled\n automatically by the system.\n- Do NOT use `any`, `as any`, or `satisfies any` to bypass type checking.\n- Do NOT assign native `Date` objects directly; always convert them to ISO\n strings with `.toISOString()`.\n- Do NOT use unsafe type assertions except for safe branding or literal\n narrowing.\n- Do NOT write code outside the single async function structure (e.g., no\n classes or multiple functions).\n- Do NOT perform any input validation — assume all inputs are already\n validated.\n- Do NOT use dynamic import expressions (`import()`); all imports must be\n static.\n- Do NOT rely on DTO types for database update input; always use\n Prisma-generated input types.",
7657
+ description: "✅ Phase 4: Final implementation\n\nThe complete and fully correct TypeScript function implementation.\n\n- Passes strict type checking without errors.\n- Uses only safe branding or literal type assertions.\n- Converts all date values properly to ISO string format.\n- Follows DTO structures using `satisfies`.\n- Avoids any weak typing such as `any`, `as any`, or `satisfies any`.\n- Uses only allowed imports (e.g., from `src/api/structures` and\n `MyGlobal.prisma`).\n\n⚠️ Prohibited Practices:\n\n- Do NOT add or modify import statements manually. Imports are handled\n automatically by the system.\n- Do NOT use `any`, `as any`, or `satisfies any` to bypass type checking.\n- Do NOT assign native `Date` objects directly; always convert them to ISO\n strings with `.toISOString()`.\n- Do NOT use unsafe type assertions except for safe branding or literal\n narrowing.\n- Do NOT write code outside the single async function structure (e.g., no\n classes or multiple functions).\n- Do NOT perform any input validation — assume all inputs are already\n validated.\n- Do NOT use dynamic import expressions (`import()`); all imports must be\n static.\n- Do NOT rely on DTO types for database update input; always use\n Prisma-generated input types.",
7078
7658
  type: "string"
7079
7659
  }
7080
7660
  },
7081
- required: [ "filename", "plan", "review", "implementationCode" ]
7661
+ required: [ "filename", "plan", "draft_without_date_type", "review", "implementationCode" ]
7082
7662
  }
7083
7663
  }
7084
7664
  },
7085
7665
  validate: (() => {
7086
7666
  const _io0 = input => "object" === typeof input.output && null !== input.output && _io1(input.output);
7087
- const _io1 = input => "string" === typeof input.filename && "string" === typeof input.plan && "string" === typeof input.review && (undefined === input.withCompilerFeedback || "string" === typeof input.withCompilerFeedback) && "string" === typeof input.implementationCode;
7667
+ const _io1 = input => "string" === typeof input.filename && "string" === typeof input.plan && "string" === typeof input.draft_without_date_type && "string" === typeof input.review && (undefined === input.withCompilerFeedback || "string" === typeof input.withCompilerFeedback) && "string" === typeof input.implementationCode;
7088
7668
  const _vo0 = (input, _path, _exceptionable = true) => [ ("object" === typeof input.output && null !== input.output || _report(_exceptionable, {
7089
7669
  path: _path + ".output",
7090
7670
  expected: "IAutoBeRealizeCoderApplication.RealizeCoderOutput",
@@ -7102,6 +7682,10 @@ const collection$4 = {
7102
7682
  path: _path + ".plan",
7103
7683
  expected: "string",
7104
7684
  value: input.plan
7685
+ }), "string" === typeof input.draft_without_date_type || _report(_exceptionable, {
7686
+ path: _path + ".draft_without_date_type",
7687
+ expected: "string",
7688
+ value: input.draft_without_date_type
7105
7689
  }), "string" === typeof input.review || _report(_exceptionable, {
7106
7690
  path: _path + ".review",
7107
7691
  expected: "string",
@@ -7168,7 +7752,7 @@ const orchestrateRealizePlanner = async (ctx, operation) => {
7168
7752
  };
7169
7753
  };
7170
7754
 
7171
- async function writeCodeUntilCompilePassed(ctx, ops, retry = 5) {
7755
+ async function writeCodeUntilCompilePassed(ctx, ops, retry = 3) {
7172
7756
  const files = Object.entries(await ctx.files({
7173
7757
  dbms: "postgres"
7174
7758
  })).filter((([key]) => key.startsWith("src"))).reduce(((acc, [filename, content]) => Object.assign(acc, {
@@ -7182,8 +7766,14 @@ async function writeCodeUntilCompilePassed(ctx, ops, retry = 5) {
7182
7766
  current: [],
7183
7767
  total: []
7184
7768
  };
7769
+ ops = ops.filter(((_el, i) => i < 10));
7185
7770
  for (let i = 0; i < retry; i++) {
7186
- const generatedCodes = await Promise.all(ops.filter((op => shouldProcessOperation(op, diagnostics.current))).map((op => process$1(ctx, op, diagnostics, entireCodes))));
7771
+ const targets = ops.filter((op => shouldProcessOperation(op, diagnostics.current)));
7772
+ const metadata = {
7773
+ total: targets.length,
7774
+ count: 0
7775
+ };
7776
+ const generatedCodes = await Promise.all(targets.map((op => process$1(ctx, metadata, op, diagnostics, entireCodes))));
7187
7777
  for (const c of generatedCodes) {
7188
7778
  if (c.type === "success") {
7189
7779
  entireCodes[c.result.filename] = {
@@ -7209,7 +7799,7 @@ async function writeCodeUntilCompilePassed(ctx, ops, retry = 5) {
7209
7799
  } else if (compiled.type === "failure") {
7210
7800
  diagnostics.current = compiled.diagnostics;
7211
7801
  diagnostics.total = [ ...diagnostics.total, ...compiled.diagnostics ];
7212
- console.log(JSON.stringify(diagnostics, null, 2), i);
7802
+ console.log(JSON.stringify(diagnostics.current, null, 2), `현재 에러의 수: ${diagnostics.current.length}\n`, `현재 시도 수: ${i}`);
7213
7803
  }
7214
7804
  }
7215
7805
  return Object.entries(entireCodes).map((([filename, {content}]) => ({
@@ -7232,13 +7822,26 @@ async function loadTemplateFiles(templateFiles) {
7232
7822
  return result;
7233
7823
  }
7234
7824
 
7235
- async function process$1(ctx, op, diagnostics, entireCodes) {
7236
- const result = await pipe(op, (op => orchestrateRealizePlanner(ctx, op)), (p => {
7825
+ async function process$1(ctx, metadata, op, diagnostics, entireCodes) {
7826
+ const result = await pipe(op, (op => orchestrateRealizePlanner(ctx, op)), (async p => {
7237
7827
  const filename = `src/providers/${p.functionName}.ts`;
7238
7828
  const t = diagnostics.total.filter((el => el.file === filename));
7239
7829
  const d = diagnostics.current.filter((el => el.file === filename));
7240
7830
  const c = entireCodes[filename]?.content ?? null;
7241
- return orchestrateRealizeCoder(ctx, op, p, c, t, d);
7831
+ return orchestrateRealizeCoder(ctx, op, p, c, t, d).then((res => {
7832
+ if (res === FAILED) ; else {
7833
+ ctx.dispatch({
7834
+ type: "realizeProgress",
7835
+ filename: res.filename,
7836
+ content: res.implementationCode,
7837
+ completed: ++metadata.count,
7838
+ created_at: (new Date).toISOString(),
7839
+ step: ctx.state().analyze?.step ?? 0,
7840
+ total: metadata.total
7841
+ });
7842
+ }
7843
+ return res;
7844
+ }));
7242
7845
  }));
7243
7846
  if (result === FAILED) {
7244
7847
  return {
@@ -7271,6 +7874,13 @@ const orchestrateRealize = ctx => async props => {
7271
7874
  if (!ops) {
7272
7875
  throw new Error("Can't do realize agent because operations are nothing.");
7273
7876
  }
7877
+ ctx.dispatch({
7878
+ type: "realizeStart",
7879
+ created_at: (new Date).toISOString(),
7880
+ reason: props.reason,
7881
+ step: ctx.state().test?.step ?? 0
7882
+ });
7883
+ await orchestrateRealizeDecorator(ctx);
7274
7884
  await writeCodeUntilCompilePassed(ctx, ops, 3);
7275
7885
  const now = (new Date).toISOString();
7276
7886
  ctx.dispatch({
@@ -7502,7 +8112,7 @@ const compile = async (ctx, func) => {
7502
8112
  };
7503
8113
 
7504
8114
  const predicate = async (ctx, content, event, life) => {
7505
- ctx.dispatch(event);
8115
+ if (event.result.type === "failure") ctx.dispatch(event);
7506
8116
  return event.result.type === "failure" ? correct(ctx, content, event, life - 1) : event;
7507
8117
  };
7508
8118
 
@@ -9802,193 +10412,6 @@ const createAutoBeState = histories => {
9802
10412
  };
9803
10413
  };
9804
10414
 
9805
- async function getAutoBeGenerated(ctx, histories, tokenUsage, options) {
9806
- const state = ctx.state();
9807
- const ret = {};
9808
- if (state.analyze === null) return {};
9809
- Object.assign(ret, Object.fromEntries(Object.entries(state.analyze.files).map((([key, value]) => [ `docs/analysis/${key.split("/").at(-1)}`, value ]))));
9810
- const compiler = await ctx.compiler();
9811
- if (state.prisma?.step === state.analyze.step) {
9812
- const schemaFiles = (options?.dbms ?? "postgres") === "postgres" ? state.prisma.schemas : await compiler.prisma.write(state.prisma.result.data, options.dbms);
9813
- Object.assign(ret, Object.fromEntries(Object.entries(schemaFiles).map((([key, value]) => [ `prisma/schema/${key.split("/").at(-1)}`, value ]))), {
9814
- "autobe/prisma.json": (() => {
9815
- const _so0 = input => `{"files":${`[${input.files.map((elem => _so1(elem))).join(",")}]`}}`;
9816
- const _so1 = input => `{"filename":${__typia_transform__jsonStringifyString._jsonStringifyString(input.filename)},"namespace":${__typia_transform__jsonStringifyString._jsonStringifyString(input.namespace)},"models":${`[${input.models.map((elem => _so2(elem))).join(",")}]`}}`;
9817
- const _so2 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"material":${input.material},"primaryField":${_so3(input.primaryField)},"foreignFields":${`[${input.foreignFields.map((elem => _so4(elem))).join(",")}]`},"plainFields":${`[${input.plainFields.map((elem => _so6(elem))).join(",")}]`},"uniqueIndexes":${`[${input.uniqueIndexes.map((elem => _so7(elem))).join(",")}]`},"plainIndexes":${`[${input.plainIndexes.map((elem => _so8(elem))).join(",")}]`},"ginIndexes":${`[${input.ginIndexes.map((elem => _so9(elem))).join(",")}]`}}`;
9818
- const _so3 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"type":${'"' + input.type + '"'},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)}}`;
9819
- const _so4 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"type":${'"' + input.type + '"'},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"relation":${_so5(input.relation)},"unique":${input.unique},"nullable":${input.nullable}}`;
9820
- const _so5 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"targetModel":${__typia_transform__jsonStringifyString._jsonStringifyString(input.targetModel)}}`;
9821
- const _so6 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"type":${'"' + input.type + '"'},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"nullable":${input.nullable}}`;
9822
- const _so7 = input => `{"fieldNames":${`[${input.fieldNames.map((elem => __typia_transform__jsonStringifyString._jsonStringifyString(elem))).join(",")}]`},"unique":${input.unique}}`;
9823
- const _so8 = input => `{"fieldNames":${`[${input.fieldNames.map((elem => __typia_transform__jsonStringifyString._jsonStringifyString(elem))).join(",")}]`}}`;
9824
- const _so9 = input => `{"fieldName":${__typia_transform__jsonStringifyString._jsonStringifyString(input.fieldName)}}`;
9825
- return input => _so0(input);
9826
- })()(state.prisma.result.data)
9827
- });
9828
- if (state.prisma.compiled.type === "success") ret["docs/ERD.md"] = state.prisma.compiled.document; else if (state.prisma.compiled.type === "failure") ret["prisma/compile-error-reason.log"] = state.prisma.compiled.reason;
9829
- }
9830
- if (state.interface?.step === state.analyze.step) {
9831
- const files = await compiler.interface.write(state.interface.document);
9832
- Object.assign(ret, state.test?.step === state.interface.step ? Object.fromEntries(Object.entries(files).filter((([key]) => key.startsWith("test/features/") === false))) : files, {
9833
- "autobe/document.json": (() => {
9834
- const _so0 = input => `{"operations":${`[${input.operations.map((elem => _so1(elem))).join(",")}]`},"components":${_so8(input.components)}}`;
9835
- const _so1 = input => `{"specification":${__typia_transform__jsonStringifyString._jsonStringifyString(input.specification)},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"summary":${__typia_transform__jsonStringifyString._jsonStringifyString(input.summary)},"parameters":${`[${input.parameters.map((elem => _so2(elem))).join(",")}]`},"requestBody":${null !== input.requestBody ? _so6(input.requestBody) : "null"},"responseBody":${null !== input.responseBody ? _so7(input.responseBody) : "null"},"authorizationRoles":${null !== input.authorizationRoles ? `[${input.authorizationRoles.map((elem => __typia_transform__jsonStringifyString._jsonStringifyString(elem))).join(",")}]` : "null"},"path":${__typia_transform__jsonStringifyString._jsonStringifyString(input.path)},"method":${'"' + input.method + '"'}}`;
9836
- const _so2 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"schema":${_su0(input.schema)}}`;
9837
- const _so3 = input => `{${undefined === input.minimum ? "" : `"minimum":${undefined !== input.minimum ? input.minimum : undefined},`}${undefined === input.maximum ? "" : `"maximum":${undefined !== input.maximum ? input.maximum : undefined},`}${undefined === input.exclusiveMinimum ? "" : `"exclusiveMinimum":${undefined !== input.exclusiveMinimum ? input.exclusiveMinimum : undefined},`}${undefined === input.exclusiveMaximum ? "" : `"exclusiveMaximum":${undefined !== input.exclusiveMaximum ? input.exclusiveMaximum : undefined},`}${undefined === input.multipleOf ? "" : `"multipleOf":${undefined !== input.multipleOf ? input.multipleOf : undefined},`}"type":${'"' + input.type + '"'}}`;
9838
- const _so4 = input => `{${undefined === input.minimum ? "" : `"minimum":${undefined !== input.minimum ? input.minimum : undefined},`}${undefined === input.maximum ? "" : `"maximum":${undefined !== input.maximum ? input.maximum : undefined},`}${undefined === input.exclusiveMinimum ? "" : `"exclusiveMinimum":${undefined !== input.exclusiveMinimum ? input.exclusiveMinimum : undefined},`}${undefined === input.exclusiveMaximum ? "" : `"exclusiveMaximum":${undefined !== input.exclusiveMaximum ? input.exclusiveMaximum : undefined},`}${undefined === input.multipleOf ? "" : `"multipleOf":${undefined !== input.multipleOf ? input.multipleOf : undefined},`}"type":${'"' + input.type + '"'}}`;
9839
- const _so5 = input => `{${undefined === input.format ? "" : `"format":${undefined !== input.format ? __typia_transform__jsonStringifyString._jsonStringifyString(input.format) : undefined},`}${undefined === input.pattern ? "" : `"pattern":${undefined !== input.pattern ? __typia_transform__jsonStringifyString._jsonStringifyString(input.pattern) : undefined},`}${undefined === input.contentMediaType ? "" : `"contentMediaType":${undefined !== input.contentMediaType ? __typia_transform__jsonStringifyString._jsonStringifyString(input.contentMediaType) : undefined},`}${undefined === input.minLength ? "" : `"minLength":${undefined !== input.minLength ? input.minLength : undefined},`}${undefined === input.maxLength ? "" : `"maxLength":${undefined !== input.maxLength ? input.maxLength : undefined},`}"type":${'"' + input.type + '"'}}`;
9840
- const _so6 = input => `{"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"typeName":${__typia_transform__jsonStringifyString._jsonStringifyString(input.typeName)}}`;
9841
- const _so7 = input => `{"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"typeName":${__typia_transform__jsonStringifyString._jsonStringifyString(input.typeName)}}`;
9842
- const _so8 = input => `{${undefined === input.authorization ? "" : `"authorization":${undefined !== input.authorization ? `[${input.authorization.map((elem => _so11(elem))).join(",")}]` : undefined},`}"schemas":${_so9(input.schemas)}}`;
9843
- const _so9 = input => `{${Object.entries(input).map((([key, value]) => {
9844
- if (undefined === value) return "";
9845
- return `${JSON.stringify(key)}:${_so10(value)}`;
9846
- })).filter((str => "" !== str)).join(",")}}`;
9847
- const _so10 = input => `{"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)}}`;
9848
- const _so11 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)}}`;
9849
- const _su0 = input => (() => {
9850
- if ("number" === input.type) return _so4(input); else if ("integer" === input.type) return _so3(input); else if ("string" === input.type) return _so5(input); else __typia_transform__throwTypeGuardError._throwTypeGuardError({
9851
- method: "typia.json.stringify",
9852
- expected: "(AutoBeOpenApi.IJsonSchema.INumber | AutoBeOpenApi.IJsonSchema.IInteger | AutoBeOpenApi.IJsonSchema.IString)",
9853
- value: input
9854
- });
9855
- })();
9856
- return input => _so0(input);
9857
- })()(state.interface.document)
9858
- });
9859
- }
9860
- if (state.test?.step === state.analyze.step) Object.assign(ret, Object.fromEntries(state.test.files.map((f => [ f.location, f.content ]))), await compiler.test.getTemplate());
9861
- if (state.realize?.step === state.analyze.step) Object.assign(ret, state.realize.files, await compiler.realize.getTemplate());
9862
- Object.assign(ret, {
9863
- "autobe/histories.json": (() => {
9864
- const _so0 = input => `{"reason":${__typia_transform__jsonStringifyString._jsonStringifyString(input.reason)},"step":${input.step},"prefix":${__typia_transform__jsonStringifyString._jsonStringifyString(input.prefix)},"files":${_so1(input.files)},"completed_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.completed_at)},"roles":${`[${input.roles.map((elem => _so2(elem))).join(",")}]`},"id":${__typia_transform__jsonStringifyString._jsonStringifyString(input.id)},"type":${'"' + input.type + '"'},"created_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.created_at)}}`;
9865
- const _so1 = input => `{${Object.entries(input).map((([key, value]) => {
9866
- if (undefined === value) return "";
9867
- return `${JSON.stringify(key)}:${__typia_transform__jsonStringifyString._jsonStringifyString(value)}`;
9868
- })).filter((str => "" !== str)).join(",")}}`;
9869
- const _so2 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)}}`;
9870
- const _so3 = input => `{"text":${__typia_transform__jsonStringifyString._jsonStringifyString(input.text)},"completed_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.completed_at)},"id":${__typia_transform__jsonStringifyString._jsonStringifyString(input.id)},"type":${'"' + input.type + '"'},"created_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.created_at)}}`;
9871
- const _so4 = input => `{"document":${_so5(input.document)},"reason":${__typia_transform__jsonStringifyString._jsonStringifyString(input.reason)},"step":${input.step},"completed_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.completed_at)},"id":${__typia_transform__jsonStringifyString._jsonStringifyString(input.id)},"type":${'"' + input.type + '"'},"created_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.created_at)}}`;
9872
- const _so5 = input => `{"operations":${`[${input.operations.map((elem => _so6(elem))).join(",")}]`},"components":${_so13(input.components)}}`;
9873
- const _so6 = input => `{"specification":${__typia_transform__jsonStringifyString._jsonStringifyString(input.specification)},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"summary":${__typia_transform__jsonStringifyString._jsonStringifyString(input.summary)},"parameters":${`[${input.parameters.map((elem => _so7(elem))).join(",")}]`},"requestBody":${null !== input.requestBody ? _so11(input.requestBody) : "null"},"responseBody":${null !== input.responseBody ? _so12(input.responseBody) : "null"},"authorizationRoles":${null !== input.authorizationRoles ? `[${input.authorizationRoles.map((elem => __typia_transform__jsonStringifyString._jsonStringifyString(elem))).join(",")}]` : "null"},"path":${__typia_transform__jsonStringifyString._jsonStringifyString(input.path)},"method":${'"' + input.method + '"'}}`;
9874
- const _so7 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"schema":${_su2(input.schema)}}`;
9875
- const _so8 = input => `{${undefined === input.minimum ? "" : `"minimum":${undefined !== input.minimum ? input.minimum : undefined},`}${undefined === input.maximum ? "" : `"maximum":${undefined !== input.maximum ? input.maximum : undefined},`}${undefined === input.exclusiveMinimum ? "" : `"exclusiveMinimum":${undefined !== input.exclusiveMinimum ? input.exclusiveMinimum : undefined},`}${undefined === input.exclusiveMaximum ? "" : `"exclusiveMaximum":${undefined !== input.exclusiveMaximum ? input.exclusiveMaximum : undefined},`}${undefined === input.multipleOf ? "" : `"multipleOf":${undefined !== input.multipleOf ? input.multipleOf : undefined},`}"type":${'"' + input.type + '"'}}`;
9876
- const _so9 = input => `{${undefined === input.minimum ? "" : `"minimum":${undefined !== input.minimum ? input.minimum : undefined},`}${undefined === input.maximum ? "" : `"maximum":${undefined !== input.maximum ? input.maximum : undefined},`}${undefined === input.exclusiveMinimum ? "" : `"exclusiveMinimum":${undefined !== input.exclusiveMinimum ? input.exclusiveMinimum : undefined},`}${undefined === input.exclusiveMaximum ? "" : `"exclusiveMaximum":${undefined !== input.exclusiveMaximum ? input.exclusiveMaximum : undefined},`}${undefined === input.multipleOf ? "" : `"multipleOf":${undefined !== input.multipleOf ? input.multipleOf : undefined},`}"type":${'"' + input.type + '"'}}`;
9877
- const _so10 = input => `{${undefined === input.format ? "" : `"format":${undefined !== input.format ? __typia_transform__jsonStringifyString._jsonStringifyString(input.format) : undefined},`}${undefined === input.pattern ? "" : `"pattern":${undefined !== input.pattern ? __typia_transform__jsonStringifyString._jsonStringifyString(input.pattern) : undefined},`}${undefined === input.contentMediaType ? "" : `"contentMediaType":${undefined !== input.contentMediaType ? __typia_transform__jsonStringifyString._jsonStringifyString(input.contentMediaType) : undefined},`}${undefined === input.minLength ? "" : `"minLength":${undefined !== input.minLength ? input.minLength : undefined},`}${undefined === input.maxLength ? "" : `"maxLength":${undefined !== input.maxLength ? input.maxLength : undefined},`}"type":${'"' + input.type + '"'}}`;
9878
- const _so11 = input => `{"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"typeName":${__typia_transform__jsonStringifyString._jsonStringifyString(input.typeName)}}`;
9879
- const _so12 = input => `{"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"typeName":${__typia_transform__jsonStringifyString._jsonStringifyString(input.typeName)}}`;
9880
- const _so13 = input => `{${undefined === input.authorization ? "" : `"authorization":${undefined !== input.authorization ? `[${input.authorization.map((elem => _so16(elem))).join(",")}]` : undefined},`}"schemas":${_so14(input.schemas)}}`;
9881
- const _so14 = input => `{${Object.entries(input).map((([key, value]) => {
9882
- if (undefined === value) return "";
9883
- return `${JSON.stringify(key)}:${_so15(value)}`;
9884
- })).filter((str => "" !== str)).join(",")}}`;
9885
- const _so15 = input => `{"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)}}`;
9886
- const _so16 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)}}`;
9887
- const _so17 = input => `{"result":${_su3(input.result)},"schemas":${_so1(input.schemas)},"compiled":${_su4(input.compiled)},"reason":${__typia_transform__jsonStringifyString._jsonStringifyString(input.reason)},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"step":${input.step},"completed_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.completed_at)},"id":${__typia_transform__jsonStringifyString._jsonStringifyString(input.id)},"type":${'"' + input.type + '"'},"created_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.created_at)}}`;
9888
- const _so18 = input => `{"success":${input.success},"data":${_so19(input.data)}}`;
9889
- const _so19 = input => `{"files":${`[${input.files.map((elem => _so20(elem))).join(",")}]`}}`;
9890
- const _so20 = input => `{"filename":${__typia_transform__jsonStringifyString._jsonStringifyString(input.filename)},"namespace":${__typia_transform__jsonStringifyString._jsonStringifyString(input.namespace)},"models":${`[${input.models.map((elem => _so21(elem))).join(",")}]`}}`;
9891
- const _so21 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"material":${input.material},"primaryField":${_so22(input.primaryField)},"foreignFields":${`[${input.foreignFields.map((elem => _so23(elem))).join(",")}]`},"plainFields":${`[${input.plainFields.map((elem => _so25(elem))).join(",")}]`},"uniqueIndexes":${`[${input.uniqueIndexes.map((elem => _so26(elem))).join(",")}]`},"plainIndexes":${`[${input.plainIndexes.map((elem => _so27(elem))).join(",")}]`},"ginIndexes":${`[${input.ginIndexes.map((elem => _so28(elem))).join(",")}]`}}`;
9892
- const _so22 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"type":${'"' + input.type + '"'},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)}}`;
9893
- const _so23 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"type":${'"' + input.type + '"'},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"relation":${_so24(input.relation)},"unique":${input.unique},"nullable":${input.nullable}}`;
9894
- const _so24 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"targetModel":${__typia_transform__jsonStringifyString._jsonStringifyString(input.targetModel)}}`;
9895
- const _so25 = input => `{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"type":${'"' + input.type + '"'},"description":${__typia_transform__jsonStringifyString._jsonStringifyString(input.description)},"nullable":${input.nullable}}`;
9896
- const _so26 = input => `{"fieldNames":${`[${input.fieldNames.map((elem => __typia_transform__jsonStringifyString._jsonStringifyString(elem))).join(",")}]`},"unique":${input.unique}}`;
9897
- const _so27 = input => `{"fieldNames":${`[${input.fieldNames.map((elem => __typia_transform__jsonStringifyString._jsonStringifyString(elem))).join(",")}]`}}`;
9898
- const _so28 = input => `{"fieldName":${__typia_transform__jsonStringifyString._jsonStringifyString(input.fieldName)}}`;
9899
- const _so29 = input => `{"success":${input.success},"data":${_so19(input.data)},"errors":${`[${input.errors.map((elem => _so30(elem))).join(",")}]`}}`;
9900
- const _so30 = input => `{"path":${__typia_transform__jsonStringifyString._jsonStringifyString(input.path)},"table":${null !== input.table ? __typia_transform__jsonStringifyString._jsonStringifyString(input.table) : "null"},"field":${null !== input.field ? __typia_transform__jsonStringifyString._jsonStringifyString(input.field) : "null"},"message":${__typia_transform__jsonStringifyString._jsonStringifyString(input.message)}}`;
9901
- const _so31 = input => `{"type":${'"' + input.type + '"'},"document":${__typia_transform__jsonStringifyString._jsonStringifyString(input.document)},"diagrams":${_so1(input.diagrams)},"schemas":${_so1(input.schemas)},"nodeModules":${_so1(input.nodeModules)}}`;
9902
- const _so32 = input => `{"type":${'"' + input.type + '"'},"reason":${__typia_transform__jsonStringifyString._jsonStringifyString(input.reason)}}`;
9903
- const _so33 = input => `{${undefined === input.error || "function" === typeof input.error ? "" : `"error":${undefined !== input.error ? JSON.stringify(input.error) : undefined},`}"type":${'"' + input.type + '"'}}`;
9904
- const _so34 = input => `{"files":${_so1(input.files)},"compiled":${_su5(input.compiled)},"reason":${__typia_transform__jsonStringifyString._jsonStringifyString(input.reason)},"step":${input.step},"completed_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.completed_at)},"id":${__typia_transform__jsonStringifyString._jsonStringifyString(input.id)},"type":${'"' + input.type + '"'},"created_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.created_at)}}`;
9905
- const _so35 = input => `{"type":${'"' + input.type + '"'}}`;
9906
- const _so36 = input => `{"type":${'"' + input.type + '"'},"diagnostics":${`[${input.diagnostics.map((elem => _so37(elem))).join(",")}]`}}`;
9907
- const _so37 = input => `{${undefined === input.start ? "" : `"start":${undefined !== input.start ? input.start : undefined},`}${undefined === input.length ? "" : `"length":${undefined !== input.length ? input.length : undefined},`}"file":${null !== input.file ? __typia_transform__jsonStringifyString._jsonStringifyString(input.file) : "null"},"category":${'"' + input.category + '"'},"code":${(() => {
9908
- if ("string" === typeof input.code) return __typia_transform__jsonStringifyString._jsonStringifyString(input.code);
9909
- if ("number" === typeof input.code) return input.code;
9910
- __typia_transform__throwTypeGuardError._throwTypeGuardError({
9911
- method: "typia.json.stringify",
9912
- expected: "(number | string)",
9913
- value: input.code
9914
- });
9915
- })()},"messageText":${__typia_transform__jsonStringifyString._jsonStringifyString(input.messageText)}}`;
9916
- const _so38 = input => `{${undefined === input.error || "function" === typeof input.error ? "" : `"error":${undefined !== input.error ? JSON.stringify(input.error) : undefined},`}"type":${'"' + input.type + '"'}}`;
9917
- const _so39 = input => `{"files":${`[${input.files.map((elem => _so40(elem))).join(",")}]`},"compiled":${_su5(input.compiled)},"reason":${__typia_transform__jsonStringifyString._jsonStringifyString(input.reason)},"step":${input.step},"completed_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.completed_at)},"id":${__typia_transform__jsonStringifyString._jsonStringifyString(input.id)},"type":${'"' + input.type + '"'},"created_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.created_at)}}`;
9918
- const _so40 = input => `{"location":${__typia_transform__jsonStringifyString._jsonStringifyString(input.location)},"content":${__typia_transform__jsonStringifyString._jsonStringifyString(input.content)},"scenario":${_so41(input.scenario)}}`;
9919
- const _so41 = input => `{"endpoint":${_so42(input.endpoint)},"draft":${__typia_transform__jsonStringifyString._jsonStringifyString(input.draft)},"functionName":${__typia_transform__jsonStringifyString._jsonStringifyString(input.functionName)},"dependencies":${`[${input.dependencies.map((elem => _so43(elem))).join(",")}]`}}`;
9920
- const _so42 = input => `{"path":${__typia_transform__jsonStringifyString._jsonStringifyString(input.path)},"method":${'"' + input.method + '"'}}`;
9921
- const _so43 = input => `{"purpose":${__typia_transform__jsonStringifyString._jsonStringifyString(input.purpose)},"endpoint":${_so42(input.endpoint)}}`;
9922
- const _so44 = input => `{"contents":${`[${input.contents.map((elem => _su1(elem))).join(",")}]`},"id":${__typia_transform__jsonStringifyString._jsonStringifyString(input.id)},"type":${'"' + input.type + '"'},"created_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.created_at)}}`;
9923
- const _so45 = input => `{"data":${__typia_transform__jsonStringifyString._jsonStringifyString(input.data)},"format":${'"' + input.format + '"'},"type":${'"' + input.type + '"'}}`;
9924
- const _so46 = input => `{"file":${_su6(input.file)},"type":${'"' + input.type + '"'}}`;
9925
- const _so47 = input => `{"type":${'"' + input.type + '"'},"id":${__typia_transform__jsonStringifyString._jsonStringifyString(input.id)}}`;
9926
- const _so48 = input => `{"type":${'"' + input.type + '"'},"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"data":${__typia_transform__jsonStringifyString._jsonStringifyString(input.data)}}`;
9927
- const _so49 = input => `{${undefined === input.detail ? "" : `"detail":${undefined !== input.detail ? '"' + input.detail + '"' : undefined},`}"url":${__typia_transform__jsonStringifyString._jsonStringifyString(input.url)},"type":${'"' + input.type + '"'}}`;
9928
- const _so50 = input => `{"text":${__typia_transform__jsonStringifyString._jsonStringifyString(input.text)},"type":${'"' + input.type + '"'}}`;
9929
- const _su0 = input => (() => {
9930
- if ("analyze" === input.type) return _so0(input); else if ("assistantMessage" === input.type) return _so3(input); else if ("interface" === input.type) return _so4(input); else if ("prisma" === input.type) return _so17(input); else if ("test" === input.type) return _so39(input); else if ("realize" === input.type) return _so34(input); else if ("userMessage" === input.type) return _so44(input); else __typia_transform__throwTypeGuardError._throwTypeGuardError({
9931
- method: "typia.json.stringify",
9932
- expected: "(AutoBeAnalyzeHistory | AutoBeAssistantMessageHistory | AutoBeInterfaceHistory | AutoBePrismaHistory | AutoBeTestHistory | AutoBeRealizeHistory | AutoBeUserMessageHistory)",
9933
- value: input
9934
- });
9935
- })();
9936
- const _su1 = input => (() => {
9937
- if (undefined !== input.format) return _so45(input); else if ("file" === input.type) return _so46(input); else if ("image" === input.type) return _so49(input); else if ("text" === input.type) return _so50(input); else __typia_transform__throwTypeGuardError._throwTypeGuardError({
9938
- method: "typia.json.stringify",
9939
- expected: "(AutoBeUserMessageAudioContent | AutoBeUserMessageFileContent | AutoBeUserMessageImageContent | AutoBeUserMessageTextContent)",
9940
- value: input
9941
- });
9942
- })();
9943
- const _su2 = input => (() => {
9944
- if ("number" === input.type) return _so9(input); else if ("integer" === input.type) return _so8(input); else if ("string" === input.type) return _so10(input); else __typia_transform__throwTypeGuardError._throwTypeGuardError({
9945
- method: "typia.json.stringify",
9946
- expected: "(AutoBeOpenApi.IJsonSchema.INumber | AutoBeOpenApi.IJsonSchema.IInteger | AutoBeOpenApi.IJsonSchema.IString)",
9947
- value: input
9948
- });
9949
- })();
9950
- const _su3 = input => (() => {
9951
- if (true === input.success) return _so18(input); else if (false === input.success) return _so29(input); else __typia_transform__throwTypeGuardError._throwTypeGuardError({
9952
- method: "typia.json.stringify",
9953
- expected: "(IAutoBePrismaValidation.ISuccess | IAutoBePrismaValidation.IFailure)",
9954
- value: input
9955
- });
9956
- })();
9957
- const _su4 = input => (() => {
9958
- if ("success" === input.type) return _so31(input); else if ("failure" === input.type) return _so32(input); else if ("exception" === input.type) return _so33(input); else __typia_transform__throwTypeGuardError._throwTypeGuardError({
9959
- method: "typia.json.stringify",
9960
- expected: "(IAutoBePrismaCompileResult.ISuccess | IAutoBePrismaCompileResult.IFailure | IAutoBePrismaCompileResult.IException)",
9961
- value: input
9962
- });
9963
- })();
9964
- const _su5 = input => (() => {
9965
- if ("success" === input.type) return _so35(input); else if ("failure" === input.type) return _so36(input); else if ("exception" === input.type) return _so38(input); else __typia_transform__throwTypeGuardError._throwTypeGuardError({
9966
- method: "typia.json.stringify",
9967
- expected: "(IAutoBeTypeScriptCompileResult.ISuccess | IAutoBeTypeScriptCompileResult.IFailure | IAutoBeTypeScriptCompileResult.IException)",
9968
- value: input
9969
- });
9970
- })();
9971
- const _su6 = input => (() => {
9972
- if ("reference" === input.type) return _so47(input); else if ("data" === input.type) return _so48(input); else __typia_transform__throwTypeGuardError._throwTypeGuardError({
9973
- method: "typia.json.stringify",
9974
- expected: "(AutoBeUserMessageFileContent.IReference | AutoBeUserMessageFileContent.IData)",
9975
- value: input
9976
- });
9977
- })();
9978
- return input => `[${input.map((elem => _su0(elem))).join(",")}]`;
9979
- })()(histories),
9980
- "autobe/tokenUsage.json": (() => {
9981
- const _so9 = input => `{"facade":${_so10(input.facade)},"analyze":${_so10(input.analyze)},"prisma":${_so10(input.prisma)},"interface":${_so10(input.interface)},"test":${_so10(input.test)},"realize":${_so10(input.realize)}}`;
9982
- const _so10 = input => `{"aggregate":${_so11(input.aggregate)},"initialize":${_so11(input.initialize)},"select":${_so11(input.select)},"cancel":${_so11(input.cancel)},"call":${_so11(input.call)},"describe":${_so11(input.describe)}}`;
9983
- const _so11 = input => `{"total":${input.total},"input":${_so12(input.input)},"output":${_so13(input.output)}}`;
9984
- const _so12 = input => `{"total":${input.total},"cached":${input.cached}}`;
9985
- const _so13 = input => `{"total":${input.total},"reasoning":${input.reasoning},"accepted_prediction":${input.accepted_prediction},"rejected_prediction":${input.rejected_prediction}}`;
9986
- return input => _so9(input.toJSON());
9987
- })()(tokenUsage)
9988
- });
9989
- return ret;
9990
- }
9991
-
9992
10415
  function transformFacadeStateMessage(state) {
9993
10416
  const currentState = getCurrentState(state);
9994
10417
  return "# AutoBE Main Agent System Prompt\n\nYou are the AutoBE Main Agent, an orchestrator for backend server development automation. Your role is to manage the conversation with users about their backend requirements and coordinate the execution of five specialized functional agents through function calling.\n\n## Core Responsibilities\n\n1. **Requirements Gathering**: Engage in detailed conversations with users to understand their backend server needs, asking clarifying questions about business logic, data models, API endpoints, and technical requirements.\n\n2. **Agent Orchestration**: Execute the appropriate functional agents in the correct sequence based on the development stage and user needs.\n\n3. **Progress Communication**: Keep users informed about the current development stage, what has been completed, and what steps remain.\n\n## Functional Agents Overview\n\nYou have access to five functional agents that must be executed in a specific order:\n\n1. **Analyze Agent** - Converts conversations into structured requirements specifications\n2. **Prisma Agent** - Generates database schemas and ERD documentation\n3. **Interface Agent** - Creates API interfaces with OpenAPI schemas and TypeScript code\n4. **Test Agent** - Generates comprehensive E2E test suites\n5. **Realize Agent** - Implements actual business logic for service providers\n\n## Execution Rules\n\n### 1. Sequential Dependencies\n\n- **analyze()**: Can only be called when sufficient requirements have been gathered.\n- **prisma()**: Requires successful completion of analyze()\n- **interface()**: Requires successful completion of prisma()\n- **test()**: Requires successful completion of interface()\n- **realize()**: Requires successful completion of interface()\n\n### 2. Requirements Gathering and analyze() Calling Criteria\n\n- Since users are not developers, it is okay if they do not understand technical terms like “endpoints” or “data models.” \n\n- Your job is to help users clearly express their intended **features** by asking many questions. \n\n- Use examples and simple questions to guide them if they have trouble explaining. \n\n- Break down features into smaller steps if needed to complete the planning gradually. \n\n- For instance, ask questions like “What tasks do you want to automate?”, “What roles do users have?”, “What screens or actions are involved?” \n\n- Even if the system requires many or complex APIs, it is not necessary to know all of them upfront. Focus on gathering core requirements step by step. \n\n#### Conditions for Calling analyze() \n- Call analyze() only when the user has clearly stated sufficient **features** and **requirements**, or \n- The user explicitly delegates the planning to you by saying things like “I’ll leave the planning to you” or “Please proceed as you see fit.” \n\n#### Pre-call Checks \n- If requirements are insufficient for some features, do **not** call analyze() and keep asking questions until the specifications are complete. \n- Continue asking actively and explain any technical terms in an easy-to-understand way.\n\n### 3. Requirements Gathering Phase\n\nBefore calling analyze(), ensure you have discussed:\n\n- System purpose and overall goals\n- Core features and functionalities\n- User roles and permissions\n- Main data entities and their relationships\n- Key business rules and constraints\n- API endpoints needed\n- Any specific technical requirements\n\nIf these aspects are unclear, continue the conversation to gather more details.\n\n### 4. Development Workflow\n\n1. Start by understanding the user's needs through conversation\n2. When requirements are sufficiently detailed, execute analyze()\n3. Review the analysis results with the user\n4. If approved, proceed with prisma() → interface() → test() → realize()\n5. At each stage, present results and get user confirmation before proceeding\n\n### 5. Handling Changes\n\n- If users request changes after agents have been executed, first understand the scope\n- For minor adjustments, you may re-run specific agents\n- For major changes, consider re-running analyze() to update the specification\n- Always explain the impact of changes on already generated code\n\n## Communication Guidelines\n\n1. **Be Transparent**: Clearly explain which agent is being executed and why\n2. **Show Progress**: Indicate completed steps and remaining work\n3. **Confirm Understanding**: Summarize requirements before executing agents\n4. **Request Approval**: Get user confirmation before moving to the next stage\n5. **Explain Results**: Briefly describe what each agent has generated\n\n## Current State\n\n{% STATE %}".replace("{% STATE %}", StringUtil.trim`
@@ -10027,22 +10450,15 @@ function getCurrentState(state) {
10027
10450
  };
10028
10451
  }
10029
10452
 
10030
- function emplaceMap(dict, key, generator) {
10031
- const oldbie = dict.get(key);
10032
- if (oldbie !== undefined) {
10033
- return oldbie;
10034
- }
10035
- const value = generator();
10036
- dict.set(key, value);
10037
- return value;
10038
- }
10039
-
10040
- class AutoBeAgent {
10453
+ class AutoBeAgent extends AutoBeAgentBase {
10041
10454
  constructor(props) {
10455
+ super({
10456
+ compiler: () => this.context_.compiler(),
10457
+ state: () => this.state_
10458
+ });
10042
10459
  this.props_ = props;
10043
10460
  this.histories_ = props.histories?.slice() ?? [];
10044
10461
  this.state_ = createAutoBeState(this.histories_);
10045
- this.listeners_ = new Map;
10046
10462
  this.usage_ = props.tokenUsage instanceof AutoBeTokenUsage ? props.tokenUsage : new AutoBeTokenUsage(props.tokenUsage);
10047
10463
  const vendor = {
10048
10464
  ...props.vendor,
@@ -10138,9 +10554,6 @@ class AutoBeAgent {
10138
10554
  await this.agentica_.conversate(content);
10139
10555
  return this.histories_.slice(index);
10140
10556
  }
10141
- async getFiles(options) {
10142
- return getAutoBeGenerated(await this.getContext(), this.histories_, this.usage_, options);
10143
- }
10144
10557
  getHistories() {
10145
10558
  return this.histories_;
10146
10559
  }
@@ -10150,26 +10563,6 @@ class AutoBeAgent {
10150
10563
  getContext() {
10151
10564
  return this.context_;
10152
10565
  }
10153
- on(type, listener) {
10154
- emplaceMap(this.listeners_, type, (() => new Set)).add(listener);
10155
- return this;
10156
- }
10157
- off(type, listener) {
10158
- const set = this.listeners_.get(type);
10159
- if (set === undefined) return this;
10160
- set.delete(listener);
10161
- if (set.size === 0) this.listeners_.delete(type);
10162
- return this;
10163
- }
10164
- async dispatch(event) {
10165
- const set = this.listeners_.get(event.type);
10166
- if (set === undefined) return;
10167
- await Promise.all(Array.from(set).map((async listener => {
10168
- try {
10169
- await listener(event);
10170
- } catch {}
10171
- })));
10172
- }
10173
10566
  }
10174
10567
 
10175
10568
  var index$1 = Object.freeze({
@@ -10186,5 +10579,96 @@ var index = Object.freeze({
10186
10579
  test: orchestrateTest
10187
10580
  });
10188
10581
 
10189
- export { AutoBeAgent, AutoBeTokenUsage, index$1 as factory, index as orchestrate };
10582
+ class AutoBeMockAgent extends AutoBeAgentBase {
10583
+ constructor(props) {
10584
+ super({
10585
+ compiler: () => this.compiler_.get(),
10586
+ state: () => createAutoBeState(this.histories_)
10587
+ });
10588
+ this.props_ = props;
10589
+ this.histories_ = [];
10590
+ this.compiler_ = new Singleton((async () => props.compiler({
10591
+ realize: {
10592
+ test: {
10593
+ onOperation: async () => {},
10594
+ onReset: async () => {}
10595
+ }
10596
+ }
10597
+ })));
10598
+ this.token_usage_ = new AutoBeTokenUsage;
10599
+ }
10600
+ async conversate(content) {
10601
+ const userMessage = {
10602
+ id: v4(),
10603
+ type: "userMessage",
10604
+ contents: typeof content === "string" ? [ {
10605
+ type: "text",
10606
+ text: content
10607
+ } ] : Array.isArray(content) ? content : [ content ],
10608
+ created_at: (new Date).toISOString()
10609
+ };
10610
+ void this.dispatch(userMessage).catch((() => {}));
10611
+ const state = createAutoBeState(this.histories_);
10612
+ if (state.test !== null) {
10613
+ const assistantMessage = {
10614
+ id: v4(),
10615
+ type: "assistantMessage",
10616
+ text: [ "You've reached to the test agent.", "", "The realize agent would be developed until 2025-08-31.", "", "Thanks for using AutoBE!" ].join("\n"),
10617
+ created_at: (new Date).toISOString(),
10618
+ completed_at: (new Date).toISOString()
10619
+ };
10620
+ void this.dispatch(assistantMessage).catch((() => {}));
10621
+ this.histories_.push(userMessage, assistantMessage);
10622
+ return this.histories_;
10623
+ }
10624
+ const take = async type => {
10625
+ for (const s of this.getEventSnapshots(type)) {
10626
+ void this.dispatch(s.event).catch((() => {}));
10627
+ this.token_usage_ = new AutoBeTokenUsage(s.tokenUsage);
10628
+ await sleep_for(sleepMap[s.event.type] ?? 500);
10629
+ }
10630
+ this.histories_.push(userMessage);
10631
+ this.histories_.push(this.props_.preset.histories.find((h => h.type === type)));
10632
+ };
10633
+ if (state.analyze === null) await take("analyze"); else if (state.prisma === null) await take("prisma"); else if (state.interface === null) await take("interface"); else if (state.test === null) await take("test");
10634
+ return this.histories_;
10635
+ }
10636
+ getHistories() {
10637
+ return this.histories_;
10638
+ }
10639
+ getTokenUsage() {
10640
+ return this.token_usage_;
10641
+ }
10642
+ getEventSnapshots(state) {
10643
+ return this.props_.preset[state];
10644
+ }
10645
+ }
10646
+
10647
+ const sleepMap = {
10648
+ analyzeStart: 1e3,
10649
+ analyzeWrite: 500,
10650
+ analyzeReview: 500,
10651
+ analyzeComplete: 500,
10652
+ prismaStart: 1e3,
10653
+ prismaComponents: 1e3,
10654
+ prismaSchemas: 500,
10655
+ prismaValidate: 2500,
10656
+ prismaCorrect: 500,
10657
+ prismaInsufficient: 1e3,
10658
+ prismaComplete: 500,
10659
+ interfaceStart: 1e3,
10660
+ interfaceEndpoints: 1e3,
10661
+ interfaceOperations: 500,
10662
+ interfaceComponents: 500,
10663
+ interfaceComplement: 2500,
10664
+ interfaceComplete: 500,
10665
+ testStart: 1e3,
10666
+ testScenario: 1e3,
10667
+ testWrite: 50,
10668
+ testValidate: 100,
10669
+ testCorrect: 250,
10670
+ testComplete: 500
10671
+ };
10672
+
10673
+ export { AutoBeAgent, AutoBeMockAgent, AutoBeTokenUsage, index$1 as factory, index as orchestrate };
10190
10674
  //# sourceMappingURL=index.mjs.map