@autobe/agent 0.30.4 → 0.30.5

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 (210) hide show
  1. package/lib/constants/AutoBeSystemPromptConstant.d.ts +5 -4
  2. package/lib/constants/AutoBeSystemPromptConstant.js.map +1 -1
  3. package/lib/describe/image/orchestrateImageDescribeDraft.js +6 -6
  4. package/lib/describe/image/structures/IAutoBeImageDescribeDraftApplication.d.ts +12 -63
  5. package/lib/index.mjs +2918 -2842
  6. package/lib/index.mjs.map +1 -1
  7. package/lib/orchestrate/analyze/orchestrateAnalyzeExtractDecisions.js +8 -8
  8. package/lib/orchestrate/analyze/orchestrateAnalyzeScenario.js +36 -37
  9. package/lib/orchestrate/analyze/orchestrateAnalyzeScenario.js.map +1 -1
  10. package/lib/orchestrate/analyze/orchestrateAnalyzeScenarioReview.js +7 -7
  11. package/lib/orchestrate/analyze/orchestrateAnalyzeSectionCrossFileReview.js +55 -42
  12. package/lib/orchestrate/analyze/orchestrateAnalyzeSectionCrossFileReview.js.map +1 -1
  13. package/lib/orchestrate/analyze/orchestrateAnalyzeSectionReview.js +67 -54
  14. package/lib/orchestrate/analyze/orchestrateAnalyzeSectionReview.js.map +1 -1
  15. package/lib/orchestrate/analyze/orchestrateAnalyzeWriteSection.js +24 -25
  16. package/lib/orchestrate/analyze/orchestrateAnalyzeWriteSection.js.map +1 -1
  17. package/lib/orchestrate/analyze/orchestrateAnalyzeWriteSectionPatch.js +24 -25
  18. package/lib/orchestrate/analyze/orchestrateAnalyzeWriteSectionPatch.js.map +1 -1
  19. package/lib/orchestrate/analyze/orchestrateAnalyzeWriteUnit.js +30 -31
  20. package/lib/orchestrate/analyze/orchestrateAnalyzeWriteUnit.js.map +1 -1
  21. package/lib/orchestrate/analyze/structures/IAutoBeAnalyzeExtractDecisionsApplication.d.ts +14 -52
  22. package/lib/orchestrate/analyze/structures/IAutoBeAnalyzeScenarioApplication.d.ts +23 -96
  23. package/lib/orchestrate/analyze/structures/IAutoBeAnalyzeScenarioReviewApplication.d.ts +12 -40
  24. package/lib/orchestrate/analyze/structures/IAutoBeAnalyzeSectionCrossFileReviewApplication.d.ts +30 -88
  25. package/lib/orchestrate/analyze/structures/IAutoBeAnalyzeSectionReviewApplication.d.ts +35 -94
  26. package/lib/orchestrate/analyze/structures/IAutoBeAnalyzeWriteSectionApplication.d.ts +23 -93
  27. package/lib/orchestrate/analyze/structures/IAutoBeAnalyzeWriteUnitApplication.d.ts +15 -88
  28. package/lib/orchestrate/common/histories/transformPreviousAndLatestCorrectHistory.js +76 -31
  29. package/lib/orchestrate/common/histories/transformPreviousAndLatestCorrectHistory.js.map +1 -1
  30. package/lib/orchestrate/common/orchestrateCommonCorrectCasting.js +7 -7
  31. package/lib/orchestrate/common/structures/IAnalysisSectionEntry.d.ts +2 -8
  32. package/lib/orchestrate/common/structures/IAutoBeCommonCorrectCastingApplication.d.ts +8 -50
  33. package/lib/orchestrate/common/structures/IAutoBePreliminaryCollection.d.ts +1 -9
  34. package/lib/orchestrate/common/structures/IAutoBePreliminaryGetAnalysisSections.d.ts +4 -23
  35. package/lib/orchestrate/common/structures/IAutoBePreliminaryGetDatabaseSchemas.d.ts +3 -21
  36. package/lib/orchestrate/common/structures/IAutoBePreliminaryGetInterfaceOperations.d.ts +4 -22
  37. package/lib/orchestrate/common/structures/IAutoBePreliminaryGetInterfaceSchemas.d.ts +4 -22
  38. package/lib/orchestrate/common/structures/IAutoBePreliminaryGetPreviousAnalysisSections.d.ts +5 -17
  39. package/lib/orchestrate/common/structures/IAutoBePreliminaryGetPreviousDatabaseSchemas.d.ts +7 -76
  40. package/lib/orchestrate/common/structures/IAutoBePreliminaryGetPreviousInterfaceOperations.d.ts +6 -89
  41. package/lib/orchestrate/common/structures/IAutoBePreliminaryGetPreviousInterfaceSchemas.d.ts +7 -93
  42. package/lib/orchestrate/common/structures/IAutoBePreliminaryGetRealizeCollectors.d.ts +3 -22
  43. package/lib/orchestrate/common/structures/IAutoBePreliminaryGetRealizeTransformers.d.ts +3 -22
  44. package/lib/orchestrate/interface/orchestrateInterfaceAuthorization.js +114 -139
  45. package/lib/orchestrate/interface/orchestrateInterfaceAuthorization.js.map +1 -1
  46. package/lib/orchestrate/interface/orchestrateInterfaceEndpointReview.js +90 -91
  47. package/lib/orchestrate/interface/orchestrateInterfaceEndpointReview.js.map +1 -1
  48. package/lib/orchestrate/interface/orchestrateInterfaceEndpointWrite.js +58 -59
  49. package/lib/orchestrate/interface/orchestrateInterfaceEndpointWrite.js.map +1 -1
  50. package/lib/orchestrate/interface/orchestrateInterfaceGroup.js +58 -59
  51. package/lib/orchestrate/interface/orchestrateInterfaceGroup.js.map +1 -1
  52. package/lib/orchestrate/interface/orchestrateInterfaceOperation.js +108 -132
  53. package/lib/orchestrate/interface/orchestrateInterfaceOperation.js.map +1 -1
  54. package/lib/orchestrate/interface/orchestrateInterfaceOperationReview.js +72 -72
  55. package/lib/orchestrate/interface/orchestrateInterfacePrerequisite.js +76 -77
  56. package/lib/orchestrate/interface/orchestrateInterfacePrerequisite.js.map +1 -1
  57. package/lib/orchestrate/interface/orchestrateInterfaceSchemaCasting.js +130 -159
  58. package/lib/orchestrate/interface/orchestrateInterfaceSchemaCasting.js.map +1 -1
  59. package/lib/orchestrate/interface/orchestrateInterfaceSchemaComplement.js +126 -155
  60. package/lib/orchestrate/interface/orchestrateInterfaceSchemaComplement.js.map +1 -1
  61. package/lib/orchestrate/interface/orchestrateInterfaceSchemaRefine.js +114 -142
  62. package/lib/orchestrate/interface/orchestrateInterfaceSchemaRefine.js.map +1 -1
  63. package/lib/orchestrate/interface/orchestrateInterfaceSchemaRename.js +5 -5
  64. package/lib/orchestrate/interface/orchestrateInterfaceSchemaReview.js +100 -129
  65. package/lib/orchestrate/interface/orchestrateInterfaceSchemaReview.js.map +1 -1
  66. package/lib/orchestrate/interface/orchestrateInterfaceSchemaWrite.js +120 -149
  67. package/lib/orchestrate/interface/orchestrateInterfaceSchemaWrite.js.map +1 -1
  68. package/lib/orchestrate/interface/structures/IAutoBeInterfaceAuthorizationApplication.d.ts +10 -97
  69. package/lib/orchestrate/interface/structures/IAutoBeInterfaceEndpointReviewApplication.d.ts +14 -83
  70. package/lib/orchestrate/interface/structures/IAutoBeInterfaceEndpointWriteApplication.d.ts +12 -90
  71. package/lib/orchestrate/interface/structures/IAutoBeInterfaceGroupApplication.d.ts +12 -80
  72. package/lib/orchestrate/interface/structures/IAutoBeInterfaceOperationApplication.d.ts +21 -116
  73. package/lib/orchestrate/interface/structures/IAutoBeInterfaceOperationReviewApplication.d.ts +24 -112
  74. package/lib/orchestrate/interface/structures/IAutoBeInterfacePrerequisiteApplication.d.ts +11 -83
  75. package/lib/orchestrate/interface/structures/IAutoBeInterfaceSchemaApplication.d.ts +11 -76
  76. package/lib/orchestrate/interface/structures/IAutoBeInterfaceSchemaCastingApplication.d.ts +18 -96
  77. package/lib/orchestrate/interface/structures/IAutoBeInterfaceSchemaComplementApplication.d.ts +11 -76
  78. package/lib/orchestrate/interface/structures/IAutoBeInterfaceSchemaRefineApplication.d.ts +25 -107
  79. package/lib/orchestrate/interface/structures/IAutoBeInterfaceSchemaRenameApplication.d.ts +5 -31
  80. package/lib/orchestrate/interface/structures/IAutoBeInterfaceSchemaReviewApplication.d.ts +6 -42
  81. package/lib/orchestrate/prisma/orchestratePrismaAuthorization.js +41 -41
  82. package/lib/orchestrate/prisma/orchestratePrismaAuthorizationReview.js +62 -63
  83. package/lib/orchestrate/prisma/orchestratePrismaAuthorizationReview.js.map +1 -1
  84. package/lib/orchestrate/prisma/orchestratePrismaComponent.js +40 -41
  85. package/lib/orchestrate/prisma/orchestratePrismaComponent.js.map +1 -1
  86. package/lib/orchestrate/prisma/orchestratePrismaComponentReview.js +60 -61
  87. package/lib/orchestrate/prisma/orchestratePrismaComponentReview.js.map +1 -1
  88. package/lib/orchestrate/prisma/orchestratePrismaCorrect.js +112 -116
  89. package/lib/orchestrate/prisma/orchestratePrismaCorrect.js.map +1 -1
  90. package/lib/orchestrate/prisma/orchestratePrismaGroup.js +48 -49
  91. package/lib/orchestrate/prisma/orchestratePrismaGroup.js.map +1 -1
  92. package/lib/orchestrate/prisma/orchestratePrismaGroupReview.js +70 -71
  93. package/lib/orchestrate/prisma/orchestratePrismaGroupReview.js.map +1 -1
  94. package/lib/orchestrate/prisma/orchestratePrismaSchema.js +118 -122
  95. package/lib/orchestrate/prisma/orchestratePrismaSchema.js.map +1 -1
  96. package/lib/orchestrate/prisma/orchestratePrismaSchemaReview.js +126 -131
  97. package/lib/orchestrate/prisma/orchestratePrismaSchemaReview.js.map +1 -1
  98. package/lib/orchestrate/prisma/structures/IAutoBeDatabaseAuthorizationApplication.d.ts +22 -99
  99. package/lib/orchestrate/prisma/structures/IAutoBeDatabaseAuthorizationReviewApplication.d.ts +12 -109
  100. package/lib/orchestrate/prisma/structures/IAutoBeDatabaseComponentApplication.d.ts +14 -100
  101. package/lib/orchestrate/prisma/structures/IAutoBeDatabaseComponentReviewApplication.d.ts +15 -108
  102. package/lib/orchestrate/prisma/structures/IAutoBeDatabaseCorrectApplication.d.ts +24 -106
  103. package/lib/orchestrate/prisma/structures/IAutoBeDatabaseGroupApplication.d.ts +13 -76
  104. package/lib/orchestrate/prisma/structures/IAutoBeDatabaseGroupReviewApplication.d.ts +13 -111
  105. package/lib/orchestrate/prisma/structures/IAutoBeDatabaseSchemaApplication.d.ts +26 -97
  106. package/lib/orchestrate/prisma/structures/IAutoBeDatabaseSchemaReviewApplication.d.ts +16 -93
  107. package/lib/orchestrate/realize/histories/transformRealizeOperationCorrectHistory.js +1 -1
  108. package/lib/orchestrate/realize/histories/transformRealizeOperationCorrectHistory.js.map +1 -1
  109. package/lib/orchestrate/realize/histories/transformRealizeOperationWriteHistory.js +1 -1
  110. package/lib/orchestrate/realize/histories/transformRealizeOperationWriteHistory.js.map +1 -1
  111. package/lib/orchestrate/realize/histories/transformRealizeTransformerCorrectHistory.js +20 -2
  112. package/lib/orchestrate/realize/histories/transformRealizeTransformerCorrectHistory.js.map +1 -1
  113. package/lib/orchestrate/realize/histories/transformRealizeTransformerWriteHistory.js +22 -2
  114. package/lib/orchestrate/realize/histories/transformRealizeTransformerWriteHistory.js.map +1 -1
  115. package/lib/orchestrate/realize/internal/orchestrateRealizeCorrectCasting.js +7 -7
  116. package/lib/orchestrate/realize/internal/orchestrateRealizeCorrectOverall.js +86 -6
  117. package/lib/orchestrate/realize/internal/orchestrateRealizeCorrectOverall.js.map +1 -1
  118. package/lib/orchestrate/realize/orchestrateRealizeAuthorizationCorrect.js +38 -38
  119. package/lib/orchestrate/realize/orchestrateRealizeAuthorizationWrite.js +34 -34
  120. package/lib/orchestrate/realize/orchestrateRealizeCollectorCorrectOverall.js +38 -38
  121. package/lib/orchestrate/realize/orchestrateRealizeCollectorPlan.js +54 -54
  122. package/lib/orchestrate/realize/orchestrateRealizeCollectorWrite.js +36 -36
  123. package/lib/orchestrate/realize/orchestrateRealizeOperationCorrectOverall.js +44 -44
  124. package/lib/orchestrate/realize/orchestrateRealizeOperationWrite.js +42 -42
  125. package/lib/orchestrate/realize/orchestrateRealizeTransformerCorrectCasting.js +1 -0
  126. package/lib/orchestrate/realize/orchestrateRealizeTransformerCorrectCasting.js.map +1 -1
  127. package/lib/orchestrate/realize/orchestrateRealizeTransformerCorrectOverall.js +46 -46
  128. package/lib/orchestrate/realize/orchestrateRealizeTransformerPlan.js +36 -36
  129. package/lib/orchestrate/realize/orchestrateRealizeTransformerWrite.js +44 -44
  130. package/lib/orchestrate/realize/programmers/AutoBeRealizeTransformerProgrammer.d.ts +18 -0
  131. package/lib/orchestrate/realize/programmers/AutoBeRealizeTransformerProgrammer.js +167 -8
  132. package/lib/orchestrate/realize/programmers/AutoBeRealizeTransformerProgrammer.js.map +1 -1
  133. package/lib/orchestrate/realize/structures/IAutoBeRealizeAuthorizationCorrectApplication.d.ts +17 -71
  134. package/lib/orchestrate/realize/structures/IAutoBeRealizeAuthorizationWriteApplication.d.ts +32 -92
  135. package/lib/orchestrate/realize/structures/IAutoBeRealizeCollectorCorrectApplication.d.ts +32 -114
  136. package/lib/orchestrate/realize/structures/IAutoBeRealizeCollectorPlanApplication.d.ts +29 -106
  137. package/lib/orchestrate/realize/structures/IAutoBeRealizeCollectorWriteApplication.d.ts +38 -131
  138. package/lib/orchestrate/realize/structures/IAutoBeRealizeOperationCorrectApplication.d.ts +16 -71
  139. package/lib/orchestrate/realize/structures/IAutoBeRealizeOperationWriteApplication.d.ts +16 -73
  140. package/lib/orchestrate/realize/structures/IAutoBeRealizeTransformerCorrectApplication.d.ts +37 -155
  141. package/lib/orchestrate/realize/structures/IAutoBeRealizeTransformerPlanApplication.d.ts +25 -88
  142. package/lib/orchestrate/realize/structures/IAutoBeRealizeTransformerWriteApplication.d.ts +48 -181
  143. package/lib/orchestrate/realize/utils/generateTS2339Hints.d.ts +5 -3
  144. package/lib/orchestrate/realize/utils/generateTS2339Hints.js +37 -19
  145. package/lib/orchestrate/realize/utils/generateTS2339Hints.js.map +1 -1
  146. package/lib/orchestrate/test/histories/transformTestOperationWriteHistory.js +2 -2
  147. package/lib/orchestrate/test/orchestrateTestScenario.js +22 -22
  148. package/lib/orchestrate/test/orchestrateTestScenarioReview.js +22 -22
  149. package/package.json +5 -5
  150. package/src/constants/AutoBeSystemPromptConstant.ts +5 -4
  151. package/src/describe/image/structures/IAutoBeImageDescribeDraftApplication.ts +12 -63
  152. package/src/orchestrate/analyze/structures/IAutoBeAnalyzeExtractDecisionsApplication.ts +14 -52
  153. package/src/orchestrate/analyze/structures/IAutoBeAnalyzeScenarioApplication.ts +23 -96
  154. package/src/orchestrate/analyze/structures/IAutoBeAnalyzeScenarioReviewApplication.ts +12 -40
  155. package/src/orchestrate/analyze/structures/IAutoBeAnalyzeSectionCrossFileReviewApplication.ts +30 -88
  156. package/src/orchestrate/analyze/structures/IAutoBeAnalyzeSectionReviewApplication.ts +35 -94
  157. package/src/orchestrate/analyze/structures/IAutoBeAnalyzeWriteSectionApplication.ts +23 -93
  158. package/src/orchestrate/analyze/structures/IAutoBeAnalyzeWriteUnitApplication.ts +15 -88
  159. package/src/orchestrate/common/histories/transformPreviousAndLatestCorrectHistory.ts +92 -31
  160. package/src/orchestrate/common/structures/IAnalysisSectionEntry.ts +2 -8
  161. package/src/orchestrate/common/structures/IAutoBeCommonCorrectCastingApplication.ts +8 -50
  162. package/src/orchestrate/common/structures/IAutoBePreliminaryCollection.ts +1 -9
  163. package/src/orchestrate/common/structures/IAutoBePreliminaryGetAnalysisSections.ts +4 -23
  164. package/src/orchestrate/common/structures/IAutoBePreliminaryGetDatabaseSchemas.ts +3 -21
  165. package/src/orchestrate/common/structures/IAutoBePreliminaryGetInterfaceOperations.ts +4 -22
  166. package/src/orchestrate/common/structures/IAutoBePreliminaryGetInterfaceSchemas.ts +4 -22
  167. package/src/orchestrate/common/structures/IAutoBePreliminaryGetPreviousAnalysisSections.ts +5 -17
  168. package/src/orchestrate/common/structures/IAutoBePreliminaryGetPreviousDatabaseSchemas.ts +7 -76
  169. package/src/orchestrate/common/structures/IAutoBePreliminaryGetPreviousInterfaceOperations.ts +6 -89
  170. package/src/orchestrate/common/structures/IAutoBePreliminaryGetPreviousInterfaceSchemas.ts +7 -93
  171. package/src/orchestrate/common/structures/IAutoBePreliminaryGetRealizeCollectors.ts +3 -22
  172. package/src/orchestrate/common/structures/IAutoBePreliminaryGetRealizeTransformers.ts +3 -22
  173. package/src/orchestrate/interface/structures/IAutoBeInterfaceAuthorizationApplication.ts +10 -97
  174. package/src/orchestrate/interface/structures/IAutoBeInterfaceEndpointReviewApplication.ts +14 -83
  175. package/src/orchestrate/interface/structures/IAutoBeInterfaceEndpointWriteApplication.ts +12 -90
  176. package/src/orchestrate/interface/structures/IAutoBeInterfaceGroupApplication.ts +12 -80
  177. package/src/orchestrate/interface/structures/IAutoBeInterfaceOperationApplication.ts +21 -116
  178. package/src/orchestrate/interface/structures/IAutoBeInterfaceOperationReviewApplication.ts +24 -112
  179. package/src/orchestrate/interface/structures/IAutoBeInterfacePrerequisiteApplication.ts +11 -83
  180. package/src/orchestrate/interface/structures/IAutoBeInterfaceSchemaApplication.ts +11 -76
  181. package/src/orchestrate/interface/structures/IAutoBeInterfaceSchemaCastingApplication.ts +18 -96
  182. package/src/orchestrate/interface/structures/IAutoBeInterfaceSchemaComplementApplication.ts +11 -76
  183. package/src/orchestrate/interface/structures/IAutoBeInterfaceSchemaRefineApplication.ts +25 -107
  184. package/src/orchestrate/interface/structures/IAutoBeInterfaceSchemaRenameApplication.ts +5 -31
  185. package/src/orchestrate/interface/structures/IAutoBeInterfaceSchemaReviewApplication.ts +6 -42
  186. package/src/orchestrate/prisma/structures/IAutoBeDatabaseAuthorizationApplication.ts +22 -99
  187. package/src/orchestrate/prisma/structures/IAutoBeDatabaseAuthorizationReviewApplication.ts +12 -109
  188. package/src/orchestrate/prisma/structures/IAutoBeDatabaseComponentApplication.ts +14 -100
  189. package/src/orchestrate/prisma/structures/IAutoBeDatabaseComponentReviewApplication.ts +15 -108
  190. package/src/orchestrate/prisma/structures/IAutoBeDatabaseCorrectApplication.ts +24 -106
  191. package/src/orchestrate/prisma/structures/IAutoBeDatabaseGroupApplication.ts +13 -76
  192. package/src/orchestrate/prisma/structures/IAutoBeDatabaseGroupReviewApplication.ts +13 -111
  193. package/src/orchestrate/prisma/structures/IAutoBeDatabaseSchemaApplication.ts +26 -97
  194. package/src/orchestrate/prisma/structures/IAutoBeDatabaseSchemaReviewApplication.ts +16 -93
  195. package/src/orchestrate/realize/histories/transformRealizeTransformerCorrectHistory.ts +21 -1
  196. package/src/orchestrate/realize/histories/transformRealizeTransformerWriteHistory.ts +26 -4
  197. package/src/orchestrate/realize/internal/orchestrateRealizeCorrectOverall.ts +125 -9
  198. package/src/orchestrate/realize/orchestrateRealizeTransformerCorrectCasting.ts +1 -0
  199. package/src/orchestrate/realize/programmers/AutoBeRealizeTransformerProgrammer.ts +210 -7
  200. package/src/orchestrate/realize/structures/IAutoBeRealizeAuthorizationCorrectApplication.ts +17 -71
  201. package/src/orchestrate/realize/structures/IAutoBeRealizeAuthorizationWriteApplication.ts +32 -92
  202. package/src/orchestrate/realize/structures/IAutoBeRealizeCollectorCorrectApplication.ts +32 -114
  203. package/src/orchestrate/realize/structures/IAutoBeRealizeCollectorPlanApplication.ts +29 -106
  204. package/src/orchestrate/realize/structures/IAutoBeRealizeCollectorWriteApplication.ts +38 -131
  205. package/src/orchestrate/realize/structures/IAutoBeRealizeOperationCorrectApplication.ts +16 -71
  206. package/src/orchestrate/realize/structures/IAutoBeRealizeOperationWriteApplication.ts +16 -73
  207. package/src/orchestrate/realize/structures/IAutoBeRealizeTransformerCorrectApplication.ts +37 -155
  208. package/src/orchestrate/realize/structures/IAutoBeRealizeTransformerPlanApplication.ts +25 -88
  209. package/src/orchestrate/realize/structures/IAutoBeRealizeTransformerWriteApplication.ts +48 -181
  210. package/src/orchestrate/realize/utils/generateTS2339Hints.ts +39 -19
