Add 5 comprehensive tests for CorsSettings in TDD red phase: - cors_settings_deserialize_from_yaml: YAML deserialization - cors_settings_default_has_empty_origins: Default values - cors_settings_with_wildcard_deserializes: Wildcard origin handling - settings_loads_cors_section_from_yaml: Settings integration - cors_settings_deserialize_with_defaults: Partial deserialization Tests are intentionally failing (red phase) as CorsSettings struct will be implemented in T010. Follows TDD requirement to write tests before implementation. Ref: T009 (specs/001-modbus-relay-control/tasks.md)
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 2 In Progress - 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 (94 tasks across 8 phases).
Architecture
Current:
- Backend: Rust 2024 with Poem web framework
- Configuration: YAML-based with environment variable overrides
- API: RESTful HTTP with OpenAPI documentation
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
API Documentation
The server provides OpenAPI documentation via Swagger UI:
- Swagger UI:
http://localhost:8080/ - OpenAPI Spec:
http://localhost:8080/openapi.json
Current Endpoints:
GET /api/health- Health check endpointGET /api/meta- Application metadata
Planned Endpoints (see spec):
GET /api/relays- List all relay statesPOST /api/relays/{id}/toggle- Toggle relay statePOST /api/relays/all/on- Turn all relays onPOST /api/relays/all/off- Turn all relays offPUT /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 (Phase 2 in progress)
│ │ │ └── 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
├── specs/ # Feature specifications and documentation
│ ├── constitution.md - Architectural principles
│ └── 001-modbus-relay-control/
│ ├── spec.md - Feature specification
│ ├── plan.md - Implementation plan
│ ├── tasks.md - Task breakdown (94 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)
Planned Dependencies:
- tokio-modbus 0.17 (Modbus TCP client)
- SQLx 0.8 (async SQLite database access)
- mockall 0.13 (mocking for tests)
Frontend (planned):
- Vue 3 + TypeScript
- Vite build tool
- Axios (HTTP client)
Documentation
- Project Constitution - Architectural principles and development guidelines
- Modbus Relay Control Spec - Feature specification
- CLAUDE.md - Developer guide and code style rules
License
This project is under the AGPL-3.0 license. You can find it in the LICENSE.md file.