# Archipel API

Slim 4 on OVH shared hosting (PHP 8.4; `composer.json` still pins 8.2 for dependency resolution), raw PDO. Setup, structure, deploy and data retention are in README.md.

## How to work

- **Think first.** Say what you assume. If the request can be read two ways, ask instead of picking one. If something simpler would do, say so.
- **Keep it simple.** The least code that solves the request: no extra features, no abstraction for a single use, no options nobody asked for.
- **Warn, don't build, for unlikely cases.** Don't write handling for a case that is improbable. If one seems worth covering, tell the user what could happen and what you would do about it, and build it only if they say so.
- **Stay in scope.** Every changed line traces back to the request. Match the surrounding style; don't refactor or reformat what you didn't need to touch. Mention dead code you notice instead of deleting it; remove only what your own change made unused.
- **Prove it works.** Turn the task into something checkable before writing code, and loop until it passes (see Tests).

## Rules

- No docblocks or comment paragraphs. A single short line only when something is genuinely non-obvious.
- OVH blocks PUT and DELETE: every PUT also gets a POST on the same path, every DELETE a `POST {path}/delete`.
- Respond with `JsonResponse::ok` / `error` / `fieldError(s)`; 500s go through `serverError`, which logs and hides details.
- Unused routes stay, marked `// Unused by any client for now.`
- Uploaded files are only saved through `ImageStore` / `FileStore`, which check the file type; never write an upload to disk directly.
- Migrations: a new numbered `.sql` file, idempotent (guard on information_schema), never rename or edit an applied one, no down.
- Never commit `.env` or any `.env.*` other than `.env.example` and `.env.testing`. Secrets never go in chat either.

## Tests

Every change comes with a test in `tests/`: a bug fix starts with a test that fails before the fix, a new route or rule gets tests for the normal case and the refused one, a refactor passes the same tests before and after.

```bash
composer analyse
DB_PORT=3306 composer test
```

Tests rebuild `archipel_test` from `migrations/` every run; any `DB_*` can be overridden (e.g. `DB_PORT=3307` for a throwaway MySQL in Docker when 3306 is taken). A new route is covered by `RouteSweepTest` automatically; if its path parameter is new, map it to a `World` fixture id there. The sweep sends empty bodies, so a route's real path needs its own test.

## Committing and pushing

- Commit straight to `main`, and only once the user agrees: show what changed and ask first.
- Commit messages carry no `Co-Authored-By` or other attribution line.
- Never push without asking. Before pushing, ask whether to do a cleanup pass on the changes (leftover debug, unused code, needless complexity), then run the checks above.
- Group related work into one push: every push runs a full pipeline on GitLab's paid CI minutes.

## Deploy

A push to `main` runs `check`, then deploys to api-staging.archipel.education by itself. Production is the manual `promote_production` job. Promote the API before a front end that needs its new routes.
