Skip to content

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.json files
  • Per-stage commit tracking in project.meta.json stages dict
  • 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 exception
  • ProjectAlreadyExistsError - duplicate project on creation
  • ProjectNotFoundError - 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 operations
  • src.shared_services.constants.cloud - R2_PLANT_DESIGN_PROJECTS prefix constant