Public
Like
glimpse2-runbook-view-glimpse-save-login-react
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Viewing readonly version of main branch: v27View latest version
The backend follows a clean architecture with proper separation of concerns across multiple layers.
The backend is organized into distinct layers, each with specific responsibilities:
- Controllers: Business logic, workflow orchestration, HTTP handling
- Services: External integrations and data persistence operations
- Routes: HTTP routing, middleware application, parameter extraction
- Utils: Pure utility functions with no external dependencies
Request → Routes (middleware + routing) → Controllers (business logic + orchestration) → Services (external operations) + Utils (pure functions) → Response
- Controllers orchestrate services and use utilities to implement business workflows
- Services handle external system interactions (APIs, databases, storage)
- Utils provide pure, reusable functions with no side effects
- Routes focus purely on HTTP concerns and middleware
// Controller orchestrates services and uses utils
const pageData = await getPageById(pageId); // SERVICE call
const cleanedData = formatAgentProperties(pageData); // UTIL function
await setAgentBlob(pageId, cleanedData); // SERVICE call
- Services: "I need to talk to Notion API" →
notion/page.service.ts
- Utils: "I need to format this date" →
utils/date.helpers.ts
- Services: "I need to store this in blob storage" →
blob.service.ts
- Utils: "I need to validate this email format" →
utils/validation.helpers.ts
backend/
├── controllers/ # Business logic and workflow orchestration
├── routes/ # HTTP routing and middleware
├── services/ # External integrations (APIs, storage)
├── utils/ # Pure utility functions
├── types/ # TypeScript type definitions
└── crons/ # Scheduled tasks
All controller functions return a consistent structure:
{
success: boolean,
data: any | null,
error: string | null,
details?: string // Additional error context
}
Routes then format these into appropriate HTTP responses.