UNPKG

@autobe/agent

Version:

AI backend server code generator

607 lines 281 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.orchestratePrismaCorrect = orchestratePrismaCorrect; const __typia_transform__isUniqueItems = __importStar(require("typia/lib/internal/_isUniqueItems.js")); const __typia_transform__validateReport = __importStar(require("typia/lib/internal/_validateReport.js")); const __typia_transform__llmApplicationFinalize = __importStar(require("typia/lib/internal/_llmApplicationFinalize.js")); const typia_1 = __importDefault(require("typia")); const uuid_1 = require("uuid"); const assertSchemaModel_1 = require("../../context/assertSchemaModel"); const AutoBePreliminaryController_1 = require("../common/AutoBePreliminaryController"); const transformPrismaCorrectHistory_1 = require("./histories/transformPrismaCorrectHistory"); function orchestratePrismaCorrect(ctx, application) { const unique = new Set(); for (const file of application.files) file.models = file.models.filter((model) => { if (unique.has(model.name)) return false; unique.add(model.name); return true; }); application.files = application.files.filter((f) => f.models.length !== 0); return iterate(ctx, application, Math.max(ctx.retry, 8)); } function iterate(ctx, application, life) { return __awaiter(this, void 0, void 0, function* () { var _a, _b; const compiler = yield ctx.compiler(); const result = yield compiler.prisma.validate(application); if (result.success) return result; // SUCCESS else if (life < 0) return result; // FAILURE // VALIDATION FAILED const schemas = yield compiler.prisma.write(application, "postgres"); ctx.dispatch({ type: "prismaValidate", id: (0, uuid_1.v7)(), result, schemas, compiled: yield compiler.prisma.compile({ files: schemas, }), step: (_b = (_a = ctx.state().analyze) === null || _a === void 0 ? void 0 : _a.step) !== null && _b !== void 0 ? _b : 0, created_at: new Date().toISOString(), }); const next = yield process(ctx, result); return iterate(ctx, next.correction, life - 1); }); } function process(ctx_1, failure_1) { return __awaiter(this, arguments, void 0, function* (ctx, failure, capacity = 8) { const count = getTableCount(failure); if (count <= capacity) return execute(ctx, failure); let correction = failure.data; const volume = Math.ceil(count / capacity); const plannings = []; const models = {}; let i = 0; while (i++ < volume && failure.errors.length !== 0) { const next = yield execute(ctx, Object.assign(Object.assign({}, failure), { errors: (() => { var _a; const unique = new Set(); const errors = []; for (const err of failure.errors) { unique.add((_a = err.table) !== null && _a !== void 0 ? _a : null); if (unique.size > capacity) break; else errors.push(err); } return errors; })() })); plannings.push(next.planning); for (const m of next.models) models[m.name] = m; const compiler = yield ctx.compiler(); const result = yield compiler.prisma.validate(next.correction); correction = next.correction; if (result.success === true) break; else failure = result; } return { type: "complete", planning: plannings.join("\n\n"), models: Object.values(models), correction, }; }); } function execute(ctx, failure) { return __awaiter(this, void 0, void 0, function* () { const preliminary = new AutoBePreliminaryController_1.AutoBePreliminaryController({ application: { version: "3.1", components: { schemas: { "IAutoBePrismaCorrectApplication.IProps": { type: "object", properties: { thinking: { type: "string", description: "Think before you act.\n\nBefore requesting preliminary data or completing your task, reflect on your\ncurrent state and explain your reasoning:\n\nFor preliminary requests (getAnalysisFiles, getPrismaSchemas, etc.):\n- What critical information is missing that you don't already have?\n- Why do you need it specifically right now?\n- Be brief - state the gap, don't list everything you have.\n\nFor completion (complete):\n- What key assets did you acquire?\n- What did you accomplish?\n- Why is it sufficient to complete?\n- Summarize - don't enumerate every single item.\n\nThis reflection helps you avoid duplicate requests and premature completion." }, request: { oneOf: [ { $ref: "#/components/schemas/IAutoBePreliminaryGetAnalysisFiles" }, { $ref: "#/components/schemas/IAutoBePreliminaryGetPrismaSchemas" }, { $ref: "#/components/schemas/IAutoBePrismaCorrectApplication.IComplete" } ], discriminator: { propertyName: "type", mapping: { getAnalysisFiles: "#/components/schemas/IAutoBePreliminaryGetAnalysisFiles", getPrismaSchemas: "#/components/schemas/IAutoBePreliminaryGetPrismaSchemas", complete: "#/components/schemas/IAutoBePrismaCorrectApplication.IComplete" } }, description: "Type discriminator for the request.\n\nDetermines which action to perform: preliminary data retrieval\n(getAnalysisFiles, getPrismaSchemas) or final schema correction\n(complete). When preliminary returns empty array, that type is removed\nfrom the union, physically preventing repeated calls." } }, required: [ "thinking", "request" ] }, IAutoBePreliminaryGetAnalysisFiles: { type: "object", properties: { type: { "const": "getAnalysisFiles", description: "Type discriminator for the request.\n\nDetermines which action to perform: preliminary data retrieval or actual\ntask execution. Value \"getAnalysisFiles\" indicates this is a preliminary\ndata request for analysis files." }, fileNames: { type: "array", items: { type: "string" }, minItems: 1, description: "List of analysis file names to retrieve.\n\nFile names from the analyze phase containing requirements, use cases, and\nbusiness logic documentation.\n\nCRITICAL: DO NOT request the same file names that you have already\nrequested in previous calls." } }, required: [ "type", "fileNames" ], description: "Request to retrieve requirements analysis files for context.\n\nThis type is used in the preliminary phase to request specific analysis files\nthat provide business requirements and domain context." }, IAutoBePreliminaryGetPrismaSchemas: { type: "object", properties: { type: { "const": "getPrismaSchemas", description: "Type discriminator for the request.\n\nDetermines which action to perform: preliminary data retrieval or actual\ntask execution. Value \"getPrismaSchemas\" indicates this is a preliminary\ndata request for Prisma schemas." }, schemaNames: { type: "array", items: { type: "string" }, minItems: 1, description: "List of Prisma table names to retrieve.\n\nTable names from the Prisma schema file representing database entities\n(e.g., \"user\", \"post\", \"comment\").\n\nCRITICAL: DO NOT request the same schema names that you have already\nrequested in previous calls." } }, required: [ "type", "schemaNames" ], description: "Request to retrieve Prisma database schema definitions for context.\n\nThis type is used in the preliminary phase to request specific Prisma table\nschemas needed for generating type-safe API operations." }, "IAutoBePrismaCorrectApplication.IComplete": { type: "object", properties: { type: { "const": "complete", description: "Type discriminator for the request.\n\nDetermines which action to perform: preliminary data retrieval or actual\ntask execution. Value \"complete\" indicates this is the final task\nexecution request." }, planning: { type: "string", description: "Detailed execution plan for fixing validation errors.\n\nContains systematic reasoning and step-by-step error resolution approach\nfor targeted model validation issues.\n\nRequired planning content:\n\n1. Error scope analysis:\n\n - List all validation errors from IAutoBePrismaValidation.IError[]\n - Extract unique table names to identify affected models\n - Categorize errors by type (field duplications, references, types,\n indexes)\n - Identify which models need correction vs. remain unchanged\n2. Targeted fix strategy:\n\n - Focus ONLY on models mentioned in validation errors\n - Outline minimal changes needed for each affected model\n - Plan cross-model reference updates without modifying non-error models\n - Ensure unchanged models maintain valid references to corrected models\n3. Model-specific fix plan:\n\n - Model-by-model modification plan for ONLY affected models\n - Exact field additions, renames, or type corrections required\n - Reference updates within corrected models only\n - Index corrections limited to affected models\n4. Minimal scope validation:\n\n - Confirm which models will be included in output (error models only)\n - List models that will remain unchanged in original schema\n - Identify cross-model dependencies without including unchanged models\n - Preserve all business logic within corrected models\n5. Targeted impact assessment:\n\n - Potential effects of fixes on unchanged models (reference validation)\n - Verification points for corrected models only\n - Ensure no new validation errors in targeted models\n - Confirm minimal output scope compliance" }, models: { type: "array", items: { $ref: "#/components/schemas/AutoBePrisma.IModel" }, description: "Models with validation errors that need correction.\n\nContains ONLY models mentioned in IAutoBePrismaValidation.IError[] array.\nEach model has specific validation errors requiring targeted correction.\nModels not mentioned in errors are excluded from this input.\n\nExpected validation issues:\n\n- Duplicate field/relation names within these specific models\n- Invalid foreign key references from these models to other models\n- Single foreign key fields in index arrays within these models\n- Invalid naming conventions within these specific models\n- Type validation errors in fields of these models\n\nModel content analysis:\n\n- Complete field definitions for each error model only\n- Relationships from these models (may reference unchanged models)\n- Indexes within these models that need correction\n- Business descriptions specific to these models\n- Cross-model references that need validation (read-only for targets)\n\nProcessing notes:\n\n- Input contains ONLY models with validation errors\n- May reference other models not included in this input\n- Cross-model references must be validated but target models won't be\n modified\n- Output should return corrected versions of ONLY these input models\n- All business logic and descriptions within these models must be preserved\n- Corrections must not break references from unchanged models" } }, required: [ "type", "planning", "models" ], description: "Request to fix validation errors in Prisma models.\n\nExecutes targeted error correction to resolve specific validation issues in\naffected models only. Applies minimal changes while preserving original\ndesign intent and business logic." }, "AutoBePrisma.IModel": { type: "object", properties: { name: { type: "string", pattern: "^[a-z][a-z0-9_]*$", description: "Name of the Prisma model (database table name).\n\nMUST use snake_case naming convention. Examples: \"shopping_customers\",\n\"shopping_sale_snapshots\", \"bbs_articles\" Materialized views use \"mv_\"\nprefix: \"mv_shopping_sale_last_snapshots\"" }, description: { type: "string", description: "Detailed description explaining the business purpose and usage of the\nmodel.\n\nShould include:\n\n- Business context and purpose\n- Key relationships with other models\n- Important behavioral notes or constraints\n- References to related entities using \"{@\\link ModelName}\" syntax\n\n**IMPORTANT**: Description must be written in English. Example: \"Customer\ninformation, but not a person but a **connection** basis...\"" }, material: { type: "boolean", description: "Indicates whether this model represents a materialized view for\nperformance optimization.\n\nMaterialized views are read-only computed tables that cache complex query\nresults. They're marked as \"@\\hidden\" in documentation and prefixed with\n\"mv_\" in naming. Examples: mv_shopping_sale_last_snapshots,\nmv_shopping_cart_commodity_prices" }, stance: { oneOf: [ { "const": "primary" }, { "const": "subsidiary" }, { "const": "snapshot" } ], description: "Specifies the architectural stance of this model within the database\nsystem.\n\nThis property defines how the table positions itself in relation to other\ntables and what role it plays in the overall data architecture,\nparticularly for API endpoint generation and business logic\norganization.\n\n## Values:\n\n### `\"primary\"` - Main Business Entity\n\nTables that represent core business concepts and serve as the primary\nsubjects of user operations. These tables typically warrant independent\nCRUD API endpoints since users directly interact with these entities.\n\n**Key principle**: If users need to independently create, search, filter,\nor manage entities regardless of their parent context, the table should\nbe primary stance.\n\n**API Requirements:**\n\n- Independent creation endpoints (POST /articles, POST /comments)\n- Search and filtering capabilities across all instances\n- Direct update and delete operations\n- List/pagination endpoints for browsing\n\n**Why `bbs_article_comments` is primary, not subsidiary:**\n\nAlthough comments belong to articles, they require independent\nmanagement:\n\n- **Search across articles**: \"Find all comments by user X across all\n articles\"\n- **Moderation workflows**: \"List all pending comments for review\"\n- **User activity**: \"Show all comments made by this user\"\n- **Independent operations**: Users edit/delete their comments directly\n- **Notification systems**: \"Alert when any comment is posted\"\n\nIf comments were subsidiary, these operations would be impossible or\nrequire inefficient nested queries through parent articles.\n\n**Characteristics:**\n\n- Represents tangible business concepts that users manage\n- Serves as reference points for other tables\n- Requires comprehensive API operations (CREATE, READ, UPDATE, DELETE)\n- Forms the backbone of the application's business logic\n\n**Examples:**\n\n- `bbs_articles` - Forum posts that users create, edit, and manage\n- `bbs_article_comments` - User comments that require independent\n management\n\n### `\"subsidiary\"` - Supporting/Dependent Entity\n\nTables that exist to support primary entities but are not independently\nmanaged by users. These tables are typically managed through their parent\nentities and may not need standalone API endpoints.\n\n**Characteristics:**\n\n- Depends on primary or snapshot entities for context\n- Often managed indirectly through parent entity operations\n- May have limited or no independent API operations\n- Provides supporting data or relationships\n\n**Examples:**\n\n- `bbs_article_snapshot_files` - Files attached to article snapshots\n- `bbs_article_snapshot_tags` - Tags associated with article snapshots\n- `bbs_article_comment_snapshot_files` - Files attached to comment\n snapshots\n\n### `\"snapshot\"` - Historical/Versioning Entity\n\nTables that capture point-in-time states of primary entities for audit\ntrails, version control, or historical tracking. These tables record\nchanges but are rarely modified directly by users.\n\n**Characteristics:**\n\n- Captures historical states of primary entities\n- Typically append-only (rarely updated or deleted)\n- Referenced for audit trails and change tracking\n- Usually read-only from user perspective\n\n**Examples:**\n\n- `bbs_article_snapshots` - Historical states of articles\n- `bbs_article_comment_snapshots` - Comment modification history\n\n## API Generation Guidelines:\n\nThe stance property guides automatic API endpoint generation:\n\n- **`\"primary\"`** \u2192 Generate full CRUD endpoints based on business\n requirements\n- **`\"subsidiary\"`** \u2192 Evaluate carefully; often managed through parent\n entities\n- **`\"snapshot\"`** \u2192 Typically read-only endpoints for historical data\n access" }, primaryField: { $ref: "#/components/schemas/AutoBePrisma.IPrimaryField", description: "The primary key field of the model.\n\nIn all uploaded schemas, primary keys are always UUID type with \"@\\id\"\ndirective. Usually named \"id\" and marked with \"@\\db.Uuid\" for PostgreSQL\nmapping." }, foreignFields: { type: "array", items: { $ref: "#/components/schemas/AutoBePrisma.IForeignField" }, description: "Array of foreign key fields that reference other models.\n\nThese establish relationships between models and include Prisma relation\ndirectives. Can be nullable (optional relationships) or required\n(mandatory relationships). May have unique constraints for 1:1\nrelationships." }, plainFields: { type: "array", items: { $ref: "#/components/schemas/AutoBePrisma.IPlainField" }, description: "Array of regular data fields that don't reference other models.\n\nInclude business data like names, descriptions, timestamps, flags,\namounts, etc. Common patterns: created_at, updated_at, deleted_at for\nsoft deletion and auditing." }, uniqueIndexes: { type: "array", items: { $ref: "#/components/schemas/AutoBePrisma.IUniqueIndex" }, description: "Array of unique indexes for enforcing data integrity constraints.\n\nEnsure uniqueness across single or multiple columns. Examples: unique\nemail addresses, unique codes within a channel, unique combinations like\n(channel_id, nickname)." }, plainIndexes: { type: "array", items: { $ref: "#/components/schemas/AutoBePrisma.IPlainIndex" }, description: "Array of regular indexes for query performance optimization.\n\nSpeed up common query patterns like filtering by foreign keys, date\nranges, or frequently searched fields. Examples: indexes on created_at,\nforeign key fields, search fields." }, ginIndexes: { type: "array", items: { $ref: "#/components/schemas/AutoBePrisma.IGinIndex" }, description: "Array of GIN (Generalized Inverted Index) indexes for full-text search.\n\nUsed specifically for PostgreSQL text search capabilities using trigram\noperations. Applied to text fields that need fuzzy matching or partial\ntext search. Examples: searching names, nicknames, titles, content\nbodies." } }, required: [ "name", "description", "material", "stance", "primaryField", "foreignFields", "plainFields", "uniqueIndexes", "plainIndexes", "ginIndexes" ], description: "Interface representing a single Prisma model (database table).\n\nBased on the uploaded schemas, models follow specific patterns:\n\n- Main business entities (e.g., shopping_sales, shopping_customers)\n- Snapshot/versioning entities for audit trails (e.g.,\n shopping_sale_snapshots)\n- Junction tables for M:N relationships (e.g.,\n shopping_cart_commodity_stocks)\n- Materialized views for performance (prefixed with mv_)" }, "AutoBePrisma.IPrimaryField": { type: "object", properties: { name: { type: "string", pattern: "^[a-z][a-z0-9_]*$", description: "Name of the primary key field.\n\nMUST use snake_case naming convention. Consistently named \"id\" across all\nmodels in the uploaded schemas. Represents the unique identifier for each\nrecord in the table." }, type: { "const": "uuid", description: "Data type of the primary key field.\n\nAlways \"uuid\" in the uploaded schemas for better distributed system\nsupport and to avoid exposing sequential IDs that could reveal business\ninformation." }, description: { type: "string", description: "Description of the primary key field's purpose.\n\nStandard description is \"Primary Key.\" across all models. Serves as the\nunique identifier for the model instance.\n\n**IMPORTANT**: Description must be written in English." } }, required: [ "name", "type", "description" ], description: "Interface representing the primary key field of a Prisma model.\n\nAll models in the uploaded schemas use UUID as primary key for better\ndistributed system compatibility and security (no sequential ID exposure)." }, "AutoBePrisma.IForeignField": { type: "object", properties: { name: { type: "string", pattern: "^[a-z][a-z0-9_]*$", description: "Name of the foreign key field.\n\nMUST use snake_case naming convention. Follows convention:\n\"{target_model_name_without_prefix}_id\" Examples: \"shopping_customer_id\",\n\"bbs_article_id\", \"attachment_file_id\" For self-references: \"parent_id\"\n(e.g., in hierarchical structures)" }, type: { "const": "uuid", description: "Data type of the foreign key field.\n\nAlways \"uuid\" to match the primary key type of referenced models. Ensures\nreferential integrity and consistency across the schema." }, description: { type: "string", description: "Description explaining the purpose and target of this foreign key\nrelationship.\n\nShould reference the target model using format: \"Target model's {@\\link\nModelName.id}\" Examples: \"Belonged customer's {@\\link\nshopping_customers.id}\" May include additional context about the\nrelationship's business meaning.\n\n**IMPORTANT**: Description must be written in English." }, relation: { $ref: "#/components/schemas/AutoBePrisma.IRelation", description: "Prisma relation configuration defining the association details.\n\nSpecifies how this foreign key connects to the target model, including\nrelation name, target model, and target field. This configuration is used\nto generate the appropriate Prisma relation directive in the schema." }, unique: { type: "boolean", description: "Whether this foreign key has a unique constraint.\n\nTrue: Creates a 1:1 relationship (e.g., user profile, order publish\ndetails) false: Allows 1:N relationship (e.g., customer to multiple\norders) Used for enforcing business rules about relationship\ncardinality." }, nullable: { type: "boolean", description: "Whether this foreign key can be null (optional relationship).\n\nTrue: Relationship is optional, foreign key can be null false:\nRelationship is required, foreign key cannot be null Reflects business\nrules about mandatory vs optional associations." } }, required: [ "name", "type", "description", "relation", "unique", "nullable" ], description: "Interface representing a foreign key field that establishes relationships\nbetween models.\n\nForeign keys create associations between models, enabling relational data\nmodeling. They can represent 1:1, 1:N, or participate in M:N relationships\nthrough junction tables." }, "AutoBePrisma.IRelation": { type: "object", properties: { name: { type: "string", pattern: "^[a-z][a-zA-Z0-9]*$", description: "Name of the relation property in the Prisma model.\n\nThis becomes the property name used to access the related model instance\nthrough the Prisma client. Should be descriptive and reflect the business\nrelationship being modeled.\n\nExamples:\n\n- \"customer\" for shopping_customer_id field\n- \"channel\" for shopping_channel_id field\n- \"parent\" for parent_id field in hierarchical structures\n- \"snapshot\" for versioning relationships\n- \"article\" for bbs_article_id field\n\nNaming convention: camelCase, descriptive of the relationship's business\nmeaning" }, targetModel: { type: "string", description: "Name of the target model being referenced by this relation.\n\nMust exactly match an existing model name in the schema. This is used by\nPrisma to establish the foreign key constraint and generate the\nappropriate relation mapping.\n\nExamples:\n\n- \"shopping_customers\" for customer relationships\n- \"shopping_channels\" for channel relationships\n- \"bbs_articles\" for article relationships\n- \"attachment_files\" for file attachments\n\nThe target model should exist in the same schema or be accessible through\nthe Prisma schema configuration." } }, required: [ "name", "targetModel" ], description: "Interface representing a Prisma relation configuration between models.\n\nThis interface defines how foreign key fields establish relationships with\ntheir target models. It provides the necessary information for Prisma to\ngenerate appropriate relation directives (@relation) in the schema,\nenabling proper relational data modeling and ORM functionality.\n\nThe relation configuration is essential for:\n\n- Generating correct Prisma relation syntax\n- Establishing bidirectional relationships between models\n- Enabling proper type-safe querying through Prisma client\n- Supporting complex relationship patterns (1:1, 1:N, M:N)" }, "AutoBePrisma.IPlainField": { type: "object", properties: { name: { type: "string", pattern: "^[a-z][a-z0-9_]*$", description: "Name of the field in the database table.\n\nMUST use snake_case naming convention. Common patterns from uploaded\nschemas:\n\n- Timestamps: created_at, updated_at, deleted_at, opened_at, closed_at\n- Identifiers: code, name, nickname, title\n- Business data: value, quantity, price, volume, balance\n- Flags: primary, required, exclusive, secret, multiplicative" }, type: { oneOf: [ { "const": "string" }, { "const": "boolean" }, { "const": "uuid" }, { "const": "uri" }, { "const": "int" }, { "const": "double" }, { "const": "datetime" } ], description: "Data type of the field for Prisma schema generation.\n\nMaps to appropriate Prisma/PostgreSQL types:\n\n- Boolean: Boolean flags and yes/no values\n- Int: Integer numbers, quantities, sequences\n- Double: Decimal numbers, prices, monetary values, percentages\n- String: Text data, names, descriptions, codes\n- Uri: URL/URI fields for links and references\n- Uuid: UUID fields (for non-foreign-key UUIDs)\n- Datetime: Timestamp fields with date and time" }, description: { type: "string", description: "Description explaining the business purpose and usage of this field.\n\nShould clearly explain:\n\n- What business concept this field represents\n- Valid values or constraints if applicable\n- How it relates to business processes\n- Any special behavioral notes\n\n**IMPORTANT**: Description must be written in English. Example: \"Amount\nof cash payment.\" or \"Whether the unit is required or not.\"" }, nullable: { type: "boolean", description: "Whether this field can contain null values.\n\nTrue: Field is optional and can be null (e.g., middle name, description)\nfalse: Field is required and cannot be null (e.g., creation timestamp,\nname) Reflects business rules about mandatory vs optional data." } }, required: [ "name", "type", "description", "nullable" ], description: "Interface representing a regular data field that stores business\ninformation.\n\nThese fields contain the actual business data like names, amounts,\ntimestamps, flags, descriptions, and other domain-specific information." }, "AutoBePrisma.IUniqueIndex": { type: "object", properties: { fieldNames: { type: "array", items: { type: "string" }, minItems: 1, uniqueItems: true, description: "Array of field names that together form the unique constraint.\n\nCan be single field (e.g., [\"email\"]) or composite (e.g., [\"channel_id\",\n\"code\"]). All field names must exist in the model. Order matters for\ncomposite indexes. Examples: [\"code\"], [\"shopping_channel_id\",\n\"nickname\"], [\"email\"]" }, unique: { "const": true, description: "Explicit marker indicating this is a unique index.\n\nAlways true to distinguish from regular indexes. Used by code generator\nto emit \"@@unique\" directive in Prisma schema instead of \"@@index\"." } }, required: [ "fieldNames", "unique" ], description: "Interface representing a unique index constraint on one or more fields.\n\nUnique indexes enforce data integrity by ensuring no duplicate values exist\nfor the specified field combination. Essential for business rules that\nrequire uniqueness like email addresses, codes, or composite keys." }, "AutoBePrisma.IPlainIndex": { type: "object", properties: { fieldNames: { type: "array", items: { type: "string" }, minItems: 1, uniqueItems: true, description: "Array of field names to include in the performance index.\n\nCan be single field (e.g., [\"created_at\"]) or composite (e.g.,\n[\"customer_id\", \"created_at\"]). All field names must exist in the model.\nOrder matters for composite indexes and should match common query\npatterns. Examples: [\"created_at\"], [\"shopping_customer_id\",\n\"created_at\"], [\"ip\"]" } }, required: [ "fieldNames" ], description: "Interface representing a regular (non-unique) index for query performance.\n\nRegular indexes speed up database queries by creating optimized data\nstructures for common search patterns. Essential for foreign keys, date\nranges, and frequently filtered fields." }, "AutoBePrisma.IGinIndex": { type: "object", properties: { fieldName: { type: "string", description: "Name of the text field to index for full-text search capabilities.\n\nMust be a string field in the model that contains searchable text.\nExamples from uploaded schemas: \"nickname\", \"title\", \"body\", \"name\" Used\nwith PostgreSQL gin_trgm_ops for trigram-based fuzzy text search." } }, required: [ "fieldName" ], description: "Interface representing a GIN (Generalized Inverted Index) for full-text\nsearch.\n\nGIN indexes enable advanced PostgreSQL text search capabilities including\nfuzzy matching and partial text search using trigram operations. Essential\nfor user-facing search features on text content." } } }, functions: [ { name: "process", async: false, parameters: [ { name: "props", description: " Request containing either preliminary data request or complete\ntask", required: true, schema: { $ref: "#/components/schemas/IAutoBePrismaCorrectApplication.IProps" } } ], description: "Process schema correction task or preliminary data requests.\n\nFixes validation errors in specific Prisma models while preserving all\nbusiness logic and model descriptions. Returns ONLY corrected models." } ] }, source: SOURCE, kinds: ["analysisFiles", "prismaSchemas"], state: ctx.state(), all: { prismaSchemas: failure.data.files.map((f) => f.models).flat(), }, local: { prismaSchemas: Array.from(new Set(failure.errors.map((e) => e.table).filter((t) => t !== null))) .map((table) => failure.data.files .map((f) => f.models) .flat() .find((m) => m.name === table)) .filter((m) => m !== undefined), }, }); return yield preliminary.orchestrate(ctx, (out) => __awaiter(this, void 0, void 0, function* () { var _a, _b; const pointer = { value: null, }; const result = yield ctx.conversate(Object.assign({ source: SOURCE, controller: createController({ preliminary, model: ctx.model, build: (next) => { pointer.value = next; }, }), enforceFunctionCall: true }, (0, transformPrismaCorrectHistory_1.transformPrismaCorrectHistory)({ preliminary, result: failure, }))); if (pointer.value !== null) { const correction = { files: failure.data.files.map((file) => ({ filename: file.filename, namespace: file.namespace, models: file.models.map((model) => { var _a; const newbie = (_a = pointer.value) === null || _a === void 0 ? void 0 : _a.models.find((m) => m.name === model.name); return newbie !== null && newbie !== void 0 ? newbie : model; }), })), }; ctx.dispatch({ type: SOURCE, id: (0, uuid_1.v7)(), failure, planning: pointer.value.planning, correction: correction, metric: result.metric, tokenUsage: result.tokenUsage, step: (_b = (_a = ctx.state().analyze) === null || _a === void 0 ? void 0 : _a.step) !== null && _b !== void 0 ? _b : 0, created_at: new Date().toISOString(), }); return out(result)(Object.assign(Object.assign({}, pointer.value), { correction })); } return out(result)(null); })); }); } const getTableCount = (failure) => { const unique = new Set(failure.errors.map((error) => { var _a; return (_a = error.table) !== null && _a !== void 0 ? _a : null; })); return unique.size; }; function createController(props) { (0, assertSchemaModel_1.assertSchemaModel)(props.model); const validate = (input) => { const result = (() => { const _io0 = input => "string" === typeof input.thinking && ("object" === typeof input.request && null !== input.request && _iu0(input.request)); const _io1 = input => "getAnalysisFiles" === input.type && (Array.isArray(input.fileNames) && (1 <= input.fileNames.length && input.fileNames.every(elem => "string" === typeof elem))); const _io2 = input => "getPrismaSchemas" === input.type && (Array.isArray(input.schemaNames) && (1 <= input.schemaNames.length && input.schemaNames.every(elem => "string" === typeof elem))); const _io3 = input => "complete" === input.type && "string" === typeof input.planning && (Array.isArray(input.models) && input.models.every(elem => "object" === typeof elem && null !== elem && _io4(elem))); const _io4 = input => "string" === typeof input.name && RegExp("^[a-z][a-z0-9_]*$").test(input.name) && "string" === typeof input.description && "boolean" === typeof input.material && ("primary" === input.stance || "subsidiary" === input.stance || "snapshot" === input.stance) && ("object" === typeof input.primaryField && null !== input.primaryField && _io5(input.primaryField)) && (Array.isArray(input.foreignFields) && input.foreignFields.every(elem => "object" === typeof elem && null !== elem && _io6(elem))) && (Array.isArray(input.plainFields) && input.plainFields.every(elem => "object" === typeof elem && null !== elem && _io8(elem))) && (Array.isArray(input.uniqueIndexes) && input.uniqueIndexes.every(elem => "object" === t