Lucien Cartier-Tilet 5d6c3208cc feat(cors): implement CORS configuration with From trait
Implement From<CorsSettings> for Cors trait to configure CORS middleware
with production-ready security validation.

- Move CorsSettings to backend/src/settings/cors.rs module
- Validate wildcard + credentials constraint (browser security policy)
- Configure allowed methods, headers, credentials, and max_age
- Add structured logging for CORS configuration
- Move tests from settings/mod.rs and startup.rs to cors module

Ref: T014
2026-01-22 00:57:11 +01:00
2026-01-11 00:39:18 +01:00
2026-01-11 00:39:18 +01:00
2026-01-11 00:39:18 +01:00
2026-01-11 00:39:18 +01:00

STA - Smart Temperature & Appliance Control

🤖 AI-Assisted Development Notice: This project uses Claude Code as a development assistant for task planning, code organization, and workflow management. However, all code is human-written, reviewed, and validated by the project maintainer. AI is used as a productivity tool, not as the author of the implementation.

Web-based Modbus relay control system for managing 8-channel relay modules over TCP.

⚠️ Development Status: This project is in early development. Core features are currently being implemented following a specification-driven approach.

Overview

STA will provide a modern web interface for controlling Modbus-compatible relay devices, eliminating the need for specialized industrial software. The goal is to enable browser-based relay control with real-time status updates.

Current Status

Phase 1 Complete - Foundation:

  • Monorepo structure (backend + frontend at root)
  • Rust web server with Poem 3.1 framework
  • Configuration system (YAML + environment variables)
  • Modbus TCP and relay settings structures
  • Health check and metadata API endpoints
  • OpenAPI documentation with Swagger UI
  • Rate limiting middleware
  • CORS middleware (configurable for production)
  • SQLite schema and repository for relay labels
  • Vue 3 + TypeScript frontend scaffolding with Vite
  • Type-safe API client generation from OpenAPI specs

Phase 0.5 In Progress - CORS Configuration:

  • T009: CorsSettings tests written (TDD)
  • T010: CorsSettings struct implemented with fail-safe defaults
  • 🚧 T011-T016: YAML configuration and middleware integration

Phase 2 Planned - Domain Layer:

  • 📋 Domain types with Type-Driven Development (RelayId, RelayState, RelayLabel)
  • 📋 100% test coverage for domain layer

Planned - Phases 3-8:

  • 📋 Modbus TCP client with tokio-modbus (Phase 3)
  • 📋 Mock controller for testing (Phase 3)
  • 📋 Health monitoring service (Phase 3)
  • 📋 US1: Monitor & toggle relay states - MVP (Phase 4)
  • 📋 US2: Bulk relay controls (Phase 5)
  • 📋 US3: Health status display (Phase 6)
  • 📋 US4: Relay labeling (Phase 7)
  • 📋 Production deployment (Phase 8)

See tasks.md for detailed implementation roadmap (102 tasks across 9 phases).

Architecture

Current:

  • Backend: Rust 2024 with Poem web framework
  • Configuration: YAML-based with environment variable overrides
  • API: RESTful HTTP with OpenAPI documentation
  • CORS: Configurable middleware for production security

Planned:

  • Modbus Integration: tokio-modbus for Modbus TCP communication
  • Frontend: Vue 3 with TypeScript
  • Deployment: Backend on Raspberry Pi, frontend on Cloudflare Pages
  • Access: Traefik reverse proxy with Authelia authentication
  • Persistence: SQLite for relay labels and configuration

Quick Start

Prerequisites

  • Rust 1.83+ (edition 2024)
  • Just command runner

Development

# Run development server
just run

# Run tests
just test

# Run linter
just lint

# Format code
just format

# Watch mode with bacon
bacon          # clippy-all (default)
bacon test     # test watcher

Configuration

Edit settings/base.yaml for Modbus device settings:

modbus:
  host: "192.168.0.200"
  port: 502
  slave_id: 0
  timeout_secs: 5

relay:
  label_max_length: 50

Override with environment variables:

