# SHOC Backend (`shoc-backend`) [![CI](https://github.com/Sea-Haven-Industries/shoc-backend/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/Sea-Haven-Industries/shoc-backend/actions/workflows/ci.yml) [![Deploy](https://github.com/Sea-Haven-Industries/shoc-backend/actions/workflows/deploy.yaml/badge.svg)](https://github.com/Sea-Haven-Industries/shoc-backend/actions/workflows/deploy.yaml) ![.NET 8](https://img.shields.io/badge/.NET-8.0-512BD4?logo=dotnet&logoColor=white) ![SQL Server](https://img.shields.io/badge/SQL%20Server-CC2927?logo=microsoftsqlserver&logoColor=white) ![Terraform](https://img.shields.io/badge/Terraform-844FBA?logo=terraform&logoColor=white) ASP.NET Core 8 API for Sea Haven facility management (SHOC): work orders, the work-order board, dispatches and the vendor portal, uplift approvals, notifications, and the dashboard. It is the backend for [`shoc-frontend-new`](https://github.com/Sea-Haven-Industries/shoc-frontend-new), which calls it directly over HTTPS. | Environment | API | Elastic Beanstalk environment | Deployed by | |---|---|---|---| | dev | `https://api.dev.seahaven.com` | `shoc-backend-dev` | every push to `main` | | staging | `https://api.staging.seahaven.com` | `shoc-backend-staging` | a `vX.Y.Z-staging` tag cut with `release.yaml` | Both run in `us-east-1` on the .NET 8 Amazon Linux 2023 platform. Terraform in `terraform/live/` owns the environments; GitHub Actions owns the application versions. There is no production environment yet. Stored created, modified and deletion times are UTC: the API stamps them with `DateTime.UtcNow`, whatever the host's time zone. The API has only ever run on Linux Elastic Beanstalk hosts left at their UTC default (nothing in Terraform, `.ebextensions` or `.platform` sets a time zone), so rows written before the switch from `DateTime.Now` are already UTC and need no backfill. ## Architecture ```text Controller -> I{Feature}Service -> I{Feature}DataService -> ApplicationDbContext ``` Controllers depend on feature service interfaces only. Business services depend on feature data-service interfaces, never on `DbContext`. Data services own Entity Framework Core and are the atomic commit boundary. Tenant scope is derived on the server from claims, and authorization is enforced at service entry. The rules and their reasons are in [`ARCHITECTURE_AND_CODE_QUALITY.md`](ARCHITECTURE_AND_CODE_QUALITY.md). | Project | Role | |---|---| | `Api.SeaHavenIndustries` | The deployed API: controllers, hosted services, infrastructure adapters, `Program.cs` | | `SeaHaven.Services` | Business services, DTOs, validation, helpers | | `SeaHaven.DataServices` | Feature data services over EF Core | | `Data.SeaHavenIndustries` | Entities, `ApplicationDbContext`, Identity, migrations | | `SeaHavenIndustries` | Legacy Blazor Server app sharing the data layer; not part of the API deployment | | `Api.SeaHavenIndustries.Tests`, `SeaHaven.Services.Tests`, `SeaHavenIndustries.Tests` | xunit test projects | ## Local development Requires the .NET 8 SDK and a reachable SQL Server. Configuration comes from `appsettings*.json` placeholders, then user secrets, then environment variables. `.env.example` lists every key, including the connection string, JWT secret, SendGrid key and Sentry DSN. Do not commit real values. ```bash dotnet restore SeaHavenIndustries.sln dotnet build SeaHavenIndustries.sln --configuration Release dotnet test SeaHavenIndustries.sln --configuration Release dotnet run --project Api.SeaHavenIndustries ``` The full repository gate that CI runs, including architecture discovery, the changed-file maintainability check, Terraform checks and app/Terraform isolation: ```bash BASE_REF=origin/main bash scripts/governance-check.sh ``` Migrations live in `Data.SeaHavenIndustries/Migrations` and are applied at deploy time from a bundle the packaging script builds with `dotnet-ef`. Adding one follows the G6 rules in [`QUALITY_GATES.md`](QUALITY_GATES.md). ## Contributing - Branch from `main` with a `feature/`, `fix/`, `chore/`, `docs/` or `refactor/` prefix and a kebab-case description. - Commit subjects follow Conventional Commits. PR titles end with the Jira key for product work. - The PR body uses the three-section layout the template pre-fills: Summary, Changes and value, Ticket. The reasoning is in [`REVIEW_AND_PR_FRAMEWORK.md`](REVIEW_AND_PR_FRAMEWORK.md). - `main` requires a code-owner review and the `ci-complete` check. PRs merge through the merge queue, so a branch does not need to be updated with `main` before it merges. - Application code and `terraform/` do not change in the same PR (G13). ## Deployment `deploy.yaml` packages the API with `scripts/package-elastic-beanstalk.sh`, uploads the bundle to the Elastic Beanstalk bucket, updates the environment, verifies the exact version is active, and smoke-tests it. The bundle carries a self-contained EF Core migrations bundle that Elastic Beanstalk runs on the leader instance before the new version starts (`.ebextensions/01_migrations.config`). A push to `main` targets dev. `release.yaml` cuts a SemVer tag from `main` and calls the same workflow for staging. Both are described in the workflow headers and in [`terraform/live/README.md`](terraform/live/README.md). Renovate opens dependency PRs on the schedule in `.github/renovate.json`; majors wait for approval on the Dependency Dashboard issue. ## Documentation - [`AGENTS.md`](AGENTS.md): repo-specific rules for coding agents and the order of precedence between the governance documents. - [`ARCHITECTURE_AND_CODE_QUALITY.md`](ARCHITECTURE_AND_CODE_QUALITY.md): what the architecture rules mean. - [`QUALITY_GATES.md`](QUALITY_GATES.md): every gate, the command that runs it locally, and where CI runs it. - [`REVIEW_AND_PR_FRAMEWORK.md`](REVIEW_AND_PR_FRAMEWORK.md): review order, evidence, and the PR description contract. - [`docs/adr/`](docs/adr/): architecture decision records. - [`docs/work-orders/`](docs/work-orders/): work-order board phase notes. - [`postman/`](postman/): generated Postman collection and dev environment. - [`terraform/README.md`](terraform/README.md): infrastructure runbook.