diff --git a/network-poc/kipina-codebench/golden-examples/README.md b/network-poc/kipina-codebench/golden-examples/README.md new file mode 100644 index 0000000..28a6b5e --- /dev/null +++ b/network-poc/kipina-codebench/golden-examples/README.md @@ -0,0 +1,123 @@ +# Golden Examples — referenssitoteutukset + +Kultaiset esimerkit ovat **täydellisiä, testattuja** FastAPI-projekteja joita LLM käyttää mallina koodigeneroinnissa. Malli näkee esimerkin ja tuottaa vastaavan rakenteen uudelle projektille. + +## Uuden esimerkin luominen + +### 1. Luo hakemisto + +```bash +mkdir golden-examples/shop +``` + +Nimeä hakemisto skenaarion mukaan (todo, blog, shop, booking...). + +### 2. Luo 4 tiedostoa + +| Tiedosto | Sisältö | +|----------|---------| +| `models.py` | SQLAlchemy 2.0 -mallit (DeclarativeBase, Mapped, mapped_column) | +| `schemas.py` | Pydantic v2 -skeemat (ConfigDict, `str \| None` -syntaksi) | +| `main.py` | FastAPI CRUD -endpointit (POST 201, GET, GET/:id 404, PUT, DELETE 204) | +| `test_main.py` | Pytest + TestClient, erillinen test.db, uniikki data per testi | + +### 3. Noudata konventioita + +**Python-versio:** >=3.14 + +**SQLAlchemy 2.0** (ei legacy): +```python +# Oikein +class Base(DeclarativeBase): + pass + +class Todo(Base): + id: Mapped[int] = mapped_column(primary_key=True, index=True) + title: Mapped[str] = mapped_column(String(255)) + status: Mapped[str] = mapped_column(String(20), default="pending") + +# Väärin +Base = declarative_base() +id = Column(Integer, primary_key=True) +``` + +**Pydantic v2** (ei v1): +```python +# Oikein +class TodoResponse(TodoCreate): + id: int + model_config = ConfigDict(from_attributes=True) + +# Väärin +class Config: + orm_mode = True +``` + +**Tyypitys:** +```python +# Oikein +description: Mapped[str | None] = mapped_column(Text, default=None) + +# Väärin +description: Mapped[Optional[str]] +``` + +**Dokumentointi (zensical):** +```python +"""Tietokantamallit — SQLAlchemy 2.0, Mapped-tyypitys, SQLite.""" + +class Todo(Base): + """Tehtävä — otsikko, kuvaus, deadline, prioriteetti ja status.""" +``` + +Yksi rivi riittää. Kerro mitä asia ON, älä mitä se tekee. Katso [DOCUMENTATION.md](DOCUMENTATION.md). + +**Testidata — uniikki ja kuvaava:** +```python +# Oikein +def test_create_todo(): + response = client.post("/todos/", json={"title": "Osta maitoa", "priority": 2}) + +def test_update_todo(): + created = client.post("/todos/", json={"title": "Vanha otsikko"}).json() + +# Väärin — geneerinen data +def test_create_todo(): + response = client.post("/todos/", json={"title": "test", "priority": 1}) +``` + +### 4. Testaa Docker-kontissa + +```bash +rm -rf /tmp/golden-test && mkdir /tmp/golden-test +cp golden-examples/shop/*.py /tmp/golden-test/ +docker run --rm -v /tmp/golden-test:/src:ro kipina-pytest +``` + +**Kaikkien testien pitää mennä läpi.** Ei varoituksia, ei deprecation-viestejä. + +### 5. Vaikeustasot + +| Taso | Esimerkit | Haaste | +|------|-----------|--------| +| 1 — Perus-CRUD | `todo/`, `users/`, `notes/` | Yksi entiteetti | +| 2 — Relaatiot | `blog/`, `library/`, `school/` | Foreign key, 2–3 entiteettiä | +| 3 — Liiketoimintalogiikka | `shop/`, `booking/` | Custom endpointit, validointi | + +Aloita tasosta 1 ja etene. Tason 1 esimerkkien pitää olla yksinkertaisia — ne opettavat mallille perusrakenteen. + +## Miten esimerkit vaikuttavat + +Benchmark lataa `todo/`-esimerkin ja syöttää sen LLM:lle osana koodingenerointipromptia: + +``` +REFERENCE IMPLEMENTATION (todo project — follow this exact structure): + +=== models.py === + + +=== schemas.py === +... +``` + +Malli näkee tarkan esimerkin ja tuottaa vastaavan rakenteen uudelle projektille. Mitä parempi esimerkki, sitä parempi tulos.