Skip to content

Architecture Guide

This guide covers the Web.Casa codebase structure and the conventions for adding new features.

webcasa/
├── main.go # Application entry point
├── VERSION # Version number (single source of truth)
├── internal/
│ ├── config/ # Environment config loading
│ ├── model/ # Database models and DTOs
│ ├── database/ # SQLite initialization and migrations
│ ├── auth/ # JWT authentication and middleware
│ ├── caddy/ # Caddy process management + Caddyfile rendering
│ ├── service/ # Business logic layer
│ ├── handler/ # HTTP request handlers
│ └── notify/ # Notification system (Webhook, Email, Discord, Telegram)
├── plugins/ # Feature plugins (12 built-in)
└── web/ # React 19 frontend
└── src/
└── pages/ # Page components

This is the primary architectural convention. All backend features follow a three-layer pattern:

LayerLocationResponsibility
Handlerinternal/handler/Parse HTTP requests, validate input, call service functions, format JSON responses
Serviceinternal/service/Business logic, database queries, external system interactions (Docker API, Caddy admin API, filesystem)
Modelinternal/model/Struct definitions, GORM model tags, database migration functions

This separation keeps business logic testable independently of HTTP concerns.

Data flow:

HTTP Request → Handler (parse + validate) → Service (logic) → Model (data) → Database
↓
HTTP Response ← Handler (format JSON) ← Service (result) ← Model (query) ← SQLite

Follow these steps to add a new feature to the backend:

  1. Define the data model in internal/model/

    • Create struct with GORM tags
    • Add auto-migration in the database initialization
  2. Implement the service layer in internal/service/

    • Write business logic functions
    • Handle database operations through GORM
    • Interact with external systems if needed
  3. Create HTTP handlers in internal/handler/

    • Parse request parameters and body
    • Call service functions
    • Return standardized JSON responses
  4. Register routes in the handler’s RegisterRoutes() function

    • Use appropriate HTTP methods
    • Apply authentication and RBAC middleware

Routes use the Gin router and follow REST conventions:

MethodPatternAction
GET/api/resourcesList all
GET/api/resources/:idGet one
POST/api/resourcesCreate
PUT/api/resources/:idUpdate
DELETE/api/resources/:idDelete

All responses use a standardized JSON envelope:

{
"code": 0,
"message": "success",
"data": { }
}

Web.Casa uses GORM with SQLite (WAL mode):

  • Models use GORM struct tags for column definitions
  • Auto-migration handles schema updates
  • Use GORM’s query builder for database operations
  • Database file location: /var/lib/webcasa/webcasa.db

Plugins live under plugins/ (at the project root). Each plugin implements the Plugin interface:

  • Metadata() — return plugin metadata (name, version, description, dependencies)
  • Init() — register routes, event handlers, and database tables through the plugin Context
  • Start() — start background tasks
  • Stop() — clean up resources

See Plugin System and Developing Plugins for details.

The React frontend under web/src/ follows these patterns:

  • Feature-based directories — each feature has its own directory with pages, components, hooks, and API client functions
  • State management — Zustand for global state, React hooks for local state
  • UI components — Radix UI Themes 3 for consistent design
  • Styling — Tailwind CSS v4 utility classes
  • Routing — client-side routing with route definitions in the router configuration
  • Navigation — sidebar entries defined in the layout configuration