project_repository¶
Provides project CRUD operations for plant design projects stored in R2. These are non-lifecycle operations (no lock needed) that don't belong in the session.
Replaces the project management parts of S3ProjektManager.
Structure¶
project_repository/
model/
project_metadata.py ProjectMetadata dataclass, ProjectStatus enum
stage_metadata.py Per-stage metadata dataclasses + get_default_stage_metadata()
project_errors.py Exception hierarchy
lock_file_data.py LockFileData dataclass
release_metadata.py Release metadata models
controller/
project_repository.py ProjectRepository - main API
r2_key_builder.py R2 key path helpers
Usage¶
from src.modules.plant_design.startup_system.bound_subsystems.project_repository.controller.project_repository import (
ProjectRepository,
)
repo = ProjectRepository()
# Discover projects (no index file - uses R2 prefix listing)
project_ids = repo.list_projects()
# Read metadata
metadata = repo.get_project_metadata("1234567")
# Create a new project
from src.modules.plant_design.startup_system.bound_subsystems.project_repository.model.project_metadata import (
ProjectMetadata,
)
meta = ProjectMetadata(
projekt_name="Kraftwerk Beispiel",
projekt_nummer="1234567",
created_by="max.mustermann",
created_at="2026-02-10T08:00:00",
)
repo.create_project(meta)
API¶
| Method | Description |
|---|---|
list_projects() |
Discover project IDs via list_common_prefixes() |
get_project_metadata(id) |
Download and deserialize project.meta.json |
get_stage_metadata(id, stage) |
Download stage metadata JSON |
project_exists(id) |
Check if project.meta.json exists |
create_project(metadata) |
Upload metadata + stage dirs + releases manifest |
update_project_metadata(id, metadata) |
Overwrite project.meta.json |
update_stage_metadata(id, stage, data) |
Upload stage metadata JSON |
copy_project_from_template(source_id, target_metadata) |
Server-side copy (skips .lock.json files) |
Key Design Decisions¶
- No projekt_index.json - projects discovered via R2
list_common_prefixes() - JSON metadata - all metadata is JSON (no msgpack)
- No lock state in metadata - locks are per-stage
.lock.jsonfiles - Per-stage commit tracking in
project.meta.jsonstagesdict - Typed stage metadata via
get_default_stage_metadata()on creation - Stateless - creates
BucketService()internally, no shared state
See docs/dev_guidelines/r2_project_structure_reference.md for the canonical R2 structure.
Exceptions¶
ProjectRepositoryError- base exceptionProjectAlreadyExistsError- duplicate project on creationProjectNotFoundError- project or metadata missing
R2 network/auth errors propagate as R2Error from the r2_com layer.
Dependencies¶
src.shared_services.cloud_com.r2_com- BucketService for all R2 operationssrc.shared_services.constants.cloud-R2_PLANT_DESIGN_PROJECTSprefix constant