diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..aabd585 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,69 @@ +# AGENTS.md + +## Cursor Cloud specific instructions + +This repo is the **.NET 8 backend** for SHOC (Sea Haven Industries), a facility +maintenance / work-order & vendor-dispatch platform. It pairs with the React SPA in +the `shoc-frontend-new` repo. Architecture details live in `BACKEND_ARCHITECTURE.md`; +required config is documented in `.env.example`. + +### Services & how they run (dev) + +- **SQL Server 2022** (installed on the VM, Developer edition). There is **no systemd** + in this environment, so it is **not** started as a service. Start it manually: + `sudo -u mssql MSSQL_SA_PASSWORD='SeaHaven!Passw0rd1' /opt/mssql/bin/sqlservr` + (run it in a tmux/background session). It listens on `localhost:1433`. + Note: `sqlservr` needs the OpenLDAP 2.5 libs (`liblber-2.5.so.0` / `libldap-2.5.so.0`) + which are shimmed into `/usr/lib/x86_64-linux-gnu` because the base OS ships 2.6. +- **Web API** (`Api.SeaHavenIndustries`): from the repo root run + `cd Api.SeaHavenIndustries && dotnet run` with these env vars exported first: + - `ConnectionStrings__DefaultConnection='Server=localhost,1433;Database=SeahavenIndustries;User Id=sa;Password=SeaHaven!Passw0rd1;TrustServerCertificate=True;MultipleActiveResultSets=true'` + - `JWT__Secret='local-dev-jwt-secret-key-change-me-please-1234567890'` (any long string) + - `ASPNETCORE_ENVIRONMENT=Development` and `ASPNETCORE_URLS='http://localhost:5141'` + Swagger UI is served at `http://localhost:5141/` (root). The React dev server proxies + `/api` to `:5141`. +- `SendGrid`, AWS (DynamoDB/S3), Google Maps keys are optional; email failures are + swallowed so the app runs without them. + +The SA password above is a **local-dev-only** credential for this VM's SQL Server, not a +real secret. + +### Database: migrations & seeding + +- Apply schema with EF Core (the `dotnet-ef` global tool is installed): + `dotnet-ef database update --project Data.SeaHavenIndustries --startup-project Api.SeaHavenIndustries` + (export `ConnectionStrings__DefaultConnection` first). The `DefaultConnection` + placeholder in `appsettings*.json` is intentional — always supply the real value via + env var / user-secrets. +- The role/admin seeding block in `Api.SeaHavenIndustries/Program.cs` is **commented + out**, so no users exist after a fresh migrate and there is no anonymous + registration endpoint. A dev admin is seeded on this VM (role `Admin`). Read + credentials from Cursor Cloud secrets **`TEST_LOGIN_USERNAME`** and + **`TEST_LOGIN_PASSWORD`** — do not commit plaintext credentials. If the user is + missing (e.g. a fresh DB), create it with a throwaway console app that references + `Data.SeaHavenIndustries` and uses ASP.NET Identity `UserManager`/`RoleManager` + (mirror the commented block in `Program.cs`), using those same secret values. + +### Lint / test / build + +- Build: `dotnet build SeaHavenIndustries.sln` (warnings only; 0 errors expected). +- Smoke tests (no SQL required): + `dotnet test Api.SeaHavenIndustries.Tests/Api.SeaHavenIndustries.Tests.csproj` and + `dotnet test SeaHaven.Services.Tests/SeaHaven.Services.Tests.csproj` + (xUnit + EF Core InMemory). Expect ~12 + ~18 passing on current `dev`. +- Broader suite: `dotnet test SeaHavenIndustries.Tests/SeaHavenIndustries.Tests.csproj`. + Some SQL Server LocalDB-gated tests only skip cleanly on Windows LocalDB; on Linux + they may fail open with `PlatformNotSupportedException` instead of skipping — treat + that as a test-hygiene issue on the branch under review, not a missing VM dependency. + +### Known pre-existing app bugs (NOT environment problems) + +These are real defects in the committed code; do not mistake them for setup issues: +- **EF model/migration drift.** The `Locations` entity expects columns + `Address1, Address2, Zip, PhoneNumber, Email` but the latest migration created + `Address, ZipCode, Phone, ContactEmail`. Any query that touches `Locations` + (location CRUD, and any list/detail that joins it, e.g. Follow-up list/GetById) + throws `Invalid column name 'Address1'`. The `Events` table has no migration at all + (`Invalid object name 'Events'`), so Calendar read/list fails. +- **Writes that avoid the drifted tables work end-to-end.** Verified: login, Employee + create/list/delete, and Follow-up `Create` all persist to SQL Server.