Schema Reference
Complete reference for all data schemas used in Orchestre. These schemas define the structure and validation rules for data throughout the system.
Overview
Orchestre uses Zod for runtime type validation. All schemas are defined in src/schemas/.
Core Schemas
Project Schema
Defines project configuration and metadata.
typescript
import { z } from "zod";
export const ProjectConfigSchema = z.object({
name: z.string().min(1).max(100),
template: z.enum(["makerkit-nextjs", "cloudflare-hono", "react-native-expo"]),
version: z.string().regex(/^\d+\.\d+\.\d+$/),
description: z.string().optional(),
created: z.string().datetime(),
settings: z.object({
parallelAgents: z.number().min(1).max(10).default(3),
autoReview: z.boolean().default(true),
knowledgeBase: z.boolean().default(true)
}).optional()
});
export type ProjectConfig = z.infer<typeof ProjectConfigSchema>;Analysis Schemas
Used by the analyze_project tool.
typescript
export const AnalysisRequestSchema = z.object({
requirements: z.string().min(10).max(5000),
context: z.object({
existingProject: z.boolean().default(false),
projectType: z.string().optional(),
constraints: z.array(z.string()).optional()
}).optional()
});
export const AnalysisResultSchema = z.object({
complexity: z.enum(["simple", "moderate", "complex", "very-complex"]),
estimatedHours: z.number().min(1).max(1000),
technologies: z.array(z.object({
name: z.string(),
purpose: z.string(),
required: z.boolean()
})),
risks: z.array(z.object({
type: z.string(),
description: z.string(),
mitigation: z.string(),
severity: z.enum(["low", "medium", "high"])
})),
recommendations: z.array(z.string()),
breakdown: z.object({
phases: z.array(z.object({
name: z.string(),
description: z.string(),
deliverables: z.array(z.string()),
dependencies: z.array(z.string()).optional()
}))
})
});Plan Schemas
Used by the generate_plan tool.
typescript
export const PlanRequestSchema = z.object({
analysis: AnalysisResultSchema,
preferences: z.object({
approach: z.enum(["iterative", "waterfall", "agile"]).optional(),
priority: z.enum(["speed", "quality", "learning"]).optional(),
teamSize: z.number().min(1).max(20).optional()
}).optional()
});
export const TaskSchema = z.object({
id: z.string(),
title: z.string(),
description: z.string(),
type: z.enum(["setup", "feature", "bugfix", "refactor", "test", "docs"]),
priority: z.enum(["critical", "high", "medium", "low"]),
estimatedHours: z.number(),
dependencies: z.array(z.string()).optional(),
assignee: z.string().optional(),
status: z.enum(["pending", "in-progress", "blocked", "completed"]).default("pending")
});
export const PhaseSchema = z.object({
id: z.string(),
name: z.string(),
description: z.string(),
tasks: z.array(TaskSchema),
milestone: z.string(),
duration: z.object({
min: z.number(),
max: z.number(),
unit: z.enum(["hours", "days", "weeks"])
})
});
export const PlanResultSchema = z.object({
title: z.string(),
overview: z.string(),
phases: z.array(PhaseSchema),
timeline: z.object({
start: z.string().datetime().optional(),
end: z.string().datetime().optional(),
totalHours: z.number()
}),
resources: z.array(z.object({
type: z.string(),
description: z.string(),
required: z.boolean()
})).optional()
});Review Schemas
Used by the multi_llm_review tool.
typescript
export const ReviewRequestSchema = z.object({
scope: z.enum(["full", "security", "performance", "architecture", "specific"]).default("full"),
focus: z.string().optional(),
compare: z.string().optional(),
files: z.array(z.string()).optional()
});
export const ReviewFindingSchema = z.object({
type: z.enum(["security", "performance", "bug", "style", "architecture", "best-practice"]),
severity: z.enum(["critical", "high", "medium", "low", "info"]),
file: z.string().optional(),
line: z.number().optional(),
description: z.string(),
suggestion: z.string(),
example: z.string().optional()
});
export const ReviewResultSchema = z.object({
summary: z.object({
score: z.number().min(0).max(100),
strengths: z.array(z.string()),
improvements: z.array(z.string())
}),
findings: z.array(ReviewFindingSchema),
consensus: z.object({
agreed: z.array(z.string()),
disputed: z.array(z.object({
issue: z.string(),
perspectives: z.record(z.string())
}))
}),
recommendations: z.array(z.object({
priority: z.enum(["immediate", "short-term", "long-term"]),
action: z.string(),
impact: z.string()
}))
});Template Schemas
Template Configuration
typescript
export const TemplateConfigSchema = z.object({
name: z.string(),
displayName: z.string(),
description: z.string(),
version: z.string(),
author: z.string().optional(),
repository: z.string().url().optional(),
keywords: z.array(z.string()),
requirements: z.object({
node: z.string(),
orchestreVersion: z.string()
}),
setupCommands: z.array(z.string()),
structure: z.object({
sourceDir: z.string(),
commandsDir: z.string(),
patternsDir: z.string().optional()
}),
features: z.array(z.string()),
variants: z.record(z.object({
prompt: z.string(),
options: z.array(z.string()),
affects: z.array(z.string())
})).optional()
});Command Schema
typescript
export const CommandDefinitionSchema = z.object({
name: z.string().regex(/^[a-z-]+$/),
description: z.string(),
category: z.enum(["core", "template", "utility", "advanced"]),
availability: z.object({
templates: z.array(z.string()).optional(),
condition: z.string().optional()
}).optional(),
parameters: z.array(z.object({
name: z.string(),
type: z.enum(["string", "number", "boolean", "array", "object"]),
description: z.string(),
required: z.boolean().default(false),
default: z.any().optional(),
enum: z.array(z.any()).optional()
})).optional(),
examples: z.array(z.object({
description: z.string(),
command: z.string(),
result: z.string().optional()
}))
});State Schemas
Memory Document Schema
typescript
export const MemoryDocumentSchema = z.object({
title: z.string(),
type: z.enum(["project", "feature", "decision", "pattern", "learning"]),
created: z.string().datetime(),
updated: z.string().datetime(),
content: z.object({
overview: z.string().optional(),
context: z.string().optional(),
decisions: z.array(z.object({
title: z.string(),
rationale: z.string(),
alternatives: z.array(z.string()).optional(),
date: z.string().datetime()
})).optional(),
patterns: z.array(z.object({
name: z.string(),
description: z.string(),
usage: z.string(),
example: z.string().optional()
})).optional(),
learnings: z.array(z.object({
insight: z.string(),
context: z.string(),
application: z.string()
})).optional()
}),
metadata: z.record(z.any()).optional()
});Pattern Schema
typescript
export const PatternSchema = z.object({
id: z.string(),
name: z.string(),
category: z.enum(["architecture", "code", "testing", "deployment", "security"]),
description: z.string(),
problem: z.string(),
solution: z.string(),
example: z.object({
before: z.string().optional(),
after: z.string()
}),
benefits: z.array(z.string()),
tradeoffs: z.array(z.string()).optional(),
related: z.array(z.string()).optional(),
tags: z.array(z.string())
});API Schemas
Tool Response Schema
typescript
export const ToolResponseSchema = z.object({
content: z.array(z.object({
type: z.literal("text"),
text: z.string()
})).min(1),
isError: z.boolean().optional()
});Error Schema
typescript
export const ErrorResponseSchema = z.object({
error: z.string(),
code: z.string().optional(),
details: z.any().optional(),
suggestion: z.string().optional(),
documentation: z.string().url().optional()
});Validation Helpers
Using Schemas
typescript
import { ProjectConfigSchema } from "@/schemas";
// Validate data
try {
const config = ProjectConfigSchema.parse(data);
// config is fully typed
} catch (error) {
if (error instanceof z.ZodError) {
console.error("Validation errors:", error.errors);
}
}
// Safe parsing
const result = ProjectConfigSchema.safeParse(data);
if (result.success) {
// Use result.data
} else {
// Handle result.error
}Custom Validators
typescript
// Email validation
export const EmailSchema = z.string().email().toLowerCase();
// URL validation with specific domains
export const GitHubUrlSchema = z.string().url().refine(
(url) => url.includes("github.com"),
"Must be a GitHub URL"
);
// File path validation
export const FilePathSchema = z.string().refine(
(path) => !path.includes(".."),
"Path traversal not allowed"
);
// Semantic version
export const SemVerSchema = z.string().regex(
/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/,
"Invalid semantic version"
);Composition Patterns
typescript
// Base schemas
const BaseEntitySchema = z.object({
id: z.string().uuid(),
createdAt: z.string().datetime(),
updatedAt: z.string().datetime()
});
// Extend schemas
export const UserSchema = BaseEntitySchema.extend({
email: EmailSchema,
name: z.string().min(1).max(100),
role: z.enum(["admin", "user", "guest"])
});
// Partial schemas
export const UserUpdateSchema = UserSchema.partial().omit({
id: true,
createdAt: true
});
// Union schemas
export const NotificationSchema = z.union([
z.object({
type: z.literal("email"),
to: EmailSchema,
subject: z.string(),
body: z.string()
}),
z.object({
type: z.literal("sms"),
to: z.string().regex(/^\+?[1-9]\d{1,14}$/),
message: z.string().max(160)
})
]);Schema Generation
From TypeScript Types
typescript
// Generate schema from type
import { z } from "zod";
import { zodToTs } from "zod-to-ts";
const schema = z.object({
name: z.string(),
age: z.number()
});
// Get TypeScript type
const { node } = zodToTs(schema);Dynamic Schemas
typescript
// Schema factory
function createEntitySchema<T extends z.ZodRawShape>(
name: string,
shape: T
) {
return z.object({
_type: z.literal(name),
...BaseEntitySchema.shape,
...shape
});
}
// Usage
const ProductSchema = createEntitySchema("product", {
name: z.string(),
price: z.number().positive(),
inStock: z.boolean()
});Best Practices
1. Reusable Schemas
typescript
// Common schemas in separate file
export const common = {
id: z.string().uuid(),
email: z.string().email(),
url: z.string().url(),
datetime: z.string().datetime(),
positiveInt: z.number().int().positive()
};
// Use in other schemas
const UserSchema = z.object({
id: common.id,
email: common.email,
website: common.url.optional()
});2. Error Messages
typescript
export const PasswordSchema = z.string()
.min(12, "Password must be at least 12 characters")
.regex(/[A-Z]/, "Password must contain uppercase letter")
.regex(/[a-z]/, "Password must contain lowercase letter")
.regex(/[0-9]/, "Password must contain number")
.regex(/[^A-Za-z0-9]/, "Password must contain special character");3. Transform and Refine
typescript
// Transform data
export const DateSchema = z.string().transform((str) => new Date(str));
// Refine with custom logic
export const FutureDateSchema = DateSchema.refine(
(date) => date > new Date(),
"Date must be in the future"
);
// Complex refinement
export const TimeRangeSchema = z.object({
start: z.string(),
end: z.string()
}).refine(
(data) => new Date(data.start) < new Date(data.end),
"End time must be after start time"
);Testing Schemas
typescript
import { describe, it, expect } from "vitest";
describe("ProjectConfigSchema", () => {
it("should validate correct config", () => {
const valid = {
name: "my-project",
template: "cloudflare-hono",
version: "1.0.0",
created: new Date().toISOString()
};
expect(() => ProjectConfigSchema.parse(valid)).not.toThrow();
});
it("should reject invalid template", () => {
const invalid = {
name: "my-project",
template: "invalid-template",
version: "1.0.0",
created: new Date().toISOString()
};
const result = ProjectConfigSchema.safeParse(invalid);
expect(result.success).toBe(false);
expect(result.error?.issues[0].path).toEqual(["template"]);
});
});