# AGENTS.md

Tento repozitář obsahuje aplikaci běžící v AppFactory.

Tento soubor je určený pro AI asistenty, vývojáře a automatizované nástroje, které budou aplikaci upravovat.

## Kontext AppFactory

Aplikace běží jako Docker container spravovaný AppFactory.

AppFactory zajišťuje:

- vytvoření Gitea repozitáře
- webhook z Gitea do AppFactory
- build Docker image
- deploy containeru
- reverse proxy přes Caddy
- runtime variables a secrets přes environment variables
- monitoring přes health endpoint

Aplikační repozitář nemá měnit infrastrukturu AppFactory.

## Veřejná URL a reverse proxy

Aplikace neběží v rootu domény.

Veřejná URL aplikace má tvar:

```text
https://services.csbot.cz/apps/<app-id>
```

Příklady:

```text
https://services.csbot.cz/apps/test-dotnet-api
https://services.csbot.cz/apps/microsoft-365-service
```

Aplikace musí počítat s tím, že běží za reverse proxy.

Nikdy nehardcoduj veřejnou doménu.

Nikdy nehardcoduj `/apps/<app-id>` do business logiky, pokud framework nabízí lepší mechanismus, například:

- `ROOT_PATH`
- `PathBase`
- `basePath`
- OpenAPI `servers`
- Swagger route prefix
- framework-specific proxy/base URL nastavení

## Caddy routing

AppFactory Caddy routuje aplikace přes:

```text
/apps/<app-id>
```

Typicky platí:

```text
veřejný request:
GET /apps/<app-id>/contacts

aplikace uvnitř containeru často vidí:
GET /contacts
```

Důvodem je použití reverse proxy route typu `handle_path`, která prefix `/apps/<app-id>` odstraní před předáním do containeru.

Aplikace proto musí být napsaná tak, aby:

- správně obsloužila interní routy
- správně generovala dokumentaci pro veřejnou proxy cestu
- Swagger UI testování používalo veřejnou cestu s `/apps/<app-id>`

## Povinné endpointy

Každá služba musí poskytovat:

```text
GET /health
GET /docs
```

Z veřejné URL musí být dostupné jako:

```text
GET /apps/<app-id>/health
GET /apps/<app-id>/docs
```

`/health` musí vracet HTTP 200, pokud je aplikace schopná přijímat provoz.

`/docs` musí poskytovat Swagger/OpenAPI dokumentaci nebo obdobnou interaktivní dokumentaci API.

Pokud služba není HTTP API, musí i tak poskytovat minimální HTTP health endpoint.

## Swagger / OpenAPI pravidla

Swagger UI a OpenAPI definice musí respektovat AppFactory reverse proxy prefix.

Pokud aplikace běží veřejně na:

```text
https://services.csbot.cz/apps/<app-id>
```

pak Swagger UI musí při testování endpointů volat stejný prefix.

Špatně:

```text
GET https://services.csbot.cz/contacts
```

Správně:

```text
GET https://services.csbot.cz/apps/<app-id>/contacts
```

Po každé úpravě API je povinné ověřit:

1. `/health` funguje
2. `/docs` funguje
3. Swagger UI se načte
4. Swagger UI `Try it out` volá endpointy přes `/apps/<app-id>`
5. OpenAPI JSON obsahuje správný server/base path
6. Nově přidané endpointy jsou ve Swagger dokumentaci

Pokud framework generuje OpenAPI `servers`, musí obsahovat proxy prefix.

Příklad:

```json
{
  "servers": [
    {
      "url": "/apps/<app-id>"
    }
  ]
}
```

Nesmí vzniknout stav, kdy Swagger UI vypadá správně, ale tlačítko `Try it out` volá endpointy bez `/apps/<app-id>`.

## ROOT_PATH / PathBase

AppFactory může aplikaci předávat environment variable:

```text
ROOT_PATH=/apps/<app-id>
```

Použití závisí na frameworku.

### .NET

V ASP.NET Core použij `UsePathBase`, pokud template nebo aplikace používá `ROOT_PATH`.

Typicky:

```csharp
var rootPath = Environment.GetEnvironmentVariable("ROOT_PATH");

if (!string.IsNullOrWhiteSpace(rootPath))
{
    app.UsePathBase(rootPath);
}
```

Swagger/OpenAPI ale musí být nakonfigurovaný tak, aby `servers` odpovídaly proxy prefixu.

Nestačí pouze přidat endpoint `/docs`.

Je nutné ověřit i Swagger `Try it out`.

### Python / FastAPI

FastAPI typicky používá `root_path`.

Aplikace musí zajistit, že dokumentace a OpenAPI schema respektují proxy prefix.

### Node.js / Express

Express aplikace musí počítat s reverse proxy prefixem.

Pokud se používá Swagger UI, musí být OpenAPI `servers` nebo Swagger konfigurace nastavené tak, aby testovací requesty šly přes `/apps/<app-id>`.

