@autobe/agent
Version:
AI backend server code generator
73 lines • 3.25 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateScenarioBasics = void 0;
/**
* Validate scenario output for structural soundness before LLM review.
*
* Checks minimum entity count, actor completeness, relationship integrity, and
* cross-reference consistency. Zero token cost — purely programmatic.
*/
const validateScenarioBasics = (props) => {
var _a;
const errors = [];
// 1. Prefix non-empty
if (!props.prefix || props.prefix.trim().length === 0)
errors.push("Project prefix is empty.");
// 2. Minimum entity count (User + at least 1 domain entity)
if (props.entities.length < 2)
errors.push(`Entity count is ${props.entities.length}, below minimum (2). Most domains require at least User + 1 domain entity.`);
// 3. Actor basics: guest and member must exist
if (!props.actors.some((a) => a.kind === "guest"))
errors.push("Missing guest actor. Public endpoints (registration, login) require a guest actor.");
if (!props.actors.some((a) => a.kind === "member"))
errors.push("Missing member actor. Authenticated features require a member actor.");
// 4. Each entity must have at least 2 attributes
for (const entity of props.entities) {
if (entity.attributes.length < 2)
errors.push(`Entity "${entity.name}" has ${entity.attributes.length} attribute(s), below minimum (2).`);
}
// 5. Each entity should have at least 1 relationship
for (const entity of props.entities) {
if (!entity.relationships || entity.relationships.length === 0)
errors.push(`Entity "${entity.name}" has no relationships. Every entity should relate to at least one other entity.`);
}
// 6. Cross-reference: relationship targets must exist in entities list
const entityNames = new Set(props.entities.map((e) => e.name.toLowerCase()));
for (const entity of props.entities) {
for (const rel of (_a = entity.relationships) !== null && _a !== void 0 ? _a : []) {
const refNames = extractRelationshipTargets(rel);
for (const refName of refNames) {
if (!entityNames.has(refName.toLowerCase()))
errors.push(`Entity "${entity.name}" references "${refName}" in relationship "${rel}" but "${refName}" is not in the entities list.`);
}
}
}
return { valid: errors.length === 0, errors };
};
exports.validateScenarioBasics = validateScenarioBasics;
/**
* Extract entity names referenced in a relationship string.
*
* Handles patterns like:
*
* - "belongsTo User via userId"
* - "hasMany Todo"
* - "manyToMany Tag through TodoTag"
*/
const extractRelationshipTargets = (rel) => {
const targets = [];
const patterns = [
/(?:belongsTo|hasMany|hasOne|manyToMany)\s+(\w+)/gi,
/(?:through|via)\s+(\w+)/gi,
];
for (const pattern of patterns) {
for (const match of rel.matchAll(pattern)) {
const name = match[1];
if (name && PASCAL_CASE_PATTERN.test(name))
targets.push(name);
}
}
return targets;
};
const PASCAL_CASE_PATTERN = /^[A-Z][a-zA-Z0-9]*$/;
//# sourceMappingURL=validateScenarioBasics.js.map