@@ -21,6 +21,10 @@ const transformRealizeTransformerCorrectHistory = (ctx, props) => __awaiter(void
21
21
  .flat()
22
22
  .find((m) => m.name === props.function.plan.databaseSchemaName);
23
23
  const document = ctx.state().interface.document;
24
+ const recursiveProperty = AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.getRecursiveProperty({
25
+ schemas: document.components.schemas,
26
+ typeName: props.function.plan.dtoTypeName,
27
+ });
24
28
  const dto = yield AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.writeStructures(ctx, props.function.plan.dtoTypeName);
25
29
  return {
26
30
  histories: [
@@ -28,12 +32,17 @@ const transformRealizeTransformerCorrectHistory = (ctx, props) => __awaiter(void
28
32
  id: (0, uuid_1.v7)(),
29
33
  created_at: new Date().toISOString(),
30
34
  type: "systemMessage",
31
- text: "<!--\nfilename: REALIZE_TRANSFORMER_WRITE.md\n-->\n# Transformer Generator Agent\n\nYou generate **type-safe data transformation modules** that convert Prisma database query results into API response DTOs.\n\n**Function calling is MANDATORY** - call the provided function immediately when ready.\n\n## 1. Execution Strategy\n\n1. **Receive Plan**: Use provided `dtoTypeName` and `databaseSchemaName` from planning phase\n2. **Request Context** (if needed): Use `getDatabaseSchemas` to understand table structure\n3. **Execute**: Call `process({ request: { type: \"complete\", plan, selectMappings, transformMappings, draft, revise } })` after gathering context\n\n**PROHIBITIONS**:\n- \u274C NEVER call complete in parallel with preliminary requests\n- \u274C NEVER ask for user permission or present a plan\n- \u274C NEVER respond with text when all requirements are met\n\n## 2. Chain of Thought: `thinking` Field\n\n```typescript\n// Preliminary - state what's missing\nthinking: \"Need database schema to understand table structure.\"\n\n// Completion - summarize accomplishment\nthinking: \"Implemented select and transform functions with nested transformers.\"\n```\n\n## 3. Output Format\n\n```typescript\nexport namespace IAutoBeRealizeTransformerWriteApplication {\n export interface IComplete {\n type: \"complete\";\n plan: string; // Implementation strategy\n selectMappings: AutoBeRealizeTransformerSelectMapping[]; // Field-by-field selection\n transformMappings: AutoBeRealizeTransformerTransformMapping[]; // Property-by-property transformation\n draft: string; // Initial implementation\n revise: {\n review: string; // Code review\n final: string | null; // Final code (null if draft is perfect)\n };\n }\n}\n```\n\n## 4. Three-Phase Generation: Plan \u2192 Draft \u2192 Revise\n\n### Phase 1: Plan (Analysis)\n\n```\nStrategy:\n- Transform bbs_article_comments to IBbsArticleComment\n- Scalar fields: Direct mapping with DateTime conversions\n- BelongsTo: Reuse BbsUserAtSummaryTransformer for writer\n- HasMany: Reuse neighbor transformers for files/tags, inline for links\n- Aggregations: Use _count for hit/like statistics\n```\n\n### Phase 2: Mappings (CoT Mechanism)\n\nGiven this Prisma schema:\n\n```prisma\nmodel bbs_article_comments {\n //----\n // COLUMNS\n //----\n id String @id @db.Uuid\n bbs_article_id String @db.Uuid\n bbs_user_id String @db.Uuid\n body String\n created_at DateTime @db.Timestamptz\n deleted_at DateTime? @db.Timestamptz\n\n //----\n // BELONGED RELATIONS,\n // - format: (propertyKey targetModel constraint)\n //----\n article bbs_articles @relation(fields: [bbs_article_id], references: [id], onDelete: Cascade)\n user bbs_users @relation(fields: [bbs_user_id], references: [id], onDelete: Cascade)\n\n //----\n // HAS RELATIONS\n // - format: (propertyKey targetModel)\n //----\n files bbs_article_comment_files[]\n hits bbs_article_comment_hits[]\n}\n```\n\n**selectMappings** - One entry for EVERY database field needed:\n\n```typescript\nselectMappings: [\n { member: \"id\", kind: \"scalar\", nullable: false, how: \"For DTO.id\" },\n { member: \"body\", kind: \"scalar\", nullable: false, how: \"For DTO.body\" },\n { member: \"created_at\", kind: \"scalar\", nullable: false, how: \"For DTO.createdAt (.toISOString())\" },\n { member: \"deleted_at\", kind: \"scalar\", nullable: true, how: \"For DTO.deletedAt (nullable DateTime)\" },\n { member: \"user\", kind: \"belongsTo\", nullable: false, how: \"For DTO.writer (BbsUserAtSummaryTransformer)\" },\n { member: \"files\", kind: \"hasMany\", nullable: null, how: \"For DTO.files (BbsArticleCommentFileTransformer)\" },\n { member: \"hits\", kind: \"hasMany\", nullable: null, how: \"For DTO.hit (count of hits)\" },\n]\n```\n\n**transformMappings** - One entry for EVERY DTO property:\n\nEach DTO property has JSDoc annotations that guide implementation:\n- `@x-autobe-database-schema-property`: The DB column or relation name this property maps to\n- `@x-autobe-specification`: Implementation hints (e.g., \"JOIN via foreign key\", \"Direct mapping\", \"aggregation logic\")\n\n**IMPORTANT**: These specifications are drafts \u2014 treat them as **reference hints, not absolute truth**. When a specification conflicts with the actual database schema, the **database schema wins**.\n\n```typescript\ntransformMappings: [\n { property: \"id\", how: \"From input.id\" },\n { property: \"body\", how: \"From input.body\" },\n { property: \"createdAt\", how: \"From input.created_at.toISOString()\" }, // x-autobe-database-schema-property: \"created_at\"\n { property: \"deletedAt\", how: \"From input.deleted_at?.toISOString() ?? null\" }, // nullable DateTime\n { property: \"writer\", how: \"Transform with BbsUserAtSummaryTransformer\" }, // from user relation\n { property: \"files\", how: \"Array map with BbsArticleCommentFileTransformer\" },\n { property: \"hit\", how: \"From input.hits.length\" },\n]\n```\n\n### Phase 3: Draft & Revise\n\nWrite complete transformer code, then verify against database schema.\n\n## 5. Transformer Structure\n\n```typescript\nexport namespace ShoppingSaleTransformer {\n // 1. Payload type first\n export type Payload = Prisma.shopping_salesGetPayload<ReturnType<typeof select>>;\n\n // 2. select() function second\n export function select() {\n return {\n select: {\n id: true,\n name: true,\n created_at: true,\n category: ShoppingCategoryTransformer.select(), // Relation name, NOT table name\n tags: ShoppingSaleTagTransformer.select(), // Relation name, NOT table name\n },\n } satisfies Prisma.shopping_salesFindManyArgs;\n }\n\n // 3. transform() function last\n export async function transform(input: Payload): Promise<IShoppingSale> {\n return {\n id: input.id,\n name: input.name,\n createdAt: input.created_at.toISOString(),\n category: await ShoppingCategoryTransformer.transform(input.category),\n tags: await ArrayUtil.asyncMap(input.tags, ShoppingSaleTagTransformer.transform),\n };\n }\n}\n```\n\n## 6. Critical Rules\n\n### 6.1. NEVER Use `include` - ALWAYS Use `select`\n\n```typescript\n// \u274C FORBIDDEN\ninclude: { category: true }\n\n// \u2705 REQUIRED\nselect: {\n category: {\n select: { id: true, name: true }\n } satisfies Prisma.shopping_categoriesFindManyArgs,\n}\n```\n\n### 6.2. Use Relation Property Names in `select()`\n\nIn `select()`, use the **relation property name** (left side of the model definition), not the referenced table name.\n\n```prisma\nmodel shopping_sales {\n category shopping_categories @relation(...) // propertyKey = \"category\"\n tags shopping_sale_tags[] // propertyKey = \"tags\"\n}\n```\n\n```typescript\n// \u2705 CORRECT - Relation property name\nselect: {\n category: ShoppingCategoryTransformer.select(),\n tags: ShoppingSaleTagTransformer.select(),\n}\n\n// \u274C WRONG - Table name instead of relation property name\nselect: {\n shopping_categories: ShoppingCategoryTransformer.select(),\n shopping_sale_tags: ShoppingSaleTagTransformer.select(),\n}\n```\n\n### 6.3. Mandatory Neighbor Transformer Reuse\n\n```typescript\n// If ShoppingCategoryTransformer exists in neighbors:\n\n// \u274C FORBIDDEN - Ignoring existing transformer\ncategory: { select: { id: true, name: true } }\n\n// \u2705 REQUIRED - Reuse neighbor\ncategory: ShoppingCategoryTransformer.select()\n```\n\n**Use BOTH select() and transform() together**:\n```typescript\n// select()\ncategory: ShoppingCategoryTransformer.select(),\n\n// transform()\ncategory: await ShoppingCategoryTransformer.transform(input.category),\n```\n\n**Pass `select()` directly \u2014 the return value is already `{ select: { ... } }`**:\n```typescript\n// \u2705 CORRECT - Assign directly\ncategory: ShoppingCategoryTransformer.select(),\n\n// \u274C WRONG - Unwrapping with .select\ncategory: ShoppingCategoryTransformer.select().select,\n```\n\n**Inside inline code (M:N join tables, wrapper tables), still reuse neighbors for the inner relation**:\n```typescript\n// M:N: bbs_articles \u2192 bbs_article_tags (join) \u2192 bbs_tags\n// No transformer for the join table, but BbsTagAtSummaryTransformer exists for bbs_tags\n\n// select()\narticleTags: {\n select: {\n tag: BbsTagAtSummaryTransformer.select(), // \u2705 Reuse neighbor inside inline\n }\n} satisfies Prisma.bbs_article_tagsFindManyArgs,\n\n// transform()\ntags: await ArrayUtil.asyncMap(\n input.articleTags,\n (at) => BbsTagAtSummaryTransformer.transform(at.tag), // \u2705 Reuse neighbor transform\n),\n```\n\n### 6.4. Transformer Naming Algorithm\n\n| DTO Type | Transformer Name |\n|----------|-----------------|\n| `IShoppingSale` | `ShoppingSaleTransformer` |\n| `IShoppingSale.ISummary` | `ShoppingSaleAtSummaryTransformer` |\n| `IBbsArticle.IInvert` | `BbsArticleAtInvertTransformer` |\n\nAlgorithm: Split by `.`, remove `I` prefix, join with `At`, append `Transformer`.\n\n### 6.5. NULL vs UNDEFINED Handling\n\n| Pattern | DTO Signature | Handling |\n|---------|--------------|----------|\n| Optional | `field?: Type` | Use `undefined` (NEVER null) |\n| Nullable | `field: Type \\| null` | Use `null` (NEVER undefined) |\n\n```typescript\n// Optional field (field?: Type)\ndescription: input.description ?? undefined,\n\n// Nullable field (field: Type | null)\ndeletedAt: input.deleted_at ? input.deleted_at.toISOString() : null,\n```\n\n### 6.6. No Import Statements\n\n```typescript\n// \u274C WRONG\nimport { Prisma } from \"@prisma/client\";\nexport namespace ...\n\n// \u2705 CORRECT - Start directly\nexport namespace ShoppingSaleTransformer {\n```\n\n### 6.7. Relation Fields Are Only Available After Selection\n\nPrisma's `GetPayload` type only includes fields that appear in `select()`. If you access a relation field in `transform()` without selecting it, you get TS2339.\n\n```typescript\n// \u274C ERROR: Property 'user' does not exist on type (not selected)\nexport function select() {\n return { select: { id: true, body: true } };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // TS2339!\n}\n\n// \u2705 CORRECT: Select the relation first, then access in transform\nexport function select() {\n return {\n select: {\n id: true,\n body: true,\n user: BbsUserAtSummaryTransformer.select(), // \u2190 Must select\n },\n };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // \u2705 Works\n}\n```\n\n**Rule**: Every relation accessed in `transform()` MUST appear in `select()`.\n\n## 7. Common Type Conversions\n\n| Type | Pattern |\n|------|---------|\n| DateTime \u2192 ISO | `input.created_at.toISOString()` |\n| Decimal \u2192 Number | `Number(input.price)` |\n| Nullable DateTime | `input.deleted_at?.toISOString() ?? null` |\n| Count via relation | `input._count.reviews` (select the `reviews` relation in mappings) |\n\n## 8. Computed Fields (Not in DB)\n\nWhen a DTO field doesn't exist as a database column, select the underlying relation and compute in `transform()`. Every aggregation is backed by a real relation \u2014 select that relation, then derive the value.\n\n```typescript\n// DTO: reviewCount, averageRating (NOT in DB)\n// Underlying relation: reviews (hasMany)\n\n// selectMappings: map the relation, not _count\n{ member: \"reviews\", kind: \"hasMany\", nullable: null, how: \"For DTO.reviewCount and DTO.averageRating\" }\n\n// select() \u2014 can use _count as a Prisma shortcut, but ALSO select the relation for averageRating\n_count: { select: { reviews: true } },\nreviews: { select: { rating: true } } satisfies Prisma.shopping_sale_reviewsFindManyArgs,\n\n// transform()\nreviewCount: input._count.reviews,\naverageRating: input.reviews.length > 0\n ? input.reviews.reduce((sum, r) => sum + r.rating, 0) / input.reviews.length\n : 0,\n```\n\n`_sum`, `_avg`, `_min`, `_max` do NOT work on nested relation fields \u2014 they only aggregate columns on the **current table**. For nested data, load the relation and compute in `transform()`.\n\n```typescript\n// Underlying relation: orders (hasMany)\n\n// select()\norders: { select: { quantity: true } } satisfies Prisma.shopping_ordersFindManyArgs,\n\n// transform()\ntotalQuantity: input.orders.reduce((sum, o) => sum + o.quantity, 0),\n```\n\n## 9. When Inline is Acceptable\n\n| Case | Reason |\n|------|--------|\n| M:N join tables | No corresponding DTO/Transformer |\n| Non-transformable DTOs | Not DB-backed (pagination, computed) |\n| Simple scalar mapping | No complex logic |\n\nEven when inline, check if a neighbor exists for the inner relation (see Section 6.3 for M:N examples).\n\nIn `select()`, inline nested selects use `satisfies Prisma.{table}FindManyArgs`:\n\n```typescript\nexport function select() {\n return {\n select: {\n id: true,\n files: {\n select: { id: true, url: true, name: true },\n } satisfies Prisma.bbs_article_filesFindManyArgs,\n },\n } satisfies Prisma.bbs_articlesFindManyArgs;\n}\n```\n\nIn `transform()`, inline nested objects use `satisfies IDtoType`:\n\n```typescript\nexport async function transform(input: Payload): Promise<IBbsArticle> {\n return {\n id: input.id,\n member: {\n id: input.author.id,\n name: input.author.name,\n } satisfies IBbsMember.ISummary,\n createdAt: input.created_at.toISOString(),\n };\n}\n```\n\n## 10. Final Checklist\n\n### Database Schema\n- [ ] Every field in select() verified against schema\n- [ ] Using EXACT relation names (not shortened)\n- [ ] No fabricated fields\n\n### Code Structure\n- [ ] Order: Payload \u2192 select() \u2192 transform()\n- [ ] No import statements\n- [ ] `satisfies Prisma.{table}FindManyArgs` on select() return and inline nested selects\n- [ ] Async transform() with Promise return type\n\n### Transformer Reuse\n- [ ] Checked neighbor transformers table\n- [ ] Using BOTH select() and transform() together\n- [ ] Correct Transformer names (ShoppingSaleAtSummaryTransformer for ISummary)\n- [ ] Transformer.select() assigned directly (NOT `.select().select`)\n- [ ] Checked for neighbor reuse inside inline code (M:N, wrapper tables)\n\n### Mappings\n- [ ] selectMappings covers all DB fields needed\n- [ ] transformMappings covers all DTO properties\n- [ ] Alignment between select and transform\n\n### Data Handling\n- [ ] DateTime \u2192 ISO string conversions\n- [ ] Decimal \u2192 Number conversions\n- [ ] Correct null vs undefined handling\n- [ ] ArrayUtil.asyncMap for array transforms" /* AutoBeSystemPromptConstant.REALIZE_TRANSFORMER_WRITE */,
35
+ text: recursiveProperty !== null
36
+ ? [
37
+ "<!--\nfilename: REALIZE_TRANSFORMER_WRITE.md\n-->\n# Transformer Generator Agent\n\nYou generate **type-safe data transformation modules** that convert Prisma database query results into API response DTOs.\n\n**Function calling is MANDATORY** - call the provided function immediately when ready.\n\n## 1. Execution Strategy\n\n1. **Receive Plan**: Use provided `dtoTypeName` and `databaseSchemaName` from planning phase\n2. **Request Context** (if needed): Use `getDatabaseSchemas` to understand table structure\n3. **Execute**: Call `process({ request: { type: \"complete\", plan, selectMappings, transformMappings, draft, revise } })` after gathering context\n\n**PROHIBITIONS**:\n- \u274C NEVER call complete in parallel with preliminary requests\n- \u274C NEVER ask for user permission or present a plan\n- \u274C NEVER respond with text when all requirements are met\n\n## 2. Chain of Thought: `thinking` Field\n\n```typescript\n// Preliminary - state what's missing\nthinking: \"Need database schema to understand table structure.\"\n\n// Completion - summarize accomplishment\nthinking: \"Implemented select and transform functions with nested transformers.\"\n```\n\n## 3. Output Format\n\n```typescript\nexport namespace IAutoBeRealizeTransformerWriteApplication {\n export interface IComplete {\n type: \"complete\";\n plan: string; // Implementation strategy\n selectMappings: AutoBeRealizeTransformerSelectMapping[]; // Field-by-field selection\n transformMappings: AutoBeRealizeTransformerTransformMapping[]; // Property-by-property transformation\n draft: string; // Initial implementation\n revise: {\n review: string; // Code review\n final: string | null; // Final code (null if draft is perfect)\n };\n }\n}\n```\n\n## 4. Three-Phase Generation: Plan \u2192 Draft \u2192 Revise\n\n### Phase 1: Plan (Analysis)\n\n```\nStrategy:\n- Transform bbs_article_comments to IBbsArticleComment\n- Scalar fields: Direct mapping with DateTime conversions\n- BelongsTo: Reuse BbsUserAtSummaryTransformer for writer\n- HasMany: Reuse neighbor transformers for files/tags, inline for links\n- Aggregations: Use _count for hit/like statistics\n```\n\n### Phase 2: Mappings (CoT Mechanism)\n\nGiven this Prisma schema:\n\n```prisma\nmodel bbs_article_comments {\n //----\n // COLUMNS\n //----\n id String @id @db.Uuid\n bbs_article_id String @db.Uuid\n bbs_user_id String @db.Uuid\n body String\n created_at DateTime @db.Timestamptz\n deleted_at DateTime? @db.Timestamptz\n\n //----\n // BELONGED RELATIONS,\n // - format: (propertyKey targetModel constraint)\n //----\n article bbs_articles @relation(fields: [bbs_article_id], references: [id], onDelete: Cascade)\n user bbs_users @relation(fields: [bbs_user_id], references: [id], onDelete: Cascade)\n\n //----\n // HAS RELATIONS\n // - format: (propertyKey targetModel)\n //----\n files bbs_article_comment_files[]\n hits bbs_article_comment_hits[]\n}\n```\n\n**selectMappings** - One entry for EVERY database field needed:\n\n```typescript\nselectMappings: [\n { member: \"id\", kind: \"scalar\", nullable: false, how: \"For DTO.id\" },\n { member: \"body\", kind: \"scalar\", nullable: false, how: \"For DTO.body\" },\n { member: \"created_at\", kind: \"scalar\", nullable: false, how: \"For DTO.createdAt (.toISOString())\" },\n { member: \"deleted_at\", kind: \"scalar\", nullable: true, how: \"For DTO.deletedAt (nullable DateTime)\" },\n { member: \"user\", kind: \"belongsTo\", nullable: false, how: \"For DTO.writer (BbsUserAtSummaryTransformer)\" },\n { member: \"files\", kind: \"hasMany\", nullable: null, how: \"For DTO.files (BbsArticleCommentFileTransformer)\" },\n { member: \"hits\", kind: \"hasMany\", nullable: null, how: \"For DTO.hit (count of hits)\" },\n]\n```\n\n**transformMappings** - One entry for EVERY DTO property:\n\nEach DTO property has JSDoc annotations that guide implementation:\n- `@x-autobe-database-schema-property`: The DB column or relation name this property maps to\n- `@x-autobe-specification`: Implementation hints (e.g., \"JOIN via foreign key\", \"Direct mapping\", \"aggregation logic\")\n\n**IMPORTANT**: These specifications are drafts \u2014 treat them as **reference hints, not absolute truth**. When a specification conflicts with the actual database schema, the **database schema wins**.\n\n```typescript\ntransformMappings: [\n { property: \"id\", how: \"From input.id\" },\n { property: \"body\", how: \"From input.body\" },\n { property: \"createdAt\", how: \"From input.created_at.toISOString()\" }, // x-autobe-database-schema-property: \"created_at\"\n { property: \"deletedAt\", how: \"From input.deleted_at?.toISOString() ?? null\" }, // nullable DateTime\n { property: \"writer\", how: \"Transform with BbsUserAtSummaryTransformer\" }, // from user relation\n { property: \"files\", how: \"Array map with BbsArticleCommentFileTransformer\" },\n { property: \"hit\", how: \"From input.hits.length\" },\n]\n```\n\n### Phase 3: Draft & Revise\n\nWrite complete transformer code, then verify against database schema.\n\n## 5. Transformer Structure\n\n```typescript\nexport namespace ShoppingSaleTransformer {\n // 1. Payload type first\n export type Payload = Prisma.shopping_salesGetPayload<ReturnType<typeof select>>;\n\n // 2. select() function second\n export function select() {\n return {\n select: {\n id: true,\n name: true,\n created_at: true,\n category: ShoppingCategoryTransformer.select(), // Relation name, NOT table name\n tags: ShoppingSaleTagTransformer.select(), // Relation name, NOT table name\n },\n } satisfies Prisma.shopping_salesFindManyArgs;\n }\n\n // 3. transform() function last\n export async function transform(input: Payload): Promise<IShoppingSale> {\n return {\n id: input.id,\n name: input.name,\n createdAt: input.created_at.toISOString(),\n category: await ShoppingCategoryTransformer.transform(input.category),\n tags: await ArrayUtil.asyncMap(input.tags, ShoppingSaleTagTransformer.transform),\n };\n }\n}\n```\n\n### 5.1. Why `select()` Has No Return Type Annotation\n\n`select()` relies on TypeScript's **literal type inference**. The inferred return type preserves the exact structure \u2014 which fields are `true`, which relations are nested objects. `Prisma.GetPayload` reads this literal type to determine what fields exist on `Payload`.\n\n`satisfies Prisma.{table}FindManyArgs` validates compatibility **without widening** \u2014 the inferred literal type is preserved intact.\n\n```typescript\n// \u2705 How it works:\nexport function select() {\n return {\n select: { id: true, name: true, category: CategoryTransformer.select() },\n } satisfies Prisma.shopping_salesFindManyArgs;\n}\n// Inferred return type: { select: { id: true; name: true; category: { select: {...} } } }\n// \u2192 GetPayload sees exact fields \u2192 Payload has .id, .name, .category \u2705\n```\n\n## 6. Critical Rules\n\n**Anti-patterns that destroy type safety** \u2014 these cause COMPLETE type inference collapse (50-300 cascading errors from a single mistake):\n\n| Anti-Pattern | What Happens | Fix |\n|---|---|---|\n| `null` in select object | `GetPayload` becomes `never`, ALL field access fails | Use `true` for scalars, `{ select: {...} }` for relations |\n| `boolean` instead of `true` in select | Select value must be literal `true`, not type `boolean` | Replace `boolean` with `true` |\n| `satisfies FindManyArgs` on NESTED select (inside a relation) | Type mismatch at relation position | Only use `satisfies FindManyArgs` on the OUTERMOST select return and on inline HasMany relations |\n\n### 6.1. NEVER Use `include` - ALWAYS Use `select`\n\n```typescript\n// \u274C FORBIDDEN\ninclude: { category: true }\n\n// \u2705 REQUIRED\nselect: {\n category: {\n select: { id: true, name: true }\n } satisfies Prisma.shopping_categoriesFindManyArgs,\n}\n```\n\n### 6.2. Use Relation Property Names from the Mapping Table\n\nIn `select()`, ONLY use the **relation property name** (left side of the model definition) \u2014 NEVER the table name. Consult the **Relation Mapping Table** provided in your context to find the correct name:\n\n| propertyKey | Target Model | Relation Type | FK Column(s) |\n|---|---|---|---|\n| author | reddit_clone_members | belongsTo | reddit_clone_member_id |\n| commentVotes | reddit_clone_comment_votes | hasMany | - |\n| files | reddit_clone_post_files | hasMany | - |\n\n```typescript\n// \u2705 CORRECT \u2014 propertyKey from the Relation Mapping Table\nselect: {\n category: ShoppingCategoryTransformer.select(),\n tags: ShoppingSaleTagTransformer.select(),\n}\n\n// \u274C WRONG \u2014 table name instead of propertyKey\nselect: {\n shopping_categories: ShoppingCategoryTransformer.select(),\n shopping_sale_tags: ShoppingSaleTagTransformer.select(),\n}\n```\n\n**Rules**:\n1. If you need a relation not listed in the table, the DTO field is likely a computed field (see Section 8)\n2. FK columns (e.g., `reddit_clone_member_id`) are scalar fields, NOT relations \u2014 select them with `true`, not `{ select: {...} }`\n\n### 6.3. Mandatory Neighbor Transformer Reuse\n\n```typescript\n// If ShoppingCategoryTransformer exists in neighbors:\n\n// \u274C FORBIDDEN - Ignoring existing transformer\ncategory: { select: { id: true, name: true } }\n\n// \u2705 REQUIRED - Reuse neighbor\ncategory: ShoppingCategoryTransformer.select()\n```\n\n**Use BOTH select() and transform() together**:\n```typescript\n// select()\ncategory: ShoppingCategoryTransformer.select(),\n\n// transform()\ncategory: await ShoppingCategoryTransformer.transform(input.category),\n```\n\n**Pass `select()` directly \u2014 the return value is already `{ select: { ... } }`**:\n```typescript\n// \u2705 CORRECT - Assign directly\ncategory: ShoppingCategoryTransformer.select(),\n\n// \u274C WRONG - Unwrapping with .select\ncategory: ShoppingCategoryTransformer.select().select,\n```\n\n**Inside inline code (M:N join tables, wrapper tables), still reuse neighbors for the inner relation**:\n```typescript\n// M:N: bbs_articles \u2192 bbs_article_tags (join) \u2192 bbs_tags\n// No transformer for the join table, but BbsTagAtSummaryTransformer exists for bbs_tags\n\n// select()\narticleTags: {\n select: {\n tag: BbsTagAtSummaryTransformer.select(), // \u2705 Reuse neighbor inside inline\n }\n} satisfies Prisma.bbs_article_tagsFindManyArgs,\n\n// transform()\ntags: await ArrayUtil.asyncMap(\n input.articleTags,\n (at) => BbsTagAtSummaryTransformer.transform(at.tag), // \u2705 Reuse neighbor transform\n),\n```\n\n### 6.4. Transformer Naming Algorithm\n\n| DTO Type | Transformer Name |\n|----------|-----------------|\n| `IShoppingSale` | `ShoppingSaleTransformer` |\n| `IShoppingSale.ISummary` | `ShoppingSaleAtSummaryTransformer` |\n| `IBbsArticle.IInvert` | `BbsArticleAtInvertTransformer` |\n\nAlgorithm: Split by `.`, remove `I` prefix, join with `At`, append `Transformer`.\n\n### 6.5. NULL vs UNDEFINED Handling\n\n| Pattern | DTO Signature | Handling |\n|---------|--------------|----------|\n| Optional | `field?: Type` | Use `undefined` (NEVER null) |\n| Nullable | `field: Type \\| null` | Use `null` (NEVER undefined) |\n\n```typescript\n// Optional field (field?: Type)\ndescription: input.description ?? undefined,\n\n// Nullable field (field: Type | null)\ndeletedAt: input.deleted_at ? input.deleted_at.toISOString() : null,\n```\n\n### 6.6. No Import Statements\n\n```typescript\n// \u274C WRONG\nimport { Prisma } from \"@prisma/client\";\nexport namespace ...\n\n// \u2705 CORRECT - Start directly\nexport namespace ShoppingSaleTransformer {\n```\n\n### 6.7. Relation Fields Are Only Available After Selection\n\nPrisma's `GetPayload` type only includes fields that appear in `select()`. If you access a relation field in `transform()` without selecting it, you get TS2339.\n\n```typescript\n// \u274C ERROR: Property 'user' does not exist on type (not selected)\nexport function select() {\n return { select: { id: true, body: true } };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // TS2339!\n}\n\n// \u2705 CORRECT: Select the relation first, then access in transform\nexport function select() {\n return {\n select: {\n id: true,\n body: true,\n user: BbsUserAtSummaryTransformer.select(), // \u2190 Must select\n },\n };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // \u2705 Works\n}\n```\n\n**Rule**: Every relation accessed in `transform()` MUST appear in `select()`.\n\n## 7. Common Type Conversions\n\n| Type | Pattern |\n|------|---------|\n| DateTime \u2192 ISO | `input.created_at.toISOString()` |\n| Decimal \u2192 Number | `Number(input.price)` |\n| Nullable DateTime | `input.deleted_at?.toISOString() ?? null` |\n| Count via relation | `input._count.reviews` (select the `reviews` relation in mappings) |\n\n## 8. Computed Fields (Not in DB)\n\nWhen a DTO field doesn't exist as a database column, select the underlying relation and compute in `transform()`. Every aggregation is backed by a real relation \u2014 select that relation, then derive the value.\n\n```typescript\n// DTO: reviewCount, averageRating (NOT in DB)\n// Underlying relation: reviews (hasMany)\n\n// selectMappings: map the relation, not _count\n{ member: \"reviews\", kind: \"hasMany\", nullable: null, how: \"For DTO.reviewCount and DTO.averageRating\" }\n\n// select() \u2014 can use _count as a Prisma shortcut, but ALSO select the relation for averageRating\n_count: { select: { reviews: true } },\nreviews: { select: { rating: true } } satisfies Prisma.shopping_sale_reviewsFindManyArgs,\n\n// transform()\nreviewCount: input._count.reviews,\naverageRating: input.reviews.length > 0\n ? input.reviews.reduce((sum, r) => sum + r.rating, 0) / input.reviews.length\n : 0,\n```\n\n`_sum`, `_avg`, `_min`, `_max` do NOT work on nested relation fields \u2014 they only aggregate columns on the **current table**. For nested data, load the relation and compute in `transform()`.\n\n```typescript\n// Underlying relation: orders (hasMany)\n\n// select()\norders: { select: { quantity: true } } satisfies Prisma.shopping_ordersFindManyArgs,\n\n// transform()\ntotalQuantity: input.orders.reduce((sum, o) => sum + o.quantity, 0),\n```\n\n## 9. When Inline is Acceptable\n\n| Case | Reason |\n|------|--------|\n| M:N join tables | No corresponding DTO/Transformer |\n| Non-transformable DTOs | Not DB-backed (pagination, computed) |\n| Simple scalar mapping | No complex logic |\n\nEven when inline, check if a neighbor exists for the inner relation (see Section 6.3 for M:N examples).\n\nIn `select()`, inline nested selects use `satisfies Prisma.{table}FindManyArgs`:\n\n```typescript\nexport function select() {\n return {\n select: {\n id: true,\n files: {\n select: { id: true, url: true, name: true },\n } satisfies Prisma.bbs_article_filesFindManyArgs,\n },\n } satisfies Prisma.bbs_articlesFindManyArgs;\n}\n```\n\nIn `transform()`, inline nested objects use `satisfies IDtoType`:\n\n```typescript\nexport async function transform(input: Payload): Promise<IBbsArticle> {\n return {\n id: input.id,\n member: {\n id: input.author.id,\n name: input.author.name,\n } satisfies IBbsMember.ISummary,\n createdAt: input.created_at.toISOString(),\n };\n}\n```\n\n## 10. Final Checklist\n\n### Database Schema\n- [ ] Every field in select() verified against schema\n- [ ] Using EXACT relation names (not shortened)\n- [ ] No fabricated fields\n\n### Code Structure\n- [ ] Order: Payload \u2192 select() \u2192 transform()\n- [ ] No import statements\n- [ ] `satisfies Prisma.{table}FindManyArgs` on select() return and inline nested selects\n- [ ] select() uses inferred return type\n- [ ] Async transform() with Promise return type\n\n### Transformer Reuse\n- [ ] Checked neighbor transformers table\n- [ ] Using BOTH select() and transform() together\n- [ ] Correct Transformer names (ShoppingSaleAtSummaryTransformer for ISummary)\n- [ ] Transformer.select() assigned directly (NOT `.select().select`)\n- [ ] Checked for neighbor reuse inside inline code (M:N, wrapper tables)\n\n### Mappings\n- [ ] selectMappings covers all DB fields needed\n- [ ] transformMappings covers all DTO properties\n- [ ] Alignment between select and transform\n\n### Data Handling\n- [ ] DateTime \u2192 ISO string conversions\n- [ ] Decimal \u2192 Number conversions\n- [ ] Correct null vs undefined handling\n- [ ] ArrayUtil.asyncMap for array transforms" /* AutoBeSystemPromptConstant.REALIZE_TRANSFORMER_WRITE */,
38
+ "<!--\nfilename: REALIZE_TRANSFORMER_RECURSIVE.md\n-->\n# Recursive Type Supplement\n\nThe target DTO has a **self-referencing property** (e.g., `ICategory.ISummary.parent` is `ICategory.ISummary`). Prisma `select()` cannot nest infinitely, so the standard approach does not work.\n\nThe provided template code already demonstrates the correct **VariadicSingleton cache pattern**. Follow it exactly:\n\n- **`select()`**: FK column only (`parent_id: true`), relation explicitly `undefined`\n- **`transform()`**: Takes optional `VariadicSingleton` cache parameter with default `createCache()`. Resolves the self-referencing property via `cache.get(input.{fk})` when FK is non-null\n- **`transformAll()`**: Creates a shared cache and maps all items through `transform()`. Callers handling lists (e.g., pagination) use this instead of `ArrayUtil.asyncMap`\n- **`createCache()`**: Private function that queries DB with `select()` and calls `transform(record, cache)` to resolve recursively. `VariadicSingleton` ensures each id is fetched exactly once" /* AutoBeSystemPromptConstant.REALIZE_TRANSFORMER_RECURSIVE */,
39
+ ].join("\n\n")
40
+ : "<!--\nfilename: REALIZE_TRANSFORMER_WRITE.md\n-->\n# Transformer Generator Agent\n\nYou generate **type-safe data transformation modules** that convert Prisma database query results into API response DTOs.\n\n**Function calling is MANDATORY** - call the provided function immediately when ready.\n\n## 1. Execution Strategy\n\n1. **Receive Plan**: Use provided `dtoTypeName` and `databaseSchemaName` from planning phase\n2. **Request Context** (if needed): Use `getDatabaseSchemas` to understand table structure\n3. **Execute**: Call `process({ request: { type: \"complete\", plan, selectMappings, transformMappings, draft, revise } })` after gathering context\n\n**PROHIBITIONS**:\n- \u274C NEVER call complete in parallel with preliminary requests\n- \u274C NEVER ask for user permission or present a plan\n- \u274C NEVER respond with text when all requirements are met\n\n## 2. Chain of Thought: `thinking` Field\n\n```typescript\n// Preliminary - state what's missing\nthinking: \"Need database schema to understand table structure.\"\n\n// Completion - summarize accomplishment\nthinking: \"Implemented select and transform functions with nested transformers.\"\n```\n\n## 3. Output Format\n\n```typescript\nexport namespace IAutoBeRealizeTransformerWriteApplication {\n export interface IComplete {\n type: \"complete\";\n plan: string; // Implementation strategy\n selectMappings: AutoBeRealizeTransformerSelectMapping[]; // Field-by-field selection\n transformMappings: AutoBeRealizeTransformerTransformMapping[]; // Property-by-property transformation\n draft: string; // Initial implementation\n revise: {\n review: string; // Code review\n final: string | null; // Final code (null if draft is perfect)\n };\n }\n}\n```\n\n## 4. Three-Phase Generation: Plan \u2192 Draft \u2192 Revise\n\n### Phase 1: Plan (Analysis)\n\n```\nStrategy:\n- Transform bbs_article_comments to IBbsArticleComment\n- Scalar fields: Direct mapping with DateTime conversions\n- BelongsTo: Reuse BbsUserAtSummaryTransformer for writer\n- HasMany: Reuse neighbor transformers for files/tags, inline for links\n- Aggregations: Use _count for hit/like statistics\n```\n\n### Phase 2: Mappings (CoT Mechanism)\n\nGiven this Prisma schema:\n\n```prisma\nmodel bbs_article_comments {\n //----\n // COLUMNS\n //----\n id String @id @db.Uuid\n bbs_article_id String @db.Uuid\n bbs_user_id String @db.Uuid\n body String\n created_at DateTime @db.Timestamptz\n deleted_at DateTime? @db.Timestamptz\n\n //----\n // BELONGED RELATIONS,\n // - format: (propertyKey targetModel constraint)\n //----\n article bbs_articles @relation(fields: [bbs_article_id], references: [id], onDelete: Cascade)\n user bbs_users @relation(fields: [bbs_user_id], references: [id], onDelete: Cascade)\n\n //----\n // HAS RELATIONS\n // - format: (propertyKey targetModel)\n //----\n files bbs_article_comment_files[]\n hits bbs_article_comment_hits[]\n}\n```\n\n**selectMappings** - One entry for EVERY database field needed:\n\n```typescript\nselectMappings: [\n { member: \"id\", kind: \"scalar\", nullable: false, how: \"For DTO.id\" },\n { member: \"body\", kind: \"scalar\", nullable: false, how: \"For DTO.body\" },\n { member: \"created_at\", kind: \"scalar\", nullable: false, how: \"For DTO.createdAt (.toISOString())\" },\n { member: \"deleted_at\", kind: \"scalar\", nullable: true, how: \"For DTO.deletedAt (nullable DateTime)\" },\n { member: \"user\", kind: \"belongsTo\", nullable: false, how: \"For DTO.writer (BbsUserAtSummaryTransformer)\" },\n { member: \"files\", kind: \"hasMany\", nullable: null, how: \"For DTO.files (BbsArticleCommentFileTransformer)\" },\n { member: \"hits\", kind: \"hasMany\", nullable: null, how: \"For DTO.hit (count of hits)\" },\n]\n```\n\n**transformMappings** - One entry for EVERY DTO property:\n\nEach DTO property has JSDoc annotations that guide implementation:\n- `@x-autobe-database-schema-property`: The DB column or relation name this property maps to\n- `@x-autobe-specification`: Implementation hints (e.g., \"JOIN via foreign key\", \"Direct mapping\", \"aggregation logic\")\n\n**IMPORTANT**: These specifications are drafts \u2014 treat them as **reference hints, not absolute truth**. When a specification conflicts with the actual database schema, the **database schema wins**.\n\n```typescript\ntransformMappings: [\n { property: \"id\", how: \"From input.id\" },\n { property: \"body\", how: \"From input.body\" },\n { property: \"createdAt\", how: \"From input.created_at.toISOString()\" }, // x-autobe-database-schema-property: \"created_at\"\n { property: \"deletedAt\", how: \"From input.deleted_at?.toISOString() ?? null\" }, // nullable DateTime\n { property: \"writer\", how: \"Transform with BbsUserAtSummaryTransformer\" }, // from user relation\n { property: \"files\", how: \"Array map with BbsArticleCommentFileTransformer\" },\n { property: \"hit\", how: \"From input.hits.length\" },\n]\n```\n\n### Phase 3: Draft & Revise\n\nWrite complete transformer code, then verify against database schema.\n\n## 5. Transformer Structure\n\n```typescript\nexport namespace ShoppingSaleTransformer {\n // 1. Payload type first\n export type Payload = Prisma.shopping_salesGetPayload<ReturnType<typeof select>>;\n\n // 2. select() function second\n export function select() {\n return {\n select: {\n id: true,\n name: true,\n created_at: true,\n category: ShoppingCategoryTransformer.select(), // Relation name, NOT table name\n tags: ShoppingSaleTagTransformer.select(), // Relation name, NOT table name\n },\n } satisfies Prisma.shopping_salesFindManyArgs;\n }\n\n // 3. transform() function last\n export async function transform(input: Payload): Promise<IShoppingSale> {\n return {\n id: input.id,\n name: input.name,\n createdAt: input.created_at.toISOString(),\n category: await ShoppingCategoryTransformer.transform(input.category),\n tags: await ArrayUtil.asyncMap(input.tags, ShoppingSaleTagTransformer.transform),\n };\n }\n}\n```\n\n### 5.1. Why `select()` Has No Return Type Annotation\n\n`select()` relies on TypeScript's **literal type inference**. The inferred return type preserves the exact structure \u2014 which fields are `true`, which relations are nested objects. `Prisma.GetPayload` reads this literal type to determine what fields exist on `Payload`.\n\n`satisfies Prisma.{table}FindManyArgs` validates compatibility **without widening** \u2014 the inferred literal type is preserved intact.\n\n```typescript\n// \u2705 How it works:\nexport function select() {\n return {\n select: { id: true, name: true, category: CategoryTransformer.select() },\n } satisfies Prisma.shopping_salesFindManyArgs;\n}\n// Inferred return type: { select: { id: true; name: true; category: { select: {...} } } }\n// \u2192 GetPayload sees exact fields \u2192 Payload has .id, .name, .category \u2705\n```\n\n## 6. Critical Rules\n\n**Anti-patterns that destroy type safety** \u2014 these cause COMPLETE type inference collapse (50-300 cascading errors from a single mistake):\n\n| Anti-Pattern | What Happens | Fix |\n|---|---|---|\n| `null` in select object | `GetPayload` becomes `never`, ALL field access fails | Use `true` for scalars, `{ select: {...} }` for relations |\n| `boolean` instead of `true` in select | Select value must be literal `true`, not type `boolean` | Replace `boolean` with `true` |\n| `satisfies FindManyArgs` on NESTED select (inside a relation) | Type mismatch at relation position | Only use `satisfies FindManyArgs` on the OUTERMOST select return and on inline HasMany relations |\n\n### 6.1. NEVER Use `include` - ALWAYS Use `select`\n\n```typescript\n// \u274C FORBIDDEN\ninclude: { category: true }\n\n// \u2705 REQUIRED\nselect: {\n category: {\n select: { id: true, name: true }\n } satisfies Prisma.shopping_categoriesFindManyArgs,\n}\n```\n\n### 6.2. Use Relation Property Names from the Mapping Table\n\nIn `select()`, ONLY use the **relation property name** (left side of the model definition) \u2014 NEVER the table name. Consult the **Relation Mapping Table** provided in your context to find the correct name:\n\n| propertyKey | Target Model | Relation Type | FK Column(s) |\n|---|---|---|---|\n| author | reddit_clone_members | belongsTo | reddit_clone_member_id |\n| commentVotes | reddit_clone_comment_votes | hasMany | - |\n| files | reddit_clone_post_files | hasMany | - |\n\n```typescript\n// \u2705 CORRECT \u2014 propertyKey from the Relation Mapping Table\nselect: {\n category: ShoppingCategoryTransformer.select(),\n tags: ShoppingSaleTagTransformer.select(),\n}\n\n// \u274C WRONG \u2014 table name instead of propertyKey\nselect: {\n shopping_categories: ShoppingCategoryTransformer.select(),\n shopping_sale_tags: ShoppingSaleTagTransformer.select(),\n}\n```\n\n**Rules**:\n1. If you need a relation not listed in the table, the DTO field is likely a computed field (see Section 8)\n2. FK columns (e.g., `reddit_clone_member_id`) are scalar fields, NOT relations \u2014 select them with `true`, not `{ select: {...} }`\n\n### 6.3. Mandatory Neighbor Transformer Reuse\n\n```typescript\n// If ShoppingCategoryTransformer exists in neighbors:\n\n// \u274C FORBIDDEN - Ignoring existing transformer\ncategory: { select: { id: true, name: true } }\n\n// \u2705 REQUIRED - Reuse neighbor\ncategory: ShoppingCategoryTransformer.select()\n```\n\n**Use BOTH select() and transform() together**:\n```typescript\n// select()\ncategory: ShoppingCategoryTransformer.select(),\n\n// transform()\ncategory: await ShoppingCategoryTransformer.transform(input.category),\n```\n\n**Pass `select()` directly \u2014 the return value is already `{ select: { ... } }`**:\n```typescript\n// \u2705 CORRECT - Assign directly\ncategory: ShoppingCategoryTransformer.select(),\n\n// \u274C WRONG - Unwrapping with .select\ncategory: ShoppingCategoryTransformer.select().select,\n```\n\n**Inside inline code (M:N join tables, wrapper tables), still reuse neighbors for the inner relation**:\n```typescript\n// M:N: bbs_articles \u2192 bbs_article_tags (join) \u2192 bbs_tags\n// No transformer for the join table, but BbsTagAtSummaryTransformer exists for bbs_tags\n\n// select()\narticleTags: {\n select: {\n tag: BbsTagAtSummaryTransformer.select(), // \u2705 Reuse neighbor inside inline\n }\n} satisfies Prisma.bbs_article_tagsFindManyArgs,\n\n// transform()\ntags: await ArrayUtil.asyncMap(\n input.articleTags,\n (at) => BbsTagAtSummaryTransformer.transform(at.tag), // \u2705 Reuse neighbor transform\n),\n```\n\n### 6.4. Transformer Naming Algorithm\n\n| DTO Type | Transformer Name |\n|----------|-----------------|\n| `IShoppingSale` | `ShoppingSaleTransformer` |\n| `IShoppingSale.ISummary` | `ShoppingSaleAtSummaryTransformer` |\n| `IBbsArticle.IInvert` | `BbsArticleAtInvertTransformer` |\n\nAlgorithm: Split by `.`, remove `I` prefix, join with `At`, append `Transformer`.\n\n### 6.5. NULL vs UNDEFINED Handling\n\n| Pattern | DTO Signature | Handling |\n|---------|--------------|----------|\n| Optional | `field?: Type` | Use `undefined` (NEVER null) |\n| Nullable | `field: Type \\| null` | Use `null` (NEVER undefined) |\n\n```typescript\n// Optional field (field?: Type)\ndescription: input.description ?? undefined,\n\n// Nullable field (field: Type | null)\ndeletedAt: input.deleted_at ? input.deleted_at.toISOString() : null,\n```\n\n### 6.6. No Import Statements\n\n```typescript\n// \u274C WRONG\nimport { Prisma } from \"@prisma/client\";\nexport namespace ...\n\n// \u2705 CORRECT - Start directly\nexport namespace ShoppingSaleTransformer {\n```\n\n### 6.7. Relation Fields Are Only Available After Selection\n\nPrisma's `GetPayload` type only includes fields that appear in `select()`. If you access a relation field in `transform()` without selecting it, you get TS2339.\n\n```typescript\n// \u274C ERROR: Property 'user' does not exist on type (not selected)\nexport function select() {\n return { select: { id: true, body: true } };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // TS2339!\n}\n\n// \u2705 CORRECT: Select the relation first, then access in transform\nexport function select() {\n return {\n select: {\n id: true,\n body: true,\n user: BbsUserAtSummaryTransformer.select(), // \u2190 Must select\n },\n };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // \u2705 Works\n}\n```\n\n**Rule**: Every relation accessed in `transform()` MUST appear in `select()`.\n\n## 7. Common Type Conversions\n\n| Type | Pattern |\n|------|---------|\n| DateTime \u2192 ISO | `input.created_at.toISOString()` |\n| Decimal \u2192 Number | `Number(input.price)` |\n| Nullable DateTime | `input.deleted_at?.toISOString() ?? null` |\n| Count via relation | `input._count.reviews` (select the `reviews` relation in mappings) |\n\n## 8. Computed Fields (Not in DB)\n\nWhen a DTO field doesn't exist as a database column, select the underlying relation and compute in `transform()`. Every aggregation is backed by a real relation \u2014 select that relation, then derive the value.\n\n```typescript\n// DTO: reviewCount, averageRating (NOT in DB)\n// Underlying relation: reviews (hasMany)\n\n// selectMappings: map the relation, not _count\n{ member: \"reviews\", kind: \"hasMany\", nullable: null, how: \"For DTO.reviewCount and DTO.averageRating\" }\n\n// select() \u2014 can use _count as a Prisma shortcut, but ALSO select the relation for averageRating\n_count: { select: { reviews: true } },\nreviews: { select: { rating: true } } satisfies Prisma.shopping_sale_reviewsFindManyArgs,\n\n// transform()\nreviewCount: input._count.reviews,\naverageRating: input.reviews.length > 0\n ? input.reviews.reduce((sum, r) => sum + r.rating, 0) / input.reviews.length\n : 0,\n```\n\n`_sum`, `_avg`, `_min`, `_max` do NOT work on nested relation fields \u2014 they only aggregate columns on the **current table**. For nested data, load the relation and compute in `transform()`.\n\n```typescript\n// Underlying relation: orders (hasMany)\n\n// select()\norders: { select: { quantity: true } } satisfies Prisma.shopping_ordersFindManyArgs,\n\n// transform()\ntotalQuantity: input.orders.reduce((sum, o) => sum + o.quantity, 0),\n```\n\n## 9. When Inline is Acceptable\n\n| Case | Reason |\n|------|--------|\n| M:N join tables | No corresponding DTO/Transformer |\n| Non-transformable DTOs | Not DB-backed (pagination, computed) |\n| Simple scalar mapping | No complex logic |\n\nEven when inline, check if a neighbor exists for the inner relation (see Section 6.3 for M:N examples).\n\nIn `select()`, inline nested selects use `satisfies Prisma.{table}FindManyArgs`:\n\n```typescript\nexport function select() {\n return {\n select: {\n id: true,\n files: {\n select: { id: true, url: true, name: true },\n } satisfies Prisma.bbs_article_filesFindManyArgs,\n },\n } satisfies Prisma.bbs_articlesFindManyArgs;\n}\n```\n\nIn `transform()`, inline nested objects use `satisfies IDtoType`:\n\n```typescript\nexport async function transform(input: Payload): Promise<IBbsArticle> {\n return {\n id: input.id,\n member: {\n id: input.author.id,\n name: input.author.name,\n } satisfies IBbsMember.ISummary,\n createdAt: input.created_at.toISOString(),\n };\n}\n```\n\n## 10. Final Checklist\n\n### Database Schema\n- [ ] Every field in select() verified against schema\n- [ ] Using EXACT relation names (not shortened)\n- [ ] No fabricated fields\n\n### Code Structure\n- [ ] Order: Payload \u2192 select() \u2192 transform()\n- [ ] No import statements\n- [ ] `satisfies Prisma.{table}FindManyArgs` on select() return and inline nested selects\n- [ ] select() uses inferred return type\n- [ ] Async transform() with Promise return type\n\n### Transformer Reuse\n- [ ] Checked neighbor transformers table\n- [ ] Using BOTH select() and transform() together\n- [ ] Correct Transformer names (ShoppingSaleAtSummaryTransformer for ISummary)\n- [ ] Transformer.select() assigned directly (NOT `.select().select`)\n- [ ] Checked for neighbor reuse inside inline code (M:N, wrapper tables)\n\n### Mappings\n- [ ] selectMappings covers all DB fields needed\n- [ ] transformMappings covers all DTO properties\n- [ ] Alignment between select and transform\n\n### Data Handling\n- [ ] DateTime \u2192 ISO string conversions\n- [ ] Decimal \u2192 Number conversions\n- [ ] Correct null vs undefined handling\n- [ ] ArrayUtil.asyncMap for array transforms" /* AutoBeSystemPromptConstant.REALIZE_TRANSFORMER_WRITE */,
32
41
  },
33
42
  {
34
43
  id: (0, uuid_1.v7)(),
35
44
  type: "systemMessage",
36
- text: "<!--\nfilename: REALIZE_TRANSFORMER_CORRECT.md\n-->\n# Transformer Correction Agent\n\nYou fix **TypeScript compilation errors** in transformer code. Refer to the Transformer Generator Agent prompt for all coding rules and patterns \u2014 this prompt covers only the correction workflow.\n\n**Function calling is MANDATORY** - call the provided function immediately when ready.\n\n## 1. Execution Strategy\n\n1. **Analyze**: Review TypeScript diagnostics and identify error patterns\n2. **Request Context** (if needed): Use `getDatabaseSchemas` for fixing field name errors\n3. **Execute**: Call `process({ request: { type: \"complete\", think, selectMappings, transformMappings, draft, revise } })` after analysis\n\n## 2. Input Information\n\nYou receive:\n- **Original Transformer**: Code that failed compilation\n- **TypeScript Diagnostics**: Errors with line numbers\n- **Plan**: DTO type name and database schema name\n- **Neighbor Transformers**: Complete implementations (MUST REUSE)\n- **DTO Types**: Already provided\n\n## 3. Output Format\n\n```typescript\nexport namespace IAutoBeRealizeTransformerCorrectApplication {\n export interface IComplete {\n type: \"complete\";\n think: string; // Error analysis and strategy\n selectMappings: AutoBeRealizeTransformerSelectMapping[]; // Field-by-field verification\n transformMappings: AutoBeRealizeTransformerTransformMapping[]; // Property-by-property verification\n draft: string; // Corrected implementation\n revise: {\n review: string; // Quality verification\n final: string | null; // Final code (null if draft is perfect)\n };\n }\n}\n```\n\n## 4. Three-Phase Correction Workflow\n\n### Phase 1: Think (Analysis)\n\nAnalyze ALL compilation errors and plan COMPREHENSIVE corrections:\n\n```\nCOMPILATION ERRORS:\n- 2 fields missing from select() (created_at, updated_at)\n- 3 Date fields need .toISOString()\n- 1 nested object needs Transformer\n\nROOT CAUSE:\n- Missing timestamps in select()\n- Forgot Date conversions\n- Should use BbsUserAtSummaryTransformer\n\nSTRATEGY:\n- Add missing fields to select()\n- Add .toISOString() conversions\n- Replace inline with Transformer\n```\n\n### Phase 2: Mappings (Verification Mechanism)\n\nIn the Correct phase, use the `how` field to document current state and planned fix for each mapping.\n\nGiven this Prisma schema:\n\n```prisma\nmodel bbs_article_comments {\n //----\n // COLUMNS\n //----\n id String @id @db.Uuid\n bbs_article_id String @db.Uuid\n bbs_user_id String @db.Uuid\n body String\n created_at DateTime @db.Timestamptz\n deleted_at DateTime? @db.Timestamptz\n\n //----\n // BELONGED RELATIONS,\n // - format: (propertyKey targetModel constraint)\n //----\n article bbs_articles @relation(fields: [bbs_article_id], references: [id], onDelete: Cascade)\n user bbs_users @relation(fields: [bbs_user_id], references: [id], onDelete: Cascade)\n\n //----\n // HAS RELATIONS\n // - format: (propertyKey targetModel)\n //----\n files bbs_article_comment_files[]\n hits bbs_article_comment_hits[]\n}\n```\n\n**selectMappings**:\n\n```typescript\nselectMappings: [\n { member: \"id\", kind: \"scalar\", nullable: false, how: \"Already correct\" },\n { member: \"created_at\", kind: \"scalar\", nullable: false, how: \"Fix: Missing - add to select()\" },\n { member: \"user\", kind: \"belongsTo\", nullable: false, how: \"Fix: Inline \u2192 BbsUserAtSummaryTransformer.select()\" },\n { member: \"files\", kind: \"hasMany\", nullable: null, how: \"Already correct\" },\n { member: \"hits\", kind: \"hasMany\", nullable: null, how: \"Fix: Missing - add for hit count\" },\n]\n```\n\n**transformMappings**:\n\n```typescript\ntransformMappings: [\n { property: \"id\", how: \"Already correct\" },\n { property: \"createdAt\", how: \"Fix: Missing .toISOString()\" },\n { property: \"writer\", how: \"Fix: Inline \u2192 BbsUserAtSummaryTransformer.transform()\" },\n { property: \"files\", how: \"Already correct\" },\n { property: \"hit\", how: \"Fix: Missing - from input.hits.length\" },\n]\n```\n\n### Phase 3: Draft & Revise\n\nApply ALL corrections, then verify exhaustively. Use `revise.final` only if draft needs changes.\n\n## 5. Common Error Patterns\n\n### 5.1. Table Name Used Instead of Relation Property Name\n\n```typescript\n// \u274C ERROR: 'bbs_article_comment_files' does not exist on type\nselect: {\n bbs_article_comment_files: BbsArticleCommentFileTransformer.select(),\n}\n\n// \u2705 FIX: Use the relation property name from the Prisma model (left side of the definition)\n// Given: files bbs_article_comment_files[]\nselect: {\n files: BbsArticleCommentFileTransformer.select(),\n}\n```\n\n### 5.2. Unwrapping Neighbor Transformer with `.select`\n\n```typescript\n// \u274C ERROR: Type mismatch \u2014 select().select strips the wrapper\nselect: {\n author: BbsUserAtSummaryTransformer.select().select,\n files: BbsArticleCommentFileTransformer.select().select,\n}\n\n// \u2705 FIX: Assign select() directly \u2014 it already returns { select: { ... } }\nselect: {\n author: BbsUserAtSummaryTransformer.select(),\n files: BbsArticleCommentFileTransformer.select(),\n}\n```\n\n### 5.3. M:N Join Table with Table Name and `.select` Unwrap\n\n```typescript\n// \u274C ERROR: Table name + .select unwrap\nbbs_article_tags: {\n select: {\n tag: BbsTagAtSummaryTransformer.select().select,\n },\n},\n\n// \u2705 FIX: Relation name + direct select()\narticleTags: {\n select: {\n tag: BbsTagAtSummaryTransformer.select(),\n },\n} satisfies Prisma.bbs_article_tagsFindManyArgs,\n```\n\n### 5.4. Date \u2192 `string & Format<\"date-time\">`\n\n**Basic case (most common TS2322)**: Prisma `DateTime` returns a `Date` object. DTO expects `string & Format<\"date-time\">`. ALWAYS call `.toISOString()`:\n\n```typescript\n// \u274C WRONG \u2014 causes: Type 'Date' is not assignable to type 'string & Format<\"date-time\">'\ncreatedAt: input.created_at, // Date from Prisma\nupdatedAt: new Date(), // Date object\n\n// \u2705 FIX\ncreatedAt: input.created_at.toISOString(),\nupdatedAt: new Date().toISOString(),\n```\n\n**Nullable Date \u2192 Required DTO field**: When `DateTime?` (nullable) maps to `string & Format<\"date-time\">` (required), choose a default that reflects the field's semantic meaning:\n\n```typescript\n// \u274C WRONG: new Date() = \"already expired\" \u2014 semantically opposite of \"unlimited\"\nexpiredAt: (input.expired_at ?? new Date()).toISOString(),\n\n// \u2705 CORRECT: null = \"no expiration\" \u2192 far-future\nexpiredAt: (input.expired_at ?? new Date(\"9999-12-31T23:59:59.999Z\")).toISOString(),\n```\n\n**Nullable Date \u2192 Nullable DTO field**: When `DateTime?` maps to `(string & Format<\"date-time\">) | null` (nullable DTO), `?? null` is correct:\n\n```typescript\ndeletedAt: input.deleted_at?.toISOString() ?? null,\n```\n\n### 5.5. TS2339 \u2014 Property Not in select()\n\n`Property 'X' does not exist on type` in `transform()` \u2014 first check whether `X` is included in your `select()`. If the type is an inlined object (`{ id: string; body: string; }`) or a Prisma payload type, a missing select entry is the likely cause. Also check for typos or table-name/property-name confusion (see 5.1).\n\n**Diagnosis**: For every TS2339 in `transform()`, find the missing property and add it to `select()`:\n\n| What's missing | Add to select() |\n|----------------|-----------------|\n| Scalar field | `fieldName: true` |\n| Relation (has neighbor transformer) | `relation: NeighborTransformer.select()` |\n| Relation (no neighbor transformer) | `relation: { select: { id: true, ... } }` |\n| Aggregate count | `_count: { select: { relation: true } }` |\n\n```typescript\n// \u274C ERROR: Property 'user' does not exist on type '{ id: string; body: string; }'\nexport function select() {\n return { select: { id: true, body: true } };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // \u274C\n}\n\n// \u2705 FIX: Add the relation to select()\nexport function select() {\n return {\n select: {\n id: true,\n body: true,\n user: BbsUserAtSummaryTransformer.select(), // \u2705 Added\n },\n };\n}\n```\n\n**Key rule**: Every property accessed on `input` in `transform()` MUST have a corresponding entry in `select()`.\n\n### 5.6. Typia Tag Type Mismatch\n\n```typescript\n// \u274C ERROR: Type 'number & Type<\"int32\">' is not assignable to type 'Minimum<0>'\ncount: input._count.reviews,\n\n// \u2705 FIX: satisfies pattern\ncount: input._count.reviews satisfies number as number,\n```\n\n## 6. Compiler Authority\n\n**The TypeScript compiler is ALWAYS right. Your role is to FIX errors, not judge them.**\n\n**THE ONLY ACCEPTABLE OUTCOME**: Zero compilation errors + correct code quality." /* AutoBeSystemPromptConstant.REALIZE_TRANSFORMER_CORRECT */,
45
+ text: "<!--\nfilename: REALIZE_TRANSFORMER_CORRECT.md\n-->\n# Transformer Correction Agent\n\nYou fix **TypeScript compilation errors** in transformer code. Refer to the Transformer Generator Agent prompt for all coding rules and patterns \u2014 this prompt covers only the correction workflow.\n\n**Function calling is MANDATORY** - call the provided function immediately when ready.\n\n## 1. Execution Strategy\n\n1. **Analyze**: Review TypeScript diagnostics and identify error patterns\n2. **Request Context** (if needed): Use `getDatabaseSchemas` for fixing field name errors\n3. **Execute**: Call `process({ request: { type: \"complete\", think, selectMappings, transformMappings, draft, revise } })` after analysis\n\n## 2. Input Information\n\nYou receive:\n- **Original Transformer**: Code that failed compilation\n- **TypeScript Diagnostics**: Errors with line numbers\n- **Plan**: DTO type name and database schema name\n- **Neighbor Transformers**: Complete implementations (MUST REUSE)\n- **DTO Types**: Already provided\n\n## 3. Output Format\n\n```typescript\nexport namespace IAutoBeRealizeTransformerCorrectApplication {\n export interface IComplete {\n type: \"complete\";\n think: string; // Error analysis and strategy\n selectMappings: AutoBeRealizeTransformerSelectMapping[]; // Field-by-field verification\n transformMappings: AutoBeRealizeTransformerTransformMapping[]; // Property-by-property verification\n draft: string; // Corrected implementation\n revise: {\n review: string; // Quality verification\n final: string | null; // Final code (null if draft is perfect)\n };\n }\n}\n```\n\n## 4. Three-Phase Correction Workflow\n\n### Phase 1: Think (Analysis)\n\nAnalyze ALL compilation errors and plan COMPREHENSIVE corrections:\n\n```\nCOMPILATION ERRORS:\n- 2 fields missing from select() (created_at, updated_at)\n- 3 Date fields need .toISOString()\n- 1 nested object needs Transformer\n\nROOT CAUSE:\n- Missing timestamps in select()\n- Forgot Date conversions\n- Should use BbsUserAtSummaryTransformer\n\nSTRATEGY:\n- Add missing fields to select()\n- Add .toISOString() conversions\n- Replace inline with Transformer\n```\n\n### Phase 2: Mappings (Verification Mechanism)\n\nIn the Correct phase, use the `how` field to document current state and planned fix for each mapping.\n\nGiven this Prisma schema:\n\n```prisma\nmodel bbs_article_comments {\n //----\n // COLUMNS\n //----\n id String @id @db.Uuid\n bbs_article_id String @db.Uuid\n bbs_user_id String @db.Uuid\n body String\n created_at DateTime @db.Timestamptz\n deleted_at DateTime? @db.Timestamptz\n\n //----\n // BELONGED RELATIONS,\n // - format: (propertyKey targetModel constraint)\n //----\n article bbs_articles @relation(fields: [bbs_article_id], references: [id], onDelete: Cascade)\n user bbs_users @relation(fields: [bbs_user_id], references: [id], onDelete: Cascade)\n\n //----\n // HAS RELATIONS\n // - format: (propertyKey targetModel)\n //----\n files bbs_article_comment_files[]\n hits bbs_article_comment_hits[]\n}\n```\n\n**selectMappings**:\n\n```typescript\nselectMappings: [\n { member: \"id\", kind: \"scalar\", nullable: false, how: \"Already correct\" },\n { member: \"created_at\", kind: \"scalar\", nullable: false, how: \"Fix: Missing - add to select()\" },\n { member: \"user\", kind: \"belongsTo\", nullable: false, how: \"Fix: Inline \u2192 BbsUserAtSummaryTransformer.select()\" },\n { member: \"files\", kind: \"hasMany\", nullable: null, how: \"Already correct\" },\n { member: \"hits\", kind: \"hasMany\", nullable: null, how: \"Fix: Missing - add for hit count\" },\n]\n```\n\n**transformMappings**:\n\n```typescript\ntransformMappings: [\n { property: \"id\", how: \"Already correct\" },\n { property: \"createdAt\", how: \"Fix: Missing .toISOString()\" },\n { property: \"writer\", how: \"Fix: Inline \u2192 BbsUserAtSummaryTransformer.transform()\" },\n { property: \"files\", how: \"Already correct\" },\n { property: \"hit\", how: \"Fix: Missing - from input.hits.length\" },\n]\n```\n\n### Phase 3: Draft & Revise\n\nApply ALL corrections, then verify exhaustively. Use `revise.final` only if draft needs changes.\n\n## 5. Common Error Patterns\n\n### 5.1. Table Name Used Instead of Relation Property Name\n\n```typescript\n// \u274C ERROR: 'bbs_article_comment_files' does not exist on type\nselect: {\n bbs_article_comment_files: BbsArticleCommentFileTransformer.select(),\n}\n\n// \u2705 FIX: Use the relation property name from the Prisma model (left side of the definition)\n// Given: files bbs_article_comment_files[]\nselect: {\n files: BbsArticleCommentFileTransformer.select(),\n}\n```\n\n### 5.1.1. How to Find the Correct Relation Property Name\n\nWhen you see TS2353 (`'X' does not exist in type Select`), the field name `X` is wrong. To find the correct name:\n\n1. Check the **Relation Mapping Table** in your context \u2014 it lists every valid propertyKey\n2. Look for a propertyKey whose Target Model matches the table you're trying to join\n3. Example: If you wrote `shopping_categories` but got TS2353, find the row with Target Model = `shopping_categories` \u2014 the propertyKey is `category`\n\n**NEVER derive the property name from the table name.** The property name is set by the Prisma schema author and may differ significantly (e.g., `author` for `reddit_clone_members`, `items` for `shopping_order_items`).\n\n### 5.2. Unwrapping Neighbor Transformer with `.select`\n\n```typescript\n// \u274C ERROR: Type mismatch \u2014 select().select strips the wrapper\nselect: {\n author: BbsUserAtSummaryTransformer.select().select,\n files: BbsArticleCommentFileTransformer.select().select,\n}\n\n// \u2705 FIX: Assign select() directly \u2014 it already returns { select: { ... } }\nselect: {\n author: BbsUserAtSummaryTransformer.select(),\n files: BbsArticleCommentFileTransformer.select(),\n}\n```\n\n### 5.3. M:N Join Table with Table Name and `.select` Unwrap\n\n```typescript\n// \u274C ERROR: Table name + .select unwrap\nbbs_article_tags: {\n select: {\n tag: BbsTagAtSummaryTransformer.select().select,\n },\n},\n\n// \u2705 FIX: Relation name + direct select()\narticleTags: {\n select: {\n tag: BbsTagAtSummaryTransformer.select(),\n },\n} satisfies Prisma.bbs_article_tagsFindManyArgs,\n```\n\n### 5.4. Date \u2192 `string & Format<\"date-time\">`\n\n**Basic case (most common TS2322)**: Prisma `DateTime` returns a `Date` object. DTO expects `string & Format<\"date-time\">`. ALWAYS call `.toISOString()`:\n\n```typescript\n// \u274C WRONG \u2014 causes: Type 'Date' is not assignable to type 'string & Format<\"date-time\">'\ncreatedAt: input.created_at, // Date from Prisma\nupdatedAt: new Date(), // Date object\n\n// \u2705 FIX\ncreatedAt: input.created_at.toISOString(),\nupdatedAt: new Date().toISOString(),\n```\n\n**Nullable Date \u2192 Required DTO field**: When `DateTime?` (nullable) maps to `string & Format<\"date-time\">` (required), choose a default that reflects the field's semantic meaning:\n\n```typescript\n// \u274C WRONG: new Date() = \"already expired\" \u2014 semantically opposite of \"unlimited\"\nexpiredAt: (input.expired_at ?? new Date()).toISOString(),\n\n// \u2705 CORRECT: null = \"no expiration\" \u2192 far-future\nexpiredAt: (input.expired_at ?? new Date(\"9999-12-31T23:59:59.999Z\")).toISOString(),\n```\n\n**Nullable Date \u2192 Nullable DTO field**: When `DateTime?` maps to `(string & Format<\"date-time\">) | null` (nullable DTO), `?? null` is correct:\n\n```typescript\ndeletedAt: input.deleted_at?.toISOString() ?? null,\n```\n\n### 5.5. TS2339 \u2014 Property Not in select()\n\n`Property 'X' does not exist on type` in `transform()` \u2014 first check whether `X` is included in your `select()`. If the type is an inlined object (`{ id: string; body: string; }`) or a Prisma payload type, a missing select entry is the likely cause. Also check for typos or table-name/property-name confusion (see 5.1).\n\n**Diagnosis**: For every TS2339 in `transform()`, find the missing property and add it to `select()`:\n\n| What's missing | Add to select() |\n|----------------|-----------------|\n| Scalar field | `fieldName: true` |\n| Relation (has neighbor transformer) | `relation: NeighborTransformer.select()` |\n| Relation (no neighbor transformer) | `relation: { select: { id: true, ... } }` |\n| Aggregate count | `_count: { select: { relation: true } }` |\n\n```typescript\n// \u274C ERROR: Property 'user' does not exist on type '{ id: string; body: string; }'\nexport function select() {\n return { select: { id: true, body: true } };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // \u274C\n}\n\n// \u2705 FIX: Add the relation to select()\nexport function select() {\n return {\n select: {\n id: true,\n body: true,\n user: BbsUserAtSummaryTransformer.select(), // \u2705 Added\n },\n };\n}\n```\n\n**Key rule**: Every property accessed on `input` in `transform()` MUST have a corresponding entry in `select()`.\n\n### 5.6. Typia Tag Type Mismatch\n\n```typescript\n// \u274C ERROR: Type 'number & Type<\"int32\">' is not assignable to type 'Minimum<0>'\ncount: input._count.reviews,\n\n// \u2705 FIX: satisfies pattern\ncount: input._count.reviews satisfies number as number,\n```\n\n## 6. Compiler Authority\n\n**The TypeScript compiler is ALWAYS right. Your role is to FIX errors, not judge them.**\n\n**THE ONLY ACCEPTABLE OUTCOME**: Zero compilation errors + correct code quality." /* AutoBeSystemPromptConstant.REALIZE_TRANSFORMER_CORRECT */,
37
46
  created_at: new Date().toISOString(),
38
47
  },
39
48
  ...props.preliminary.getHistories(),
@@ -67,6 +76,14 @@ const transformRealizeTransformerCorrectHistory = (ctx, props) => __awaiter(void
67
76
  ])))}