## Variables a secrets

AppFactory spravuje variables a secrets přes portál.

Portál ukládá hodnoty do DB a generuje runtime `.env` soubor aplikace.

Aplikace je čte jako environment variables.

Příklady:

### .NET

```csharp
var value = Environment.GetEnvironmentVariable("MY_VARIABLE");
var optionalValue = builder.Configuration["OPTIONAL_VARIABLE"] ?? "default";
```

### Python

```python
import os

value = os.getenv("MY_VARIABLE")
```

### Node.js

```js
const value = process.env.MY_VARIABLE;
```

Secrets se nikdy nesmí:

- commitovat do repository
- zapisovat do README
- vypisovat do logu
- vracet z běžných endpointů
- zobrazovat ve Swagger příkladech
- ukládat do zdrojového kódu
- hardcodovat

Testovací endpointy, které vrací variables nebo secrets, se smí používat pouze dočasně pro ověření a musí být odstraněny před produkčním použitím.

## Docker a port

Aplikace musí poslouchat na portu definovaném AppFactory šablonou nebo metadaty aplikace.

Port neměň bez odpovídající úpravy AppFactory konfigurace.

Aplikace musí poslouchat na všech rozhraních containeru:

```text
0.0.0.0
```

Ne pouze na:

```text
localhost
```

Dockerfile musí být deterministický a nesmí vyžadovat ruční zásahy v containeru.

Ruční změny provedené přímo v běžícím containeru nejsou trvalé.

## Co AI nesmí měnit v aplikačním repozitáři

AI nesmí z aplikačního repozitáře měnit:

- AppFactory deploy mechanismus
- Caddy konfiguraci
- Gitea webhooky
- Registry konfiguraci
- Backup/restore skripty
- Secrets storage
- Systémové soubory serveru
- AppFactory core služby
- AppFactory tools skripty

Pokud je potřeba změnit infrastrukturu, musí se to řešit v příslušném AppFactory repozitáři, ne v repozitáři konkrétní aplikace.

## Pravidla pro úpravy aplikace

Před úpravou si vždy přečti:

- `README.md`
- `AGENTS.md`
- `Dockerfile`
- hlavní vstupní soubor aplikace
- existující konfiguraci Swagger/OpenAPI
- způsob práce s environment variables

Po úpravě ověř minimálně:

- `/health`
- `/docs`
- upravovaný endpoint
- Swagger UI
- Swagger `Try it out` přes `/apps/<app-id>`
- že container stále startuje
- že se nezměnil port bez úpravy metadat
- že secrets nejsou v logu ani ve zdrojovém kódu
- ideálně průběžně generuj dokumentaci .md do složky documentation v hlavním adresáři projektu.

Každá změna musí zachovat kompatibilitu s AppFactory reverse proxy.

Pokud přidáváš nový endpoint, dokumentace se musí aktualizovat současně.

Pokud upravuješ request/response modely, Swagger/OpenAPI musí odpovídat skutečnému chování aplikace.

## Secrets v parametrech
- Variables jako ClientId apod., které by neměly jít přes normální requesty se budou předávat jako X-ClientId v hlavičce. Nezapomeň takové přidat do swagger dokumentace, když budou nutné.
    - pokud se bude předávat jinak, např. jako vnitřní secret, není potřeba. Vždy se na to programátora zeptej.

  
## Zakázané zkratky

Nedělej tyto věci:

- nepřidávej endpoint, který funguje jen lokálně, ale ne přes `/apps/<app-id>`
- neopravuj Swagger tak, že bude fungovat pouze na root doméně
- nevypínej Swagger kvůli proxy problému
- nevypínej health check
- nevypínej validaci secrets tím, že je začneš logovat
- nepřepisuj Dockerfile na jiný port bez úpravy AppFactory metadat
- nepřidávej hardcoded URL produkční domény do business logiky

## Doporučený postup po změně

Po změně aplikace ověř veřejně:

```text
GET https://services.csbot.cz/apps/<app-id>/health
GET https://services.csbot.cz/apps/<app-id>/docs
```

A přes Swagger UI ověř, že testování endpointů volá URL ve tvaru:

```text
https://services.csbot.cz/apps/<app-id>/<endpoint>
```

ne:

```text
https://services.csbot.cz/<endpoint>
```

## Shrnutí pro AI

Nejdůležitější pravidla:

- aplikace běží za `/apps/<app-id>`
- `/health` je povinný
- `/docs` se Swaggerem je povinný
- Swagger `Try it out` musí používat `/apps/<app-id>`
- OpenAPI musí mít správný base path/server
- secrets nikdy nelogovat ani necommitovat
- konfiguraci číst z environment variables
- neměnit AppFactory infrastrukturu z aplikačního repozitáře
- po každé úpravě ověř reverse proxy chování
