A fully automated test generator that creates comprehensive Vitest test suites from entity definitions. This proves that everything can be generated from compilation with ZERO manual test writing.
const User = defineEntity('User', {
fields: {
email: text().required().email(),
name: text().required().min(2).max(100),
age: number().optional().min(0).max(150).integer(),
},
behaviors: {
timestamps: true,
softDelete: true,
},
protected: 'write', // list/get public, create/update/remove protected
})npx archetype generateGenerates generated/tests/user.test.ts with:
- Create: Valid data creates record with all fields
- List: Returns paginated results with proper structure
- Get: Returns single record by ID
- Update: Modifies existing record
- Remove: Deletes record (or soft deletes)
- Required fields: Rejects missing required fields
- Email validation:
email: 'invalid-email'→ throws error - Min/Max length:
name: 'x'→ throws (below min of 2) - Number constraints: Integer, positive, min/max validations
- Enum values: Rejects values outside allowed list
- Protected operations: Public caller → UNAUTHORIZED error
- Authenticated operations: Auth caller → succeeds
- Mixed protection: List public, create protected
- Filtering:
where: { email: { contains: 'test' } } - Search:
search: 'test'searches across text fields - Pagination:
page: 1, limit: 10with proper response
- createMany: Creates multiple records
- updateMany: Updates multiple records
- removeMany: Deletes multiple records
- Timestamps:
createdAt,updatedAtauto-generated - Soft delete:
deletedAtset instead of hard delete - Computed fields: Verified in responses
describe('User Router', () => {
const publicCaller = createCaller(mockPublicContext)
const authCaller = createCaller(mockAuthContext)
const validData = {
email: 'test-email@example.com',
name: 'Test User',
}
describe('create', () => {
it('should require authentication', async () => {
await expect(
publicCaller.user.create(validData)
).rejects.toThrow(/UNAUTHORIZED|unauthorized/)
})
it('should create User when authenticated', async () => {
const result = await authCaller.user.create(validData)
expect(result).toBeDefined()
expect(result.id).toBeDefined()
expect(result.email).toBe(validData.email)
expect(result.name).toBe(validData.name)
expect(result.createdAt).toBeDefined()
expect(result.updatedAt).toBeDefined()
})
it('should reject invalid email (invalid email format)', async () => {
const invalidData = { ...validData, email: 'invalid-email' }
await expect(
authCaller.user.create(invalidData)
).rejects.toThrow()
})
it('should reject invalid name (below minimum length of 2)', async () => {
const invalidData = { ...validData, name: 'x' }
await expect(
authCaller.user.create(invalidData)
).rejects.toThrow()
})
})
describe('batch operations', () => {
it('should create multiple Users', async () => {
const items = [validData, validData, validData]
const result = await authCaller.user.createMany({ items })
expect(result.created).toHaveLength(3)
expect(result.count).toBe(3)
})
})
})For 2 entities (User, Post):
generated/
├── tests/
│ ├── user.test.ts # 206 lines - comprehensive User tests
│ ├── post.test.ts # 228 lines - comprehensive Post tests
│ └── setup.ts # 26 lines - test configuration
Total: 434 lines of test code generated from ~40 lines of entity definitions.
- Write entity definition
- Write database schema
- Write API endpoints
- Write 200+ lines of tests manually
- Update all 4 when entity changes
- Write entity definition
- Run
npx archetype generate - Get tests automatically
- When entity changes → regenerate → TypeScript guides fixes
YES - EVERYTHING CAN BE GENERATED FROM COMPILATION!
- ✅ Database schemas
- ✅ API endpoints (tRPC routers)
- ✅ Validation (Zod)
- ✅ React hooks
- ✅ Tests (NEW!)
- 🔜 API documentation (OpenAPI)
- 🔜 Seed data
- 🔜 E2E tests
- 🔜 Admin UI
# Define your entity once
vim archetype/entities/user.ts
# Get EVERYTHING
npx archetype generate
# Run the auto-generated tests
npm testZero manual test writing. Zero maintenance burden.
When you add a field:
age: number().required().min(18) // NEW FIELDRegenerate:
npx archetype generateAutomatically adds:
- ✅ Database column
- ✅ Validation rule
- ✅ API field
- ✅ Test for missing age
- ✅ Test for age < 18
- ✅ Test for valid age
- OpenAPI Generator - Auto-generate API documentation
- Seed Generator - Sample data for development
- E2E Generator - Playwright/Cypress full-flow tests
- Admin UI Generator - Full CRUD dashboard
All following the same pattern: define entities once, generate everything.
"Write entities, not infrastructure"
Developers should focus on:
- Business logic (entity definitions)
- Custom behaviors (hooks)
- User experience
NOT:
- Boilerplate tests
- Repetitive CRUD code
- Manual synchronization
Archetype handles the rest. Automatically. Deterministically. Perfectly synced.