APP__MODBUS__HOST=192.168.1.100 cargo run

CORS Configuration

For development with frontend on localhost:5173:

# backend/settings/development.yaml
cors:
  allowed_origins:
    - "*"
  allow_credentials: false
  max_age_secs: 3600

For production with frontend on Cloudflare Pages:

# backend/settings/production.yaml
cors:
  allowed_origins:
    - "https://sta.example.com"
  allow_credentials: true  # Required for Authelia authentication
  max_age_secs: 3600

See CORS Configuration Guide for complete documentation.

API Documentation

The server provides OpenAPI documentation via Swagger UI:

  • Swagger UI: http://localhost:3100/
  • OpenAPI Spec: http://localhost:3100/openapi.json

Current Endpoints:

  • GET /api/health - Health check endpoint
  • GET /api/meta - Application metadata

Planned Endpoints (see spec):

  • GET /api/relays - List all relay states
  • POST /api/relays/{id}/toggle - Toggle relay state
  • POST /api/relays/all/on - Turn all relays on
  • POST /api/relays/all/off - Turn all relays off
  • PUT /api/relays/{id}/label - Set relay label

Project Structure

Monorepo Layout:

sta/                          # Repository root
├── backend/                  # Rust backend workspace member
│   ├── src/
│   │   ├── lib.rs           - Library entry point
│   │   ├── main.rs          - Binary entry point
│   │   ├── startup.rs       - Application builder and server config
│   │   ├── settings.rs      - Configuration management
│   │   ├── telemetry.rs     - Logging and tracing setup
│   │   ├── domain/          - Business logic (planned Phase 2)
│   │   │   └── relay/       - Relay domain types and repository traits
│   │   ├── application/     - Use cases (planned Phase 3-4)
│   │   ├── infrastructure/  - External integrations (Phase 3)
│   │   │   └── persistence/ - SQLite repository implementation
│   │   ├── presentation/    - API layer (planned Phase 4)
│   │   ├── route/           - HTTP endpoint handlers
│   │   │   ├── health.rs    - Health check endpoints
│   │   │   └── meta.rs      - Application metadata
│   │   └── middleware/      - Custom middleware
│   │       └── rate_limit.rs
│   ├── settings/            - YAML configuration files
│   └── tests/               - Integration tests
├── src/                     # Frontend source (Vue/TypeScript)
│   └── api/                 - Type-safe API client
├── docs/                    # Project documentation
│   ├── cors-configuration.md    - CORS setup guide
│   └── Modbus_POE_ETH_Relay.md - Hardware documentation
├── specs/                   # Feature specifications
│   ├── constitution.md      - Architectural principles
│   └── 001-modbus-relay-control/
│       ├── spec.md          - Feature specification
│       ├── plan.md          - Implementation plan
│       ├── tasks.md         - Task breakdown (102 tasks)
│       └── research-cors.md - CORS configuration research
├── package.json             - Frontend dependencies
├── vite.config.ts          - Vite build configuration
└── justfile                 - Build commands

Technology Stack

Currently Used:

  • Rust 2024 edition
  • Poem 3.1 (web framework with OpenAPI support)
  • Tokio 1.48 (async runtime)
  • config (YAML configuration)
  • tracing + tracing-subscriber (structured logging)
  • governor (rate limiting)
  • thiserror (error handling)
  • serde + serde_yaml (configuration deserialization)

Planned Dependencies:

  • tokio-modbus 0.17 (Modbus TCP client)
  • SQLx 0.8 (async SQLite database access)
  • mockall 0.13 (mocking for tests)

Frontend (scaffolding complete):

  • Vue 3 + TypeScript
  • Vite build tool
  • openapi-typescript (type-safe API client generation)

Documentation

Configuration Guides

Development Guides

License

This project is under the AGPL-3.0 license. You can find it in the LICENSE.md file.

Description
Smart Temperature & Appliance control
Readme 1.1 MiB
Languages
Rust 95.4%
TypeScript 1.6%
Nix 1.4%
Vue 0.6%
CSS 0.5%
Other 0.5%