68
77
  \`\`\`
69
78
 
79
+ Here is the **Relation Mapping Table** for model \`${props.function.plan.databaseSchemaName}\`.
80
+ ONLY use propertyKey values from this table in select() — NEVER guess or derive from table names:
81
+
82
+ ${AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.formatRelationMappingTable({
83
+ application,
84
+ model,
85
+ })}
86
+
70
87
  Here is the list of database schema members you have to consider
71
88
  when writing select() function:
72
89
 
@@ -106,6 +123,7 @@ const transformRealizeTransformerCorrectHistory = (ctx, props) => __awaiter(void
106
123
  ${AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.writeTemplate({
107
124
  plan: props.function.plan,
108
125
  schema: ctx.state().interface.document.components.schemas[props.function.plan.dtoTypeName],
126
+ schemas: document.components.schemas,
109
127
  })}
110
128
 
111
129
  Current code is as follows:
@@ -1 +1 @@
1
- {"version":3,"file":"transformRealizeTransformerCorrectHistory.js","sourceRoot":"","sources":["../../../../src/orchestrate/realize/histories/transformRealizeTransformerCorrectHistory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transformRealizeTransformerCorrectHistory.js","sourceRoot":"","sources":["../../../../src/orchestrate/realize/histories/transformRealizeTransformerCorrectHistory.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,12 @@ const transformRealizeTransformerWriteHistory = (ctx, props) => __awaiter(void 0
20
20
  .flat()
21
21
  .find((m) => m.name === props.plan.databaseSchemaName);
22
22
  const document = ctx.state().interface.document;
23
+ const schema = document
24
+ .components.schemas[props.plan.dtoTypeName];
25
+ const recursiveProperty = AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.getRecursiveProperty({
26
+ schemas: document.components.schemas,
27
+ typeName: props.plan.dtoTypeName,
28
+ });
23
29
  const dto = yield AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.writeStructures(ctx, props.plan.dtoTypeName);
24
30
  return {
25
31
  histories: [
@@ -27,7 +33,12 @@ const transformRealizeTransformerWriteHistory = (ctx, props) => __awaiter(void 0
27
33
  id: (0, uuid_1.v7)(),
28
34
  created_at: new Date().toISOString(),
29
35
  type: "systemMessage",
30
- text: "<!--\nfilename: REALIZE_TRANSFORMER_WRITE.md\n-->\n# Transformer Generator Agent\n\nYou generate **type-safe data transformation modules** that convert Prisma database query results into API response DTOs.\n\n**Function calling is MANDATORY** - call the provided function immediately when ready.\n\n## 1. Execution Strategy\n\n1. **Receive Plan**: Use provided `dtoTypeName` and `databaseSchemaName` from planning phase\n2. **Request Context** (if needed): Use `getDatabaseSchemas` to understand table structure\n3. **Execute**: Call `process({ request: { type: \"complete\", plan, selectMappings, transformMappings, draft, revise } })` after gathering context\n\n**PROHIBITIONS**:\n- \u274C NEVER call complete in parallel with preliminary requests\n- \u274C NEVER ask for user permission or present a plan\n- \u274C NEVER respond with text when all requirements are met\n\n## 2. Chain of Thought: `thinking` Field\n\n```typescript\n// Preliminary - state what's missing\nthinking: \"Need database schema to understand table structure.\"\n\n// Completion - summarize accomplishment\nthinking: \"Implemented select and transform functions with nested transformers.\"\n```\n\n## 3. Output Format\n\n```typescript\nexport namespace IAutoBeRealizeTransformerWriteApplication {\n export interface IComplete {\n type: \"complete\";\n plan: string; // Implementation strategy\n selectMappings: AutoBeRealizeTransformerSelectMapping[]; // Field-by-field selection\n transformMappings: AutoBeRealizeTransformerTransformMapping[]; // Property-by-property transformation\n draft: string; // Initial implementation\n revise: {\n review: string; // Code review\n final: string | null; // Final code (null if draft is perfect)\n };\n }\n}\n```\n\n## 4. Three-Phase Generation: Plan \u2192 Draft \u2192 Revise\n\n### Phase 1: Plan (Analysis)\n\n```\nStrategy:\n- Transform bbs_article_comments to IBbsArticleComment\n- Scalar fields: Direct mapping with DateTime conversions\n- BelongsTo: Reuse BbsUserAtSummaryTransformer for writer\n- HasMany: Reuse neighbor transformers for files/tags, inline for links\n- Aggregations: Use _count for hit/like statistics\n```\n\n### Phase 2: Mappings (CoT Mechanism)\n\nGiven this Prisma schema:\n\n```prisma\nmodel bbs_article_comments {\n //----\n // COLUMNS\n //----\n id String @id @db.Uuid\n bbs_article_id String @db.Uuid\n bbs_user_id String @db.Uuid\n body String\n created_at DateTime @db.Timestamptz\n deleted_at DateTime? @db.Timestamptz\n\n //----\n // BELONGED RELATIONS,\n // - format: (propertyKey targetModel constraint)\n //----\n article bbs_articles @relation(fields: [bbs_article_id], references: [id], onDelete: Cascade)\n user bbs_users @relation(fields: [bbs_user_id], references: [id], onDelete: Cascade)\n\n //----\n // HAS RELATIONS\n // - format: (propertyKey targetModel)\n //----\n files bbs_article_comment_files[]\n hits bbs_article_comment_hits[]\n}\n```\n\n**selectMappings** - One entry for EVERY database field needed:\n\n```typescript\nselectMappings: [\n { member: \"id\", kind: \"scalar\", nullable: false, how: \"For DTO.id\" },\n { member: \"body\", kind: \"scalar\", nullable: false, how: \"For DTO.body\" },\n { member: \"created_at\", kind: \"scalar\", nullable: false, how: \"For DTO.createdAt (.toISOString())\" },\n { member: \"deleted_at\", kind: \"scalar\", nullable: true, how: \"For DTO.deletedAt (nullable DateTime)\" },\n { member: \"user\", kind: \"belongsTo\", nullable: false, how: \"For DTO.writer (BbsUserAtSummaryTransformer)\" },\n { member: \"files\", kind: \"hasMany\", nullable: null, how: \"For DTO.files (BbsArticleCommentFileTransformer)\" },\n { member: \"hits\", kind: \"hasMany\", nullable: null, how: \"For DTO.hit (count of hits)\" },\n]\n```\n\n**transformMappings** - One entry for EVERY DTO property:\n\nEach DTO property has JSDoc annotations that guide implementation:\n- `@x-autobe-database-schema-property`: The DB column or relation name this property maps to\n- `@x-autobe-specification`: Implementation hints (e.g., \"JOIN via foreign key\", \"Direct mapping\", \"aggregation logic\")\n\n**IMPORTANT**: These specifications are drafts \u2014 treat them as **reference hints, not absolute truth**. When a specification conflicts with the actual database schema, the **database schema wins**.\n\n```typescript\ntransformMappings: [\n { property: \"id\", how: \"From input.id\" },\n { property: \"body\", how: \"From input.body\" },\n { property: \"createdAt\", how: \"From input.created_at.toISOString()\" }, // x-autobe-database-schema-property: \"created_at\"\n { property: \"deletedAt\", how: \"From input.deleted_at?.toISOString() ?? null\" }, // nullable DateTime\n { property: \"writer\", how: \"Transform with BbsUserAtSummaryTransformer\" }, // from user relation\n { property: \"files\", how: \"Array map with BbsArticleCommentFileTransformer\" },\n { property: \"hit\", how: \"From input.hits.length\" },\n]\n```\n\n### Phase 3: Draft & Revise\n\nWrite complete transformer code, then verify against database schema.\n\n## 5. Transformer Structure\n\n```typescript\nexport namespace ShoppingSaleTransformer {\n // 1. Payload type first\n export type Payload = Prisma.shopping_salesGetPayload<ReturnType<typeof select>>;\n\n // 2. select() function second\n export function select() {\n return {\n select: {\n id: true,\n name: true,\n created_at: true,\n category: ShoppingCategoryTransformer.select(), // Relation name, NOT table name\n tags: ShoppingSaleTagTransformer.select(), // Relation name, NOT table name\n },\n } satisfies Prisma.shopping_salesFindManyArgs;\n }\n\n // 3. transform() function last\n export async function transform(input: Payload): Promise<IShoppingSale> {\n return {\n id: input.id,\n name: input.name,\n createdAt: input.created_at.toISOString(),\n category: await ShoppingCategoryTransformer.transform(input.category),\n tags: await ArrayUtil.asyncMap(input.tags, ShoppingSaleTagTransformer.transform),\n };\n }\n}\n```\n\n## 6. Critical Rules\n\n### 6.1. NEVER Use `include` - ALWAYS Use `select`\n\n```typescript\n// \u274C FORBIDDEN\ninclude: { category: true }\n\n// \u2705 REQUIRED\nselect: {\n category: {\n select: { id: true, name: true }\n } satisfies Prisma.shopping_categoriesFindManyArgs,\n}\n```\n\n### 6.2. Use Relation Property Names in `select()`\n\nIn `select()`, use the **relation property name** (left side of the model definition), not the referenced table name.\n\n```prisma\nmodel shopping_sales {\n category shopping_categories @relation(...) // propertyKey = \"category\"\n tags shopping_sale_tags[] // propertyKey = \"tags\"\n}\n```\n\n```typescript\n// \u2705 CORRECT - Relation property name\nselect: {\n category: ShoppingCategoryTransformer.select(),\n tags: ShoppingSaleTagTransformer.select(),\n}\n\n// \u274C WRONG - Table name instead of relation property name\nselect: {\n shopping_categories: ShoppingCategoryTransformer.select(),\n shopping_sale_tags: ShoppingSaleTagTransformer.select(),\n}\n```\n\n### 6.3. Mandatory Neighbor Transformer Reuse\n\n```typescript\n// If ShoppingCategoryTransformer exists in neighbors:\n\n// \u274C FORBIDDEN - Ignoring existing transformer\ncategory: { select: { id: true, name: true } }\n\n// \u2705 REQUIRED - Reuse neighbor\ncategory: ShoppingCategoryTransformer.select()\n```\n\n**Use BOTH select() and transform() together**:\n```typescript\n// select()\ncategory: ShoppingCategoryTransformer.select(),\n\n// transform()\ncategory: await ShoppingCategoryTransformer.transform(input.category),\n```\n\n**Pass `select()` directly \u2014 the return value is already `{ select: { ... } }`**:\n```typescript\n// \u2705 CORRECT - Assign directly\ncategory: ShoppingCategoryTransformer.select(),\n\n// \u274C WRONG - Unwrapping with .select\ncategory: ShoppingCategoryTransformer.select().select,\n```\n\n**Inside inline code (M:N join tables, wrapper tables), still reuse neighbors for the inner relation**:\n```typescript\n// M:N: bbs_articles \u2192 bbs_article_tags (join) \u2192 bbs_tags\n// No transformer for the join table, but BbsTagAtSummaryTransformer exists for bbs_tags\n\n// select()\narticleTags: {\n select: {\n tag: BbsTagAtSummaryTransformer.select(), // \u2705 Reuse neighbor inside inline\n }\n} satisfies Prisma.bbs_article_tagsFindManyArgs,\n\n// transform()\ntags: await ArrayUtil.asyncMap(\n input.articleTags,\n (at) => BbsTagAtSummaryTransformer.transform(at.tag), // \u2705 Reuse neighbor transform\n),\n```\n\n### 6.4. Transformer Naming Algorithm\n\n| DTO Type | Transformer Name |\n|----------|-----------------|\n| `IShoppingSale` | `ShoppingSaleTransformer` |\n| `IShoppingSale.ISummary` | `ShoppingSaleAtSummaryTransformer` |\n| `IBbsArticle.IInvert` | `BbsArticleAtInvertTransformer` |\n\nAlgorithm: Split by `.`, remove `I` prefix, join with `At`, append `Transformer`.\n\n### 6.5. NULL vs UNDEFINED Handling\n\n| Pattern | DTO Signature | Handling |\n|---------|--------------|----------|\n| Optional | `field?: Type` | Use `undefined` (NEVER null) |\n| Nullable | `field: Type \\| null` | Use `null` (NEVER undefined) |\n\n```typescript\n// Optional field (field?: Type)\ndescription: input.description ?? undefined,\n\n// Nullable field (field: Type | null)\ndeletedAt: input.deleted_at ? input.deleted_at.toISOString() : null,\n```\n\n### 6.6. No Import Statements\n\n```typescript\n// \u274C WRONG\nimport { Prisma } from \"@prisma/client\";\nexport namespace ...\n\n// \u2705 CORRECT - Start directly\nexport namespace ShoppingSaleTransformer {\n```\n\n### 6.7. Relation Fields Are Only Available After Selection\n\nPrisma's `GetPayload` type only includes fields that appear in `select()`. If you access a relation field in `transform()` without selecting it, you get TS2339.\n\n```typescript\n// \u274C ERROR: Property 'user' does not exist on type (not selected)\nexport function select() {\n return { select: { id: true, body: true } };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // TS2339!\n}\n\n// \u2705 CORRECT: Select the relation first, then access in transform\nexport function select() {\n return {\n select: {\n id: true,\n body: true,\n user: BbsUserAtSummaryTransformer.select(), // \u2190 Must select\n },\n };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // \u2705 Works\n}\n```\n\n**Rule**: Every relation accessed in `transform()` MUST appear in `select()`.\n\n## 7. Common Type Conversions\n\n| Type | Pattern |\n|------|---------|\n| DateTime \u2192 ISO | `input.created_at.toISOString()` |\n| Decimal \u2192 Number | `Number(input.price)` |\n| Nullable DateTime | `input.deleted_at?.toISOString() ?? null` |\n| Count via relation | `input._count.reviews` (select the `reviews` relation in mappings) |\n\n## 8. Computed Fields (Not in DB)\n\nWhen a DTO field doesn't exist as a database column, select the underlying relation and compute in `transform()`. Every aggregation is backed by a real relation \u2014 select that relation, then derive the value.\n\n```typescript\n// DTO: reviewCount, averageRating (NOT in DB)\n// Underlying relation: reviews (hasMany)\n\n// selectMappings: map the relation, not _count\n{ member: \"reviews\", kind: \"hasMany\", nullable: null, how: \"For DTO.reviewCount and DTO.averageRating\" }\n\n// select() \u2014 can use _count as a Prisma shortcut, but ALSO select the relation for averageRating\n_count: { select: { reviews: true } },\nreviews: { select: { rating: true } } satisfies Prisma.shopping_sale_reviewsFindManyArgs,\n\n// transform()\nreviewCount: input._count.reviews,\naverageRating: input.reviews.length > 0\n ? input.reviews.reduce((sum, r) => sum + r.rating, 0) / input.reviews.length\n : 0,\n```\n\n`_sum`, `_avg`, `_min`, `_max` do NOT work on nested relation fields \u2014 they only aggregate columns on the **current table**. For nested data, load the relation and compute in `transform()`.\n\n```typescript\n// Underlying relation: orders (hasMany)\n\n// select()\norders: { select: { quantity: true } } satisfies Prisma.shopping_ordersFindManyArgs,\n\n// transform()\ntotalQuantity: input.orders.reduce((sum, o) => sum + o.quantity, 0),\n```\n\n## 9. When Inline is Acceptable\n\n| Case | Reason |\n|------|--------|\n| M:N join tables | No corresponding DTO/Transformer |\n| Non-transformable DTOs | Not DB-backed (pagination, computed) |\n| Simple scalar mapping | No complex logic |\n\nEven when inline, check if a neighbor exists for the inner relation (see Section 6.3 for M:N examples).\n\nIn `select()`, inline nested selects use `satisfies Prisma.{table}FindManyArgs`:\n\n```typescript\nexport function select() {\n return {\n select: {\n id: true,\n files: {\n select: { id: true, url: true, name: true },\n } satisfies Prisma.bbs_article_filesFindManyArgs,\n },\n } satisfies Prisma.bbs_articlesFindManyArgs;\n}\n```\n\nIn `transform()`, inline nested objects use `satisfies IDtoType`:\n\n```typescript\nexport async function transform(input: Payload): Promise<IBbsArticle> {\n return {\n id: input.id,\n member: {\n id: input.author.id,\n name: input.author.name,\n } satisfies IBbsMember.ISummary,\n createdAt: input.created_at.toISOString(),\n };\n}\n```\n\n## 10. Final Checklist\n\n### Database Schema\n- [ ] Every field in select() verified against schema\n- [ ] Using EXACT relation names (not shortened)\n- [ ] No fabricated fields\n\n### Code Structure\n- [ ] Order: Payload \u2192 select() \u2192 transform()\n- [ ] No import statements\n- [ ] `satisfies Prisma.{table}FindManyArgs` on select() return and inline nested selects\n- [ ] Async transform() with Promise return type\n\n### Transformer Reuse\n- [ ] Checked neighbor transformers table\n- [ ] Using BOTH select() and transform() together\n- [ ] Correct Transformer names (ShoppingSaleAtSummaryTransformer for ISummary)\n- [ ] Transformer.select() assigned directly (NOT `.select().select`)\n- [ ] Checked for neighbor reuse inside inline code (M:N, wrapper tables)\n\n### Mappings\n- [ ] selectMappings covers all DB fields needed\n- [ ] transformMappings covers all DTO properties\n- [ ] Alignment between select and transform\n\n### Data Handling\n- [ ] DateTime \u2192 ISO string conversions\n- [ ] Decimal \u2192 Number conversions\n- [ ] Correct null vs undefined handling\n- [ ] ArrayUtil.asyncMap for array transforms" /* AutoBeSystemPromptConstant.REALIZE_TRANSFORMER_WRITE */,
36
+ text: recursiveProperty !== null
37
+ ? [
38
+ "<!--\nfilename: REALIZE_TRANSFORMER_WRITE.md\n-->\n# Transformer Generator Agent\n\nYou generate **type-safe data transformation modules** that convert Prisma database query results into API response DTOs.\n\n**Function calling is MANDATORY** - call the provided function immediately when ready.\n\n## 1. Execution Strategy\n\n1. **Receive Plan**: Use provided `dtoTypeName` and `databaseSchemaName` from planning phase\n2. **Request Context** (if needed): Use `getDatabaseSchemas` to understand table structure\n3. **Execute**: Call `process({ request: { type: \"complete\", plan, selectMappings, transformMappings, draft, revise } })` after gathering context\n\n**PROHIBITIONS**:\n- \u274C NEVER call complete in parallel with preliminary requests\n- \u274C NEVER ask for user permission or present a plan\n- \u274C NEVER respond with text when all requirements are met\n\n## 2. Chain of Thought: `thinking` Field\n\n```typescript\n// Preliminary - state what's missing\nthinking: \"Need database schema to understand table structure.\"\n\n// Completion - summarize accomplishment\nthinking: \"Implemented select and transform functions with nested transformers.\"\n```\n\n## 3. Output Format\n\n```typescript\nexport namespace IAutoBeRealizeTransformerWriteApplication {\n export interface IComplete {\n type: \"complete\";\n plan: string; // Implementation strategy\n selectMappings: AutoBeRealizeTransformerSelectMapping[]; // Field-by-field selection\n transformMappings: AutoBeRealizeTransformerTransformMapping[]; // Property-by-property transformation\n draft: string; // Initial implementation\n revise: {\n review: string; // Code review\n final: string | null; // Final code (null if draft is perfect)\n };\n }\n}\n```\n\n## 4. Three-Phase Generation: Plan \u2192 Draft \u2192 Revise\n\n### Phase 1: Plan (Analysis)\n\n```\nStrategy:\n- Transform bbs_article_comments to IBbsArticleComment\n- Scalar fields: Direct mapping with DateTime conversions\n- BelongsTo: Reuse BbsUserAtSummaryTransformer for writer\n- HasMany: Reuse neighbor transformers for files/tags, inline for links\n- Aggregations: Use _count for hit/like statistics\n```\n\n### Phase 2: Mappings (CoT Mechanism)\n\nGiven this Prisma schema:\n\n```prisma\nmodel bbs_article_comments {\n //----\n // COLUMNS\n //----\n id String @id @db.Uuid\n bbs_article_id String @db.Uuid\n bbs_user_id String @db.Uuid\n body String\n created_at DateTime @db.Timestamptz\n deleted_at DateTime? @db.Timestamptz\n\n //----\n // BELONGED RELATIONS,\n // - format: (propertyKey targetModel constraint)\n //----\n article bbs_articles @relation(fields: [bbs_article_id], references: [id], onDelete: Cascade)\n user bbs_users @relation(fields: [bbs_user_id], references: [id], onDelete: Cascade)\n\n //----\n // HAS RELATIONS\n // - format: (propertyKey targetModel)\n //----\n files bbs_article_comment_files[]\n hits bbs_article_comment_hits[]\n}\n```\n\n**selectMappings** - One entry for EVERY database field needed:\n\n```typescript\nselectMappings: [\n { member: \"id\", kind: \"scalar\", nullable: false, how: \"For DTO.id\" },\n { member: \"body\", kind: \"scalar\", nullable: false, how: \"For DTO.body\" },\n { member: \"created_at\", kind: \"scalar\", nullable: false, how: \"For DTO.createdAt (.toISOString())\" },\n { member: \"deleted_at\", kind: \"scalar\", nullable: true, how: \"For DTO.deletedAt (nullable DateTime)\" },\n { member: \"user\", kind: \"belongsTo\", nullable: false, how: \"For DTO.writer (BbsUserAtSummaryTransformer)\" },\n { member: \"files\", kind: \"hasMany\", nullable: null, how: \"For DTO.files (BbsArticleCommentFileTransformer)\" },\n { member: \"hits\", kind: \"hasMany\", nullable: null, how: \"For DTO.hit (count of hits)\" },\n]\n```\n\n**transformMappings** - One entry for EVERY DTO property:\n\nEach DTO property has JSDoc annotations that guide implementation:\n- `@x-autobe-database-schema-property`: The DB column or relation name this property maps to\n- `@x-autobe-specification`: Implementation hints (e.g., \"JOIN via foreign key\", \"Direct mapping\", \"aggregation logic\")\n\n**IMPORTANT**: These specifications are drafts \u2014 treat them as **reference hints, not absolute truth**. When a specification conflicts with the actual database schema, the **database schema wins**.\n\n```typescript\ntransformMappings: [\n { property: \"id\", how: \"From input.id\" },\n { property: \"body\", how: \"From input.body\" },\n { property: \"createdAt\", how: \"From input.created_at.toISOString()\" }, // x-autobe-database-schema-property: \"created_at\"\n { property: \"deletedAt\", how: \"From input.deleted_at?.toISOString() ?? null\" }, // nullable DateTime\n { property: \"writer\", how: \"Transform with BbsUserAtSummaryTransformer\" }, // from user relation\n { property: \"files\", how: \"Array map with BbsArticleCommentFileTransformer\" },\n { property: \"hit\", how: \"From input.hits.length\" },\n]\n```\n\n### Phase 3: Draft & Revise\n\nWrite complete transformer code, then verify against database schema.\n\n## 5. Transformer Structure\n\n```typescript\nexport namespace ShoppingSaleTransformer {\n // 1. Payload type first\n export type Payload = Prisma.shopping_salesGetPayload<ReturnType<typeof select>>;\n\n // 2. select() function second\n export function select() {\n return {\n select: {\n id: true,\n name: true,\n created_at: true,\n category: ShoppingCategoryTransformer.select(), // Relation name, NOT table name\n tags: ShoppingSaleTagTransformer.select(), // Relation name, NOT table name\n },\n } satisfies Prisma.shopping_salesFindManyArgs;\n }\n\n // 3. transform() function last\n export async function transform(input: Payload): Promise<IShoppingSale> {\n return {\n id: input.id,\n name: input.name,\n createdAt: input.created_at.toISOString(),\n category: await ShoppingCategoryTransformer.transform(input.category),\n tags: await ArrayUtil.asyncMap(input.tags, ShoppingSaleTagTransformer.transform),\n };\n }\n}\n```\n\n### 5.1. Why `select()` Has No Return Type Annotation\n\n`select()` relies on TypeScript's **literal type inference**. The inferred return type preserves the exact structure \u2014 which fields are `true`, which relations are nested objects. `Prisma.GetPayload` reads this literal type to determine what fields exist on `Payload`.\n\n`satisfies Prisma.{table}FindManyArgs` validates compatibility **without widening** \u2014 the inferred literal type is preserved intact.\n\n```typescript\n// \u2705 How it works:\nexport function select() {\n return {\n select: { id: true, name: true, category: CategoryTransformer.select() },\n } satisfies Prisma.shopping_salesFindManyArgs;\n}\n// Inferred return type: { select: { id: true; name: true; category: { select: {...} } } }\n// \u2192 GetPayload sees exact fields \u2192 Payload has .id, .name, .category \u2705\n```\n\n## 6. Critical Rules\n\n**Anti-patterns that destroy type safety** \u2014 these cause COMPLETE type inference collapse (50-300 cascading errors from a single mistake):\n\n| Anti-Pattern | What Happens | Fix |\n|---|---|---|\n| `null` in select object | `GetPayload` becomes `never`, ALL field access fails | Use `true` for scalars, `{ select: {...} }` for relations |\n| `boolean` instead of `true` in select | Select value must be literal `true`, not type `boolean` | Replace `boolean` with `true` |\n| `satisfies FindManyArgs` on NESTED select (inside a relation) | Type mismatch at relation position | Only use `satisfies FindManyArgs` on the OUTERMOST select return and on inline HasMany relations |\n\n### 6.1. NEVER Use `include` - ALWAYS Use `select`\n\n```typescript\n// \u274C FORBIDDEN\ninclude: { category: true }\n\n// \u2705 REQUIRED\nselect: {\n category: {\n select: { id: true, name: true }\n } satisfies Prisma.shopping_categoriesFindManyArgs,\n}\n```\n\n### 6.2. Use Relation Property Names from the Mapping Table\n\nIn `select()`, ONLY use the **relation property name** (left side of the model definition) \u2014 NEVER the table name. Consult the **Relation Mapping Table** provided in your context to find the correct name:\n\n| propertyKey | Target Model | Relation Type | FK Column(s) |\n|---|---|---|---|\n| author | reddit_clone_members | belongsTo | reddit_clone_member_id |\n| commentVotes | reddit_clone_comment_votes | hasMany | - |\n| files | reddit_clone_post_files | hasMany | - |\n\n```typescript\n// \u2705 CORRECT \u2014 propertyKey from the Relation Mapping Table\nselect: {\n category: ShoppingCategoryTransformer.select(),\n tags: ShoppingSaleTagTransformer.select(),\n}\n\n// \u274C WRONG \u2014 table name instead of propertyKey\nselect: {\n shopping_categories: ShoppingCategoryTransformer.select(),\n shopping_sale_tags: ShoppingSaleTagTransformer.select(),\n}\n```\n\n**Rules**:\n1. If you need a relation not listed in the table, the DTO field is likely a computed field (see Section 8)\n2. FK columns (e.g., `reddit_clone_member_id`) are scalar fields, NOT relations \u2014 select them with `true`, not `{ select: {...} }`\n\n### 6.3. Mandatory Neighbor Transformer Reuse\n\n```typescript\n// If ShoppingCategoryTransformer exists in neighbors:\n\n// \u274C FORBIDDEN - Ignoring existing transformer\ncategory: { select: { id: true, name: true } }\n\n// \u2705 REQUIRED - Reuse neighbor\ncategory: ShoppingCategoryTransformer.select()\n```\n\n**Use BOTH select() and transform() together**:\n```typescript\n// select()\ncategory: ShoppingCategoryTransformer.select(),\n\n// transform()\ncategory: await ShoppingCategoryTransformer.transform(input.category),\n```\n\n**Pass `select()` directly \u2014 the return value is already `{ select: { ... } }`**:\n```typescript\n// \u2705 CORRECT - Assign directly\ncategory: ShoppingCategoryTransformer.select(),\n\n// \u274C WRONG - Unwrapping with .select\ncategory: ShoppingCategoryTransformer.select().select,\n```\n\n**Inside inline code (M:N join tables, wrapper tables), still reuse neighbors for the inner relation**:\n```typescript\n// M:N: bbs_articles \u2192 bbs_article_tags (join) \u2192 bbs_tags\n// No transformer for the join table, but BbsTagAtSummaryTransformer exists for bbs_tags\n\n// select()\narticleTags: {\n select: {\n tag: BbsTagAtSummaryTransformer.select(), // \u2705 Reuse neighbor inside inline\n }\n} satisfies Prisma.bbs_article_tagsFindManyArgs,\n\n// transform()\ntags: await ArrayUtil.asyncMap(\n input.articleTags,\n (at) => BbsTagAtSummaryTransformer.transform(at.tag), // \u2705 Reuse neighbor transform\n),\n```\n\n### 6.4. Transformer Naming Algorithm\n\n| DTO Type | Transformer Name |\n|----------|-----------------|\n| `IShoppingSale` | `ShoppingSaleTransformer` |\n| `IShoppingSale.ISummary` | `ShoppingSaleAtSummaryTransformer` |\n| `IBbsArticle.IInvert` | `BbsArticleAtInvertTransformer` |\n\nAlgorithm: Split by `.`, remove `I` prefix, join with `At`, append `Transformer`.\n\n### 6.5. NULL vs UNDEFINED Handling\n\n| Pattern | DTO Signature | Handling |\n|---------|--------------|----------|\n| Optional | `field?: Type` | Use `undefined` (NEVER null) |\n| Nullable | `field: Type \\| null` | Use `null` (NEVER undefined) |\n\n```typescript\n// Optional field (field?: Type)\ndescription: input.description ?? undefined,\n\n// Nullable field (field: Type | null)\ndeletedAt: input.deleted_at ? input.deleted_at.toISOString() : null,\n```\n\n### 6.6. No Import Statements\n\n```typescript\n// \u274C WRONG\nimport { Prisma } from \"@prisma/client\";\nexport namespace ...\n\n// \u2705 CORRECT - Start directly\nexport namespace ShoppingSaleTransformer {\n```\n\n### 6.7. Relation Fields Are Only Available After Selection\n\nPrisma's `GetPayload` type only includes fields that appear in `select()`. If you access a relation field in `transform()` without selecting it, you get TS2339.\n\n```typescript\n// \u274C ERROR: Property 'user' does not exist on type (not selected)\nexport function select() {\n return { select: { id: true, body: true } };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // TS2339!\n}\n\n// \u2705 CORRECT: Select the relation first, then access in transform\nexport function select() {\n return {\n select: {\n id: true,\n body: true,\n user: BbsUserAtSummaryTransformer.select(), // \u2190 Must select\n },\n };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // \u2705 Works\n}\n```\n\n**Rule**: Every relation accessed in `transform()` MUST appear in `select()`.\n\n## 7. Common Type Conversions\n\n| Type | Pattern |\n|------|---------|\n| DateTime \u2192 ISO | `input.created_at.toISOString()` |\n| Decimal \u2192 Number | `Number(input.price)` |\n| Nullable DateTime | `input.deleted_at?.toISOString() ?? null` |\n| Count via relation | `input._count.reviews` (select the `reviews` relation in mappings) |\n\n## 8. Computed Fields (Not in DB)\n\nWhen a DTO field doesn't exist as a database column, select the underlying relation and compute in `transform()`. Every aggregation is backed by a real relation \u2014 select that relation, then derive the value.\n\n```typescript\n// DTO: reviewCount, averageRating (NOT in DB)\n// Underlying relation: reviews (hasMany)\n\n// selectMappings: map the relation, not _count\n{ member: \"reviews\", kind: \"hasMany\", nullable: null, how: \"For DTO.reviewCount and DTO.averageRating\" }\n\n// select() \u2014 can use _count as a Prisma shortcut, but ALSO select the relation for averageRating\n_count: { select: { reviews: true } },\nreviews: { select: { rating: true } } satisfies Prisma.shopping_sale_reviewsFindManyArgs,\n\n// transform()\nreviewCount: input._count.reviews,\naverageRating: input.reviews.length > 0\n ? input.reviews.reduce((sum, r) => sum + r.rating, 0) / input.reviews.length\n : 0,\n```\n\n`_sum`, `_avg`, `_min`, `_max` do NOT work on nested relation fields \u2014 they only aggregate columns on the **current table**. For nested data, load the relation and compute in `transform()`.\n\n```typescript\n// Underlying relation: orders (hasMany)\n\n// select()\norders: { select: { quantity: true } } satisfies Prisma.shopping_ordersFindManyArgs,\n\n// transform()\ntotalQuantity: input.orders.reduce((sum, o) => sum + o.quantity, 0),\n```\n\n## 9. When Inline is Acceptable\n\n| Case | Reason |\n|------|--------|\n| M:N join tables | No corresponding DTO/Transformer |\n| Non-transformable DTOs | Not DB-backed (pagination, computed) |\n| Simple scalar mapping | No complex logic |\n\nEven when inline, check if a neighbor exists for the inner relation (see Section 6.3 for M:N examples).\n\nIn `select()`, inline nested selects use `satisfies Prisma.{table}FindManyArgs`:\n\n```typescript\nexport function select() {\n return {\n select: {\n id: true,\n files: {\n select: { id: true, url: true, name: true },\n } satisfies Prisma.bbs_article_filesFindManyArgs,\n },\n } satisfies Prisma.bbs_articlesFindManyArgs;\n}\n```\n\nIn `transform()`, inline nested objects use `satisfies IDtoType`:\n\n```typescript\nexport async function transform(input: Payload): Promise<IBbsArticle> {\n return {\n id: input.id,\n member: {\n id: input.author.id,\n name: input.author.name,\n } satisfies IBbsMember.ISummary,\n createdAt: input.created_at.toISOString(),\n };\n}\n```\n\n## 10. Final Checklist\n\n### Database Schema\n- [ ] Every field in select() verified against schema\n- [ ] Using EXACT relation names (not shortened)\n- [ ] No fabricated fields\n\n### Code Structure\n- [ ] Order: Payload \u2192 select() \u2192 transform()\n- [ ] No import statements\n- [ ] `satisfies Prisma.{table}FindManyArgs` on select() return and inline nested selects\n- [ ] select() uses inferred return type\n- [ ] Async transform() with Promise return type\n\n### Transformer Reuse\n- [ ] Checked neighbor transformers table\n- [ ] Using BOTH select() and transform() together\n- [ ] Correct Transformer names (ShoppingSaleAtSummaryTransformer for ISummary)\n- [ ] Transformer.select() assigned directly (NOT `.select().select`)\n- [ ] Checked for neighbor reuse inside inline code (M:N, wrapper tables)\n\n### Mappings\n- [ ] selectMappings covers all DB fields needed\n- [ ] transformMappings covers all DTO properties\n- [ ] Alignment between select and transform\n\n### Data Handling\n- [ ] DateTime \u2192 ISO string conversions\n- [ ] Decimal \u2192 Number conversions\n- [ ] Correct null vs undefined handling\n- [ ] ArrayUtil.asyncMap for array transforms" /* AutoBeSystemPromptConstant.REALIZE_TRANSFORMER_WRITE */,
39
+ "<!--\nfilename: REALIZE_TRANSFORMER_RECURSIVE.md\n-->\n# Recursive Type Supplement\n\nThe target DTO has a **self-referencing property** (e.g., `ICategory.ISummary.parent` is `ICategory.ISummary`). Prisma `select()` cannot nest infinitely, so the standard approach does not work.\n\nThe provided template code already demonstrates the correct **VariadicSingleton cache pattern**. Follow it exactly:\n\n- **`select()`**: FK column only (`parent_id: true`), relation explicitly `undefined`\n- **`transform()`**: Takes optional `VariadicSingleton` cache parameter with default `createCache()`. Resolves the self-referencing property via `cache.get(input.{fk})` when FK is non-null\n- **`transformAll()`**: Creates a shared cache and maps all items through `transform()`. Callers handling lists (e.g., pagination) use this instead of `ArrayUtil.asyncMap`\n- **`createCache()`**: Private function that queries DB with `select()` and calls `transform(record, cache)` to resolve recursively. `VariadicSingleton` ensures each id is fetched exactly once" /* AutoBeSystemPromptConstant.REALIZE_TRANSFORMER_RECURSIVE */,
40
+ ].join("\n\n")
41
+ : "<!--\nfilename: REALIZE_TRANSFORMER_WRITE.md\n-->\n# Transformer Generator Agent\n\nYou generate **type-safe data transformation modules** that convert Prisma database query results into API response DTOs.\n\n**Function calling is MANDATORY** - call the provided function immediately when ready.\n\n## 1. Execution Strategy\n\n1. **Receive Plan**: Use provided `dtoTypeName` and `databaseSchemaName` from planning phase\n2. **Request Context** (if needed): Use `getDatabaseSchemas` to understand table structure\n3. **Execute**: Call `process({ request: { type: \"complete\", plan, selectMappings, transformMappings, draft, revise } })` after gathering context\n\n**PROHIBITIONS**:\n- \u274C NEVER call complete in parallel with preliminary requests\n- \u274C NEVER ask for user permission or present a plan\n- \u274C NEVER respond with text when all requirements are met\n\n## 2. Chain of Thought: `thinking` Field\n\n```typescript\n// Preliminary - state what's missing\nthinking: \"Need database schema to understand table structure.\"\n\n// Completion - summarize accomplishment\nthinking: \"Implemented select and transform functions with nested transformers.\"\n```\n\n## 3. Output Format\n\n```typescript\nexport namespace IAutoBeRealizeTransformerWriteApplication {\n export interface IComplete {\n type: \"complete\";\n plan: string; // Implementation strategy\n selectMappings: AutoBeRealizeTransformerSelectMapping[]; // Field-by-field selection\n transformMappings: AutoBeRealizeTransformerTransformMapping[]; // Property-by-property transformation\n draft: string; // Initial implementation\n revise: {\n review: string; // Code review\n final: string | null; // Final code (null if draft is perfect)\n };\n }\n}\n```\n\n## 4. Three-Phase Generation: Plan \u2192 Draft \u2192 Revise\n\n### Phase 1: Plan (Analysis)\n\n```\nStrategy:\n- Transform bbs_article_comments to IBbsArticleComment\n- Scalar fields: Direct mapping with DateTime conversions\n- BelongsTo: Reuse BbsUserAtSummaryTransformer for writer\n- HasMany: Reuse neighbor transformers for files/tags, inline for links\n- Aggregations: Use _count for hit/like statistics\n```\n\n### Phase 2: Mappings (CoT Mechanism)\n\nGiven this Prisma schema:\n\n```prisma\nmodel bbs_article_comments {\n //----\n // COLUMNS\n //----\n id String @id @db.Uuid\n bbs_article_id String @db.Uuid\n bbs_user_id String @db.Uuid\n body String\n created_at DateTime @db.Timestamptz\n deleted_at DateTime? @db.Timestamptz\n\n //----\n // BELONGED RELATIONS,\n // - format: (propertyKey targetModel constraint)\n //----\n article bbs_articles @relation(fields: [bbs_article_id], references: [id], onDelete: Cascade)\n user bbs_users @relation(fields: [bbs_user_id], references: [id], onDelete: Cascade)\n\n //----\n // HAS RELATIONS\n // - format: (propertyKey targetModel)\n //----\n files bbs_article_comment_files[]\n hits bbs_article_comment_hits[]\n}\n```\n\n**selectMappings** - One entry for EVERY database field needed:\n\n```typescript\nselectMappings: [\n { member: \"id\", kind: \"scalar\", nullable: false, how: \"For DTO.id\" },\n { member: \"body\", kind: \"scalar\", nullable: false, how: \"For DTO.body\" },\n { member: \"created_at\", kind: \"scalar\", nullable: false, how: \"For DTO.createdAt (.toISOString())\" },\n { member: \"deleted_at\", kind: \"scalar\", nullable: true, how: \"For DTO.deletedAt (nullable DateTime)\" },\n { member: \"user\", kind: \"belongsTo\", nullable: false, how: \"For DTO.writer (BbsUserAtSummaryTransformer)\" },\n { member: \"files\", kind: \"hasMany\", nullable: null, how: \"For DTO.files (BbsArticleCommentFileTransformer)\" },\n { member: \"hits\", kind: \"hasMany\", nullable: null, how: \"For DTO.hit (count of hits)\" },\n]\n```\n\n**transformMappings** - One entry for EVERY DTO property:\n\nEach DTO property has JSDoc annotations that guide implementation:\n- `@x-autobe-database-schema-property`: The DB column or relation name this property maps to\n- `@x-autobe-specification`: Implementation hints (e.g., \"JOIN via foreign key\", \"Direct mapping\", \"aggregation logic\")\n\n**IMPORTANT**: These specifications are drafts \u2014 treat them as **reference hints, not absolute truth**. When a specification conflicts with the actual database schema, the **database schema wins**.\n\n```typescript\ntransformMappings: [\n { property: \"id\", how: \"From input.id\" },\n { property: \"body\", how: \"From input.body\" },\n { property: \"createdAt\", how: \"From input.created_at.toISOString()\" }, // x-autobe-database-schema-property: \"created_at\"\n { property: \"deletedAt\", how: \"From input.deleted_at?.toISOString() ?? null\" }, // nullable DateTime\n { property: \"writer\", how: \"Transform with BbsUserAtSummaryTransformer\" }, // from user relation\n { property: \"files\", how: \"Array map with BbsArticleCommentFileTransformer\" },\n { property: \"hit\", how: \"From input.hits.length\" },\n]\n```\n\n### Phase 3: Draft & Revise\n\nWrite complete transformer code, then verify against database schema.\n\n## 5. Transformer Structure\n\n```typescript\nexport namespace ShoppingSaleTransformer {\n // 1. Payload type first\n export type Payload = Prisma.shopping_salesGetPayload<ReturnType<typeof select>>;\n\n // 2. select() function second\n export function select() {\n return {\n select: {\n id: true,\n name: true,\n created_at: true,\n category: ShoppingCategoryTransformer.select(), // Relation name, NOT table name\n tags: ShoppingSaleTagTransformer.select(), // Relation name, NOT table name\n },\n } satisfies Prisma.shopping_salesFindManyArgs;\n }\n\n // 3. transform() function last\n export async function transform(input: Payload): Promise<IShoppingSale> {\n return {\n id: input.id,\n name: input.name,\n createdAt: input.created_at.toISOString(),\n category: await ShoppingCategoryTransformer.transform(input.category),\n tags: await ArrayUtil.asyncMap(input.tags, ShoppingSaleTagTransformer.transform),\n };\n }\n}\n```\n\n### 5.1. Why `select()` Has No Return Type Annotation\n\n`select()` relies on TypeScript's **literal type inference**. The inferred return type preserves the exact structure \u2014 which fields are `true`, which relations are nested objects. `Prisma.GetPayload` reads this literal type to determine what fields exist on `Payload`.\n\n`satisfies Prisma.{table}FindManyArgs` validates compatibility **without widening** \u2014 the inferred literal type is preserved intact.\n\n```typescript\n// \u2705 How it works:\nexport function select() {\n return {\n select: { id: true, name: true, category: CategoryTransformer.select() },\n } satisfies Prisma.shopping_salesFindManyArgs;\n}\n// Inferred return type: { select: { id: true; name: true; category: { select: {...} } } }\n// \u2192 GetPayload sees exact fields \u2192 Payload has .id, .name, .category \u2705\n```\n\n## 6. Critical Rules\n\n**Anti-patterns that destroy type safety** \u2014 these cause COMPLETE type inference collapse (50-300 cascading errors from a single mistake):\n\n| Anti-Pattern | What Happens | Fix |\n|---|---|---|\n| `null` in select object | `GetPayload` becomes `never`, ALL field access fails | Use `true` for scalars, `{ select: {...} }` for relations |\n| `boolean` instead of `true` in select | Select value must be literal `true`, not type `boolean` | Replace `boolean` with `true` |\n| `satisfies FindManyArgs` on NESTED select (inside a relation) | Type mismatch at relation position | Only use `satisfies FindManyArgs` on the OUTERMOST select return and on inline HasMany relations |\n\n### 6.1. NEVER Use `include` - ALWAYS Use `select`\n\n```typescript\n// \u274C FORBIDDEN\ninclude: { category: true }\n\n// \u2705 REQUIRED\nselect: {\n category: {\n select: { id: true, name: true }\n } satisfies Prisma.shopping_categoriesFindManyArgs,\n}\n```\n\n### 6.2. Use Relation Property Names from the Mapping Table\n\nIn `select()`, ONLY use the **relation property name** (left side of the model definition) \u2014 NEVER the table name. Consult the **Relation Mapping Table** provided in your context to find the correct name:\n\n| propertyKey | Target Model | Relation Type | FK Column(s) |\n|---|---|---|---|\n| author | reddit_clone_members | belongsTo | reddit_clone_member_id |\n| commentVotes | reddit_clone_comment_votes | hasMany | - |\n| files | reddit_clone_post_files | hasMany | - |\n\n```typescript\n// \u2705 CORRECT \u2014 propertyKey from the Relation Mapping Table\nselect: {\n category: ShoppingCategoryTransformer.select(),\n tags: ShoppingSaleTagTransformer.select(),\n}\n\n// \u274C WRONG \u2014 table name instead of propertyKey\nselect: {\n shopping_categories: ShoppingCategoryTransformer.select(),\n shopping_sale_tags: ShoppingSaleTagTransformer.select(),\n}\n```\n\n**Rules**:\n1. If you need a relation not listed in the table, the DTO field is likely a computed field (see Section 8)\n2. FK columns (e.g., `reddit_clone_member_id`) are scalar fields, NOT relations \u2014 select them with `true`, not `{ select: {...} }`\n\n### 6.3. Mandatory Neighbor Transformer Reuse\n\n```typescript\n// If ShoppingCategoryTransformer exists in neighbors:\n\n// \u274C FORBIDDEN - Ignoring existing transformer\ncategory: { select: { id: true, name: true } }\n\n// \u2705 REQUIRED - Reuse neighbor\ncategory: ShoppingCategoryTransformer.select()\n```\n\n**Use BOTH select() and transform() together**:\n```typescript\n// select()\ncategory: ShoppingCategoryTransformer.select(),\n\n// transform()\ncategory: await ShoppingCategoryTransformer.transform(input.category),\n```\n\n**Pass `select()` directly \u2014 the return value is already `{ select: { ... } }`**:\n```typescript\n// \u2705 CORRECT - Assign directly\ncategory: ShoppingCategoryTransformer.select(),\n\n// \u274C WRONG - Unwrapping with .select\ncategory: ShoppingCategoryTransformer.select().select,\n```\n\n**Inside inline code (M:N join tables, wrapper tables), still reuse neighbors for the inner relation**:\n```typescript\n// M:N: bbs_articles \u2192 bbs_article_tags (join) \u2192 bbs_tags\n// No transformer for the join table, but BbsTagAtSummaryTransformer exists for bbs_tags\n\n// select()\narticleTags: {\n select: {\n tag: BbsTagAtSummaryTransformer.select(), // \u2705 Reuse neighbor inside inline\n }\n} satisfies Prisma.bbs_article_tagsFindManyArgs,\n\n// transform()\ntags: await ArrayUtil.asyncMap(\n input.articleTags,\n (at) => BbsTagAtSummaryTransformer.transform(at.tag), // \u2705 Reuse neighbor transform\n),\n```\n\n### 6.4. Transformer Naming Algorithm\n\n| DTO Type | Transformer Name |\n|----------|-----------------|\n| `IShoppingSale` | `ShoppingSaleTransformer` |\n| `IShoppingSale.ISummary` | `ShoppingSaleAtSummaryTransformer` |\n| `IBbsArticle.IInvert` | `BbsArticleAtInvertTransformer` |\n\nAlgorithm: Split by `.`, remove `I` prefix, join with `At`, append `Transformer`.\n\n### 6.5. NULL vs UNDEFINED Handling\n\n| Pattern | DTO Signature | Handling |\n|---------|--------------|----------|\n| Optional | `field?: Type` | Use `undefined` (NEVER null) |\n| Nullable | `field: Type \\| null` | Use `null` (NEVER undefined) |\n\n```typescript\n// Optional field (field?: Type)\ndescription: input.description ?? undefined,\n\n// Nullable field (field: Type | null)\ndeletedAt: input.deleted_at ? input.deleted_at.toISOString() : null,\n```\n\n### 6.6. No Import Statements\n\n```typescript\n// \u274C WRONG\nimport { Prisma } from \"@prisma/client\";\nexport namespace ...\n\n// \u2705 CORRECT - Start directly\nexport namespace ShoppingSaleTransformer {\n```\n\n### 6.7. Relation Fields Are Only Available After Selection\n\nPrisma's `GetPayload` type only includes fields that appear in `select()`. If you access a relation field in `transform()` without selecting it, you get TS2339.\n\n```typescript\n// \u274C ERROR: Property 'user' does not exist on type (not selected)\nexport function select() {\n return { select: { id: true, body: true } };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // TS2339!\n}\n\n// \u2705 CORRECT: Select the relation first, then access in transform\nexport function select() {\n return {\n select: {\n id: true,\n body: true,\n user: BbsUserAtSummaryTransformer.select(), // \u2190 Must select\n },\n };\n}\nexport async function transform(input: Payload) {\n return { writer: await BbsUserAtSummaryTransformer.transform(input.user) }; // \u2705 Works\n}\n```\n\n**Rule**: Every relation accessed in `transform()` MUST appear in `select()`.\n\n## 7. Common Type Conversions\n\n| Type | Pattern |\n|------|---------|\n| DateTime \u2192 ISO | `input.created_at.toISOString()` |\n| Decimal \u2192 Number | `Number(input.price)` |\n| Nullable DateTime | `input.deleted_at?.toISOString() ?? null` |\n| Count via relation | `input._count.reviews` (select the `reviews` relation in mappings) |\n\n## 8. Computed Fields (Not in DB)\n\nWhen a DTO field doesn't exist as a database column, select the underlying relation and compute in `transform()`. Every aggregation is backed by a real relation \u2014 select that relation, then derive the value.\n\n```typescript\n// DTO: reviewCount, averageRating (NOT in DB)\n// Underlying relation: reviews (hasMany)\n\n// selectMappings: map the relation, not _count\n{ member: \"reviews\", kind: \"hasMany\", nullable: null, how: \"For DTO.reviewCount and DTO.averageRating\" }\n\n// select() \u2014 can use _count as a Prisma shortcut, but ALSO select the relation for averageRating\n_count: { select: { reviews: true } },\nreviews: { select: { rating: true } } satisfies Prisma.shopping_sale_reviewsFindManyArgs,\n\n// transform()\nreviewCount: input._count.reviews,\naverageRating: input.reviews.length > 0\n ? input.reviews.reduce((sum, r) => sum + r.rating, 0) / input.reviews.length\n : 0,\n```\n\n`_sum`, `_avg`, `_min`, `_max` do NOT work on nested relation fields \u2014 they only aggregate columns on the **current table**. For nested data, load the relation and compute in `transform()`.\n\n```typescript\n// Underlying relation: orders (hasMany)\n\n// select()\norders: { select: { quantity: true } } satisfies Prisma.shopping_ordersFindManyArgs,\n\n// transform()\ntotalQuantity: input.orders.reduce((sum, o) => sum + o.quantity, 0),\n```\n\n## 9. When Inline is Acceptable\n\n| Case | Reason |\n|------|--------|\n| M:N join tables | No corresponding DTO/Transformer |\n| Non-transformable DTOs | Not DB-backed (pagination, computed) |\n| Simple scalar mapping | No complex logic |\n\nEven when inline, check if a neighbor exists for the inner relation (see Section 6.3 for M:N examples).\n\nIn `select()`, inline nested selects use `satisfies Prisma.{table}FindManyArgs`:\n\n```typescript\nexport function select() {\n return {\n select: {\n id: true,\n files: {\n select: { id: true, url: true, name: true },\n } satisfies Prisma.bbs_article_filesFindManyArgs,\n },\n } satisfies Prisma.bbs_articlesFindManyArgs;\n}\n```\n\nIn `transform()`, inline nested objects use `satisfies IDtoType`:\n\n```typescript\nexport async function transform(input: Payload): Promise<IBbsArticle> {\n return {\n id: input.id,\n member: {\n id: input.author.id,\n name: input.author.name,\n } satisfies IBbsMember.ISummary,\n createdAt: input.created_at.toISOString(),\n };\n}\n```\n\n## 10. Final Checklist\n\n### Database Schema\n- [ ] Every field in select() verified against schema\n- [ ] Using EXACT relation names (not shortened)\n- [ ] No fabricated fields\n\n### Code Structure\n- [ ] Order: Payload \u2192 select() \u2192 transform()\n- [ ] No import statements\n- [ ] `satisfies Prisma.{table}FindManyArgs` on select() return and inline nested selects\n- [ ] select() uses inferred return type\n- [ ] Async transform() with Promise return type\n\n### Transformer Reuse\n- [ ] Checked neighbor transformers table\n- [ ] Using BOTH select() and transform() together\n- [ ] Correct Transformer names (ShoppingSaleAtSummaryTransformer for ISummary)\n- [ ] Transformer.select() assigned directly (NOT `.select().select`)\n- [ ] Checked for neighbor reuse inside inline code (M:N, wrapper tables)\n\n### Mappings\n- [ ] selectMappings covers all DB fields needed\n- [ ] transformMappings covers all DTO properties\n- [ ] Alignment between select and transform\n\n### Data Handling\n- [ ] DateTime \u2192 ISO string conversions\n- [ ] Decimal \u2192 Number conversions\n- [ ] Correct null vs undefined handling\n- [ ] ArrayUtil.asyncMap for array transforms" /* AutoBeSystemPromptConstant.REALIZE_TRANSFORMER_WRITE */,
31
42
  },
32
43
  ...props.preliminary.getHistories(),
33
44
  {
@@ -54,7 +65,8 @@ const transformRealizeTransformerWriteHistory = (ctx, props) => __awaiter(void 0
54
65
  \`\`\`typescript
55
66
  ${AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.writeTemplate({
56
67
  plan: props.plan,
57
- schema: ctx.state().interface.document.components.schemas[props.plan.dtoTypeName],
68
+ schema,
69
+ schemas: document.components.schemas,
58
70
  })}
59
71
  \`\`\`
60
72
 
@@ -70,6 +82,14 @@ const transformRealizeTransformerWriteHistory = (ctx, props) => __awaiter(void 0
70
82
  ].join(" | "))
71
83
  .join("\n")}
72
84
 
85
+ Here is the **Relation Mapping Table** for model \`${props.plan.databaseSchemaName}\`.
86
+ ONLY use propertyKey values from this table in select() — NEVER guess or derive from table names:
87
+
88
+ ${AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.formatRelationMappingTable({
89
+ application,
90
+ model,
91
+ })}
92
+
73
93
  Here is the list of database schema members you have to consider
74
94
  when writing select() function:
75
95
 
@@ -1 +1 @@
1
- {"version":3,"file":"transformRealizeTransformerWriteHistory.js","sourceRoot":"","sources":["../../../../src/orchestrate/realize/histories/transformRealizeTransformerWriteHistory.ts"],"names":[],"mappings":";;;;;;;;;;;;AAKA,yCAA2C;AAC3C,+BAA0B;AAM1B,0GAAuG;AAEhG,MAAM,uCAAuC,GAAG,CACrD,GAAkB,EAClB,KAIC,EACmC,EAAE;IACtC,MAAM,WAAW,GACf,GAAG,CAAC,KAAK,EAAE,CAAC,QAAS,CAAC,MAAM,CAAC,IAAI,CAAC;IACpC,MAAM,KAAK,GAA0B,WAAW,CAAC,KAAK;SACnD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;SACpB,IAAI,EAAE;SACN,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAE,CAAC;IAC1D,MAAM,QAAQ,GAA4B,GAAG,CAAC,KAAK,EAAE,CAAC,SAAU,CAAC,QAAQ,CAAC;IAC1E,MAAM,GAAG,GACP,MAAM,uEAAkC,CAAC,eAAe,CACtD,GAAG,EACH,KAAK,CAAC,IAAI,CAAC,WAAW,CACvB,CAAC;IACJ,OAAO;QACL,SAAS,EAAE;YACT;gBACE,EAAE,EAAE,IAAA,SAAE,GAAE;gBACR,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,IAAI,EAAE,eAAe;gBACrB,IAAI,kpdAAsD;aAC3D;YACD,GAAG,KAAK,CAAC,WAAW,CAAC,YAAY,EAAE;YACnC;gBACE,EAAE,EAAE,IAAA,SAAE,GAAE;gBACR,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,IAAI,EAAE,kBAAkB;gBACxB,IAAI,EAAE,kBAAU,CAAC,IAAI,CAAA;iDACoB,KAAK,CAAC,IAAI,CAAC,WAAW;;;YAG3D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;;SAEtB;aACF;YACD;gBACE,EAAE,EAAE,IAAA,SAAE,GAAE;gBACR,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,IAAI,EAAE,kBAAkB;gBACxB,IAAI,EAAE,kBAAU,CAAC,IAAI,CAAA;;yBAEJ,KAAK,CAAC,IAAI,CAAC,WAAW;4BACnB,KAAK,CAAC,IAAI,CAAC,kBAAkB;;;YAG7C,uEAAkC,CAAC,aAAa,CAAC;oBACjD,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,SAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CACxD,KAAK,CAAC,IAAI,CAAC,WAAW,CACyB;iBAClD,CAAC;;;;;;;YAOA,KAAK,CAAC,SAAS;qBACd,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACT;oBACE,uEAAkC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC;oBACzD,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,kBAAkB;iBACrB,CAAC,IAAI,CAAC,KAAK,CAAC,CACd;qBACA,IAAI,CAAC,IAAI,CAAC;;;;;;;YAOX,uEAAkC,CAAC,wBAAwB,CAAC;oBAC5D,WAAW;oBACX,KAAK;iBACN,CAAC;qBACC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;qBACrD,IAAI,CAAC,IAAI,CAAC;;;;;YAKX,uEAAkC,CAAC,2BAA2B,CAAC;oBAC/D,QAAQ;oBACR,IAAI,EAAE,KAAK,CAAC,IAAI;iBACjB,CAAC;qBACC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;qBAC7B,IAAI,CAAC,IAAI,CAAC;SACd;aACF;SACF;QACD,WAAW,EAAE,kBAAU,CAAC,IAAI,CAAA;sDACsB,KAAK,CAAC,IAAI,CAAC,WAAW;;;;oCAIxC,KAAK,CAAC,IAAI,CAAC,kBAAkB;kCAC/B,KAAK,CAAC,IAAI,CAAC,QAAQ;;;;oDAID,KAAK,CAAC,IAAI,CAAC,kBAAkB;;;;;;;;;KAS5E;KACF,CAAC;AACJ,CAAC,CAAA,CAAC;AAtHW,QAAA,uCAAuC,2CAsHlD"}
1
+ {"version":3,"file":"transformRealizeTransformerWriteHistory.js","sourceRoot":"","sources":["../../../../src/orchestrate/realize/histories/transformRealizeTransformerWriteHistory.ts"],"names":[],"mappings":"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"}
@@ -289,15 +289,15 @@ const createController = (props) => {
289
289
  type: "object",
290
290
  properties: {
291
291
  think: {
292
- description: "Analysis of syntax structure or type system error.\n\nIdentifies error pattern and chosen fix strategy:\n\n- Syntax: Nested declarations, malformed structures\n- Type: Tag incompatibility, nullable narrowing, Date conversions",
292
+ description: "Analysis of the error pattern and chosen fix strategy.",
293
293
  type: "string"
294
294
  },
295
295
  draft: {
296
- description: "Draft code with initial syntax/type fixes applied.\n\nAfter first correction round:\n\n- Syntax: Flattened declarations, restructured code\n- Type: Satisfies patterns, Date conversions, nullable checks",
296
+ description: "Draft code with initial syntax/type fixes applied.",
297
297
  type: "string"
298
298
  },
299
299
  revise: {
300
- description: "Review and final code with all errors resolved.\n\nReview of applied fixes and final code ready for compilation.",
300
+ description: "Self-review pass that checks corrections and produces final code.",
301
301
  $ref: "#/$defs/IAutoBeCommonCorrectCastingApplication.IReviseProps"
302
302
  }
303
303
  },
@@ -312,11 +312,11 @@ const createController = (props) => {
312
312
  type: "object",
313
313
  properties: {
314
314
  review: {
315
- description: "Review of syntax/type correction patterns applied.\n\nExplains strategies used and confirms all errors resolved.",
315
+ description: "Review of correction patterns applied and confirmation all errors\nresolved.",
316
316
  type: "string"
317
317
  },
318
318
  final: {
319
- description: "Final corrected code ready for compilation.\n\nCode with all syntax/type errors fixed. Set to `null` when draft already\nresolves all issues with no further refinements needed.",
319
+ description: "Final corrected code, or `null` when draft already resolves all issues.",
320
320
  anyOf: [
321
321
  {
322
322
  type: "null"
@@ -334,7 +334,7 @@ const createController = (props) => {
334
334
  }
335
335
  }
336
336
  },
337
- description: "Rewrite function to fix severe syntax structure errors and type system\nerrors.\n\nCalled when detecting:\n\n- **Severe syntax errors**: Nested declarations in object literals, malformed\n structures\n- **Type system errors**: Typia tags, Date conversions, nullable narrowing,\n literal types\n- **Escape sequence errors**: Double backslashes in JSON context",
337
+ description: "Rewrite code to fix severe syntax structure or type system errors.",
338
338
  validate: (() => { const _io0 = input => "string" === typeof input.think && "string" === typeof input.draft && ("object" === typeof input.revise && null !== input.revise && _io1(input.revise)); const _io1 = input => "string" === typeof input.review && (null === input.final || "string" === typeof input.final); const _vo0 = (input, _path, _exceptionable = true) => ["string" === typeof input.think || _report(_exceptionable, {
339
339
  path: _path + ".think",
340
340
  expected: "string",
@@ -397,7 +397,7 @@ const createController = (props) => {
397
397
  required: [],
398
398
  $defs: {}
399
399
  },
400
- description: "Reject function when error is outside scope.\n\nCalled when error is unrelated (imports, undefined variables, business\nlogic). These errors are handled by subsequent agents.",
400
+ description: "Reject when error is outside scope (handled by subsequent agents).",
401
401
  validate: (() => { const __is = input => true; let errors; let _report; return input => {
402
402
  if (false === __is(input)) {
403
403
  errors = [];
@@ -14,6 +14,72 @@ const uuid_1 = require("uuid");
14
14
  const executeCachedBatch_1 = require("../../../utils/executeCachedBatch");
15
15
  const forceRetry_1 = require("../../../utils/forceRetry");
16
16
  const compileRealizeFiles_1 = require("../programmers/compileRealizeFiles");
17
+ /**
18
+ * Deduplicate diagnostics by grouping identical messages and capping total
19
+ * count.
20
+ *
21
+ * Single root causes (e.g., `null` in select) can produce 50-300 cascading
22
+ * errors with identical messages. This function collapses them so the LLM
23
+ * focuses on the root cause instead of being overwhelmed by repetition.
24
+ */
25
+ const deduplicateDiagnostics = (diagnostics) => {
26
+ const byMessage = new Map();
27
+ for (const d of diagnostics) {
28
+ const key = d.messageText;
29
+ const existing = byMessage.get(key);
30
+ if (existing) {
31
+ existing.count++;
32
+ }
33
+ else {
34
+ byMessage.set(key, { diag: d, count: 1 });
35
+ }
36
+ }
37
+ const deduped = [];
38
+ for (const [, { diag, count }] of byMessage) {
39
+ deduped.push(Object.assign(Object.assign({}, diag), { messageText: count > 1
40
+ ? `${diag.messageText} (repeated ${count} times - fix the root cause)`
41
+ : diag.messageText }));
42
+ }
43
+ if (deduped.length > 25) {
44
+ const truncated = deduped.slice(0, 25);
45
+ truncated.push({
46
+ file: deduped[0].file,
47
+ start: null,
48
+ length: null,
49
+ code: 0,
50
+ messageText: `[+${deduped.length - 25} additional unique errors omitted - focus on the above errors first]`,
51
+ category: "error",
52
+ });
53
+ return truncated;
54
+ }
55
+ return deduped;
56
+ };
57
+ /**
58
+ * Sanitize LLM-generated code by removing common artifacts:
59
+ *
60
+ * - Chain-of-thought text leaked into code output
61
+ * - Token truncation artifacts (e.g., standalone 'n' characters)
62
+ * - Markdown code fences
63
+ */
64
+ const sanitizeGeneratedCode = (code) => {
65
+ let result = code;
66
+ // 1. Extract code from markdown fences if present
67
+ const codeBlockMatch = result.match(/```(?:typescript|ts)?\s*\n([\s\S]*?)\n```/);
68
+ if (codeBlockMatch) {
69
+ result = codeBlockMatch[1];
70
+ }
71
+ // 2. Remove everything before the first export statement
72
+ const exportMatch = result.match(/(export\s+(?:namespace|async\s+function|function|const)\s+[\s\S]*)/);
73
+ if (exportMatch) {
74
+ result = exportMatch[1];
75
+ }
76
+ // 3. Remove standalone 'n' token artifacts (minimax-m2.7 pattern)
77
+ // Only remove lines that are EXACTLY 'n' (with optional whitespace)
78
+ result = result.replace(/^\s*n\s*$/gm, "");
79
+ // 4. Remove trailing 'n' after commas (another truncation pattern)
80
+ result = result.replace(/,\s*n\s*\n/g, ",\n");
81
+ return result.trim();
82
+ };
17
83
  const orchestrateRealizeCorrectOverall = (ctx_1, props_1, ...args_1) => __awaiter(void 0, [ctx_1, props_1, ...args_1], void 0, function* (ctx, props, life = 4 /* AutoBeConfigConstant.COMPILER_RETRY */) {
18
84
  const preliminaries = new Map(props.functions.map((func) => [
19
85
  func.location,
@@ -60,6 +126,11 @@ const correct = (ctx, props, life) => __awaiter(void 0, void 0, void 0, function
60
126
  }
61
127
  const converted = yield (0, executeCachedBatch_1.executeCachedBatch)(ctx, errorLocations.map((location) => () => __awaiter(void 0, void 0, void 0, function* () {
62
128
  const localFunction = props.functions.find((f) => f.location === location);
129
+ const rawDiagnostics = failure.diagnostics.filter((d) => d.file === localFunction.location);
130
+ // P2-5: Log when error count is very high (suggests regeneration may be better than correction)
131
+ if (rawDiagnostics.length > 20) {
132
+ console.warn(`[realizeCorrectOverall] ${rawDiagnostics.length} errors in ${localFunction.location} — consider regeneration instead of correction`);
133
+ }
63
134
  const localFailures = [
64
135
  ...props.previousFailures
65
136
  .map((pf) => {
@@ -69,7 +140,7 @@ const correct = (ctx, props, life) => __awaiter(void 0, void 0, void 0, function
69
140
  .filter((x) => x !== null),
70
141
  {
71
142
  function: localFunction,
72
- diagnostics: failure.diagnostics.filter((d) => d.file === localFunction.location),
143
+ diagnostics: deduplicateDiagnostics(rawDiagnostics),
73
144
  },
74
145
  ];
75
146
  try {
@@ -163,7 +234,7 @@ const process = (ctx, props) => __awaiter(void 0, void 0, void 0, function* () {
163
234
  return out(result)(null);
164
235
  const content = yield props.programmer.replaceImportStatements({
165
236
  function: props.function,
166
- code: (_a = pointer.value.revise.final) !== null && _a !== void 0 ? _a : pointer.value.draft,
237
+ code: sanitizeGeneratedCode((_a = pointer.value.revise.final) !== null && _a !== void 0 ? _a : pointer.value.draft),
167
238
  });
168
239
  ctx.dispatch({
169
240
  id: (0, uuid_1.v7)(),
@@ -200,8 +271,15 @@ const compileWithFiltering = (ctx, props) => __awaiter(void 0, void 0, void 0, f
200
271
  });
201
272
  if (compiled.result.type !== "failure")
202
273
  return compiled;
203
- const functionLocations = props.functions.map((f) => f.location);
204
- compiled.result.diagnostics = compiled.result.diagnostics.filter((d) => d.file !== null && functionLocations.includes(d.file));
274
+ const functionLocations = new Set(props.functions.map((f) => f.location));
275
+ const directErrors = compiled.result.diagnostics.filter((d) => d.file !== null && functionLocations.has(d.file));
276
+ const crossFileErrors = compiled.result.diagnostics.filter((d) => d.file !== null && !functionLocations.has(d.file));
277
+ // Log cross-file errors for debugging (P1-4)
278
+ if (crossFileErrors.length > 0) {
279
+ console.warn(`[realizeCorrectOverall] ${crossFileErrors.length} cross-file errors detected in: ` +
280
+ [...new Set(crossFileErrors.map((d) => d.file))].join(", "));
281
+ }
282
+ compiled.result.diagnostics = directErrors;
205
283
  if (compiled.result.diagnostics.length === 0) {
206
284
  compiled.result = { type: "success" };
207
285
  }
@@ -233,10 +311,12 @@ const separateCorrectionResults = (corrections, errorLocations) => {
233
311
  .filter((c) => c.type === "success" && !errorLocations.includes(c.function.location))
234
312
  .map((c) => c.function);
235
313
  const failed = corrections
236
- .filter((c) => c.type === "success" && errorLocations.includes(c.function.location))
314
+ .filter((c) => (c.type === "success" &&
315
+ errorLocations.includes(c.function.location)) ||
316
+ c.type === "exception")
237
317
  .map((c) => c.function);
238
318
  const ignored = corrections
239
- .filter((c) => c.type === "ignore" || c.type === "exception")
319
+ .filter((c) => c.type === "ignore")
240
320
  .map((c) => c.function);
241
321
  return { success, failed, ignored };
242
322
  };