Add Speckit and Constitution
This commit is contained in:
149
.specify/memory/constitution.md
Normal file
149
.specify/memory/constitution.md
Normal file
@@ -0,0 +1,149 @@
|
||||
<!--
|
||||
Sync Impact Report
|
||||
==================
|
||||
Version change: (new) -> 1.0.0
|
||||
Modified principles: N/A (initial ratification)
|
||||
Added sections:
|
||||
- Core Principles (5 principles)
|
||||
- Technology Stack & Constraints
|
||||
- Development Workflow
|
||||
- Governance
|
||||
Removed sections: N/A
|
||||
Templates requiring updates:
|
||||
- .specify/templates/plan-template.md — ✅ no changes needed (Constitution Check section is generic)
|
||||
- .specify/templates/spec-template.md — ✅ no changes needed
|
||||
- .specify/templates/tasks-template.md — ✅ no changes needed
|
||||
- .specify/templates/checklist-template.md — ✅ no changes needed
|
||||
- .specify/templates/agent-file-template.md — ✅ no changes needed
|
||||
Follow-up TODOs: None
|
||||
-->
|
||||
|
||||
# ImageApi Constitution
|
||||
|
||||
## Core Principles
|
||||
|
||||
### I. Layered Architecture
|
||||
|
||||
All features MUST follow the established layered architecture:
|
||||
|
||||
- **HTTP Layer** (`main.rs`, feature modules): Route handlers, request
|
||||
parsing, response formatting. No direct database access.
|
||||
- **Service Layer** (`files.rs`, `exif.rs`, `memories.rs`, etc.): Business
|
||||
logic. No HTTP-specific types.
|
||||
- **DAO Layer** (`database/` trait definitions): Trait-based data access
|
||||
contracts. Every DAO MUST be defined as a trait to enable mock
|
||||
implementations for testing.
|
||||
- **Database Layer** (Diesel ORM, `schema.rs`): Concrete `Sqlite*Dao`
|
||||
implementations. All queries traced with OpenTelemetry.
|
||||
|
||||
New features MUST NOT bypass layers (e.g., HTTP handlers MUST NOT
|
||||
execute raw SQL). Actix actors are permitted for long-running async
|
||||
work (video processing, file watching) but MUST interact with the
|
||||
DAO layer through the established trait interfaces.
|
||||
|
||||
### II. Path Safety (NON-NEGOTIABLE)
|
||||
|
||||
All user-supplied file paths MUST be validated against `BASE_PATH`
|
||||
using `is_valid_full_path()` before any filesystem operation. This
|
||||
prevents directory traversal attacks.
|
||||
|
||||
- Paths stored in the database MUST be relative to `BASE_PATH`.
|
||||
- Paths passed to external tools (ffmpeg, image processing) MUST be
|
||||
fully resolved absolute paths.
|
||||
- Extension detection MUST use the centralized helpers in
|
||||
`file_types.rs` (case-insensitive). Manual string matching on
|
||||
extensions is prohibited.
|
||||
|
||||
### III. Trait-Based Testability
|
||||
|
||||
All data access MUST go through trait-based DAOs so that every
|
||||
handler and service can be tested with mock implementations.
|
||||
|
||||
- Each DAO trait MUST be defined in `src/database/` and require
|
||||
`Sync + Send`.
|
||||
- Mock DAOs for testing MUST live in `src/testhelpers.rs`.
|
||||
- Integration tests against real SQLite MUST use in-memory databases
|
||||
via `in_memory_db_connection()` from `database::test`.
|
||||
- Handler tests MUST use `actix_web::test` utilities with JWT token
|
||||
injection (using `Claims::valid_user()` and the `test_key` secret).
|
||||
- New DAO implementations MUST include a `#[cfg(test)]` constructor
|
||||
(e.g., `from_connection`) accepting an injected connection.
|
||||
|
||||
### IV. Environment-Driven Configuration
|
||||
|
||||
Server behavior MUST be controlled through environment variables
|
||||
loaded from `.env` files. Hard-coded paths, URLs, or secrets are
|
||||
prohibited.
|
||||
|
||||
- Required variables MUST call `.expect()` with a clear message at
|
||||
startup so misconfiguration fails fast.
|
||||
- Optional variables MUST use `.unwrap_or_else()` with sensible
|
||||
defaults and be documented in `README.md`.
|
||||
- Any new environment variable MUST be added to the README
|
||||
environment section before the feature is considered complete.
|
||||
|
||||
### V. Observability
|
||||
|
||||
All database operations and HTTP handlers MUST be instrumented
|
||||
with OpenTelemetry spans via the `trace_db_call` helper or
|
||||
equivalent tracing macros.
|
||||
|
||||
- Release builds export traces to the configured OTLP endpoint.
|
||||
- Debug builds use the basic logger.
|
||||
- Prometheus metrics (`imageserver_image_total`,
|
||||
`imageserver_video_total`) MUST be maintained for key counters.
|
||||
- Errors MUST be logged at `error!` level with sufficient context
|
||||
for debugging without reproducing the issue.
|
||||
|
||||
## Technology Stack & Constraints
|
||||
|
||||
- **Language**: Rust (stable toolchain, Cargo build system)
|
||||
- **HTTP Framework**: Actix-web 4
|
||||
- **ORM**: Diesel 2.2 with SQLite backend
|
||||
- **Auth**: JWT (HS256) via `jsonwebtoken` crate, bcrypt password
|
||||
hashing
|
||||
- **Video Processing**: ffmpeg/ffprobe (CLI, must be on PATH)
|
||||
- **Image Processing**: `image` crate for thumbnails, `kamadak-exif`
|
||||
for EXIF extraction
|
||||
- **Tracing**: OpenTelemetry with OTLP export (release),
|
||||
basic logger (debug)
|
||||
- **Testing**: `cargo test`, `actix_web::test`, in-memory SQLite
|
||||
|
||||
External dependencies (ffmpeg, Ollama) are optional runtime
|
||||
requirements. The server MUST start and serve core functionality
|
||||
(images, thumbnails, tags) without them. Features that depend on
|
||||
optional services MUST degrade gracefully with logged warnings,
|
||||
not panics.
|
||||
|
||||
## Development Workflow
|
||||
|
||||
- `cargo fmt` MUST pass before committing.
|
||||
- `cargo clippy` warnings MUST be resolved or explicitly suppressed
|
||||
with a justification comment.
|
||||
- `cargo test` MUST pass with all tests green before merging to
|
||||
master.
|
||||
- Database schema changes MUST use Diesel migrations
|
||||
(`diesel migration generate`), with hand-written SQL in `up.sql`
|
||||
and `down.sql`, followed by `diesel print-schema` to regenerate
|
||||
`schema.rs`.
|
||||
- Features MUST be developed on named branches
|
||||
(`###-feature-name`) and merged to master via pull request.
|
||||
- File uploads MUST preserve existing files (append timestamp on
|
||||
conflict, never overwrite).
|
||||
|
||||
## Governance
|
||||
|
||||
This constitution defines the non-negotiable architectural and
|
||||
development standards for the ImageApi project. All code changes
|
||||
MUST comply with these principles.
|
||||
|
||||
- **Amendments**: Any change to this constitution MUST be documented
|
||||
with a version bump, rationale, and updated Sync Impact Report.
|
||||
- **Versioning**: MAJOR for principle removals/redefinitions, MINOR
|
||||
for new principles or material expansions, PATCH for wording
|
||||
clarifications.
|
||||
- **Compliance**: Pull request reviews SHOULD verify adherence to
|
||||
these principles. The CLAUDE.md file provides runtime development
|
||||
guidance and MUST remain consistent with this constitution.
|
||||
|
||||
**Version**: 1.0.0 | **Ratified**: 2026-02-26 | **Last Amended**: 2026-02-26
|
||||
Reference in New Issue
Block a user