# Migrazio-gida: 9.8.5 → 9.9.0

**9.9.0** bertsioak Filter zaharren runtime-a faseetan oinarritutako Middleware sistemarekin ordezkatzen du eta Osumi Framework-en aplikazio-migrazio bertsionatuen lehen motorra gehitzen du.

Filterrak erabiltzen dituzten aplikazioentzat **bateragarritasun-haustura duen bertsioa** da.

Framework-ak migrazio automatiko bat dauka, onartutako Filter erabilerak Middleware sistemara bihurtzeko eta jatorrizko Filter negozio-logika mantentzeko.

---

## Laburpena

### Gehitua

- Hiru fasetako Middleware pipeline natiboa:
  - `before`
  - `afterRender`
  - `afterResponse`
- Middleware globalak, taldekoak eta ibilbidekoak.
- `src/Middleware/Middlewares.php` konfigurazio globalerako.
- `ORequest::getMiddleware()`.
- `ORequest::getMiddlewareValue()`.
- `ODTOField`-en Middleware iturburuak:
  - `middleware`
  - `middlewareProperty`
- `stop` bidezko errore-erantzun tipatuak.
- Framework migrazio-motorra.
- `vendor/bin/ofw-migrate`.
- Migrazio-kopia transakzionalak.
- Migrazio-egoera `ofw/tmp/state.json` fitxategian.
- Composer integrazioa `osumionline/plugin-updater` bidez.

### Aldatua

- Ibilbideko Filterrak faseen arabera definitutako Middlewareekin ordezkatzen dira.
- Filter zaharren irteera Middleware testuinguru gisa azaltzen da migrazio automatikoaren ondoren.
- `ODTOField(filter: ..., filterProperty: ...)` → `middleware` / `middlewareProperty`.
- `$req->getFilter('Name')` → `$req->getMiddleware('Name')`.
- Autentifikazioa, baimena eta eskaera-interzepzioa Middleware natiboekin egin behar dira.

### 9.9 runtime-tik kendua

- Filter pipeline-a.
- CLI bidez Filter berriak sortzea.
- Filterrei lotutako `ORequest` API legacy-ak.

Filter klase zaharrak aldi baterako gera daitezke migratutako proiektuetan, migrazioak haien gaineko bateragarritasun Middleware adapterrak sortzen dituelako.

---

# 1. Eguneratu aurreko baldintzak

Osumi Framework 9.9k behar ditu:

- PHP 8.5 edo berriagoa.
- Composer 2.x.
- `osumionline/plugin-updater`.
- Composer-ek updater plugina exekutatzeko baimena.

Eguneratu aurretik, gehitu hau proiektuaren erroko `composer.json` fitxategian oraindik ez badago:

```json
{
	"config": {
		"allow-plugins": {
			"osumionline/plugin-updater": true
		}
	}
}
```

Composer-ek lehen instalazioan pluginean konfiantza izateko galdetu dezake.

---

# 2. Gomendatutako eguneratze-prozedura

Eguneratu aurretik:

1. Egin commit edo stash aplikazioaren aldaketekin.
2. Ziurtatu proiektua egoera funtzional ezagun batean dagoela.
3. Produkzioan, egin datu iraunkorren kopia.
4. Eguneratu framework-a Composer bidez.

Adibidea:

```bash
composer update osumionline/framework --with-dependencies
```

Composer-ek autoloader-a berreraiki ondoren, `osumionline/plugin-updater`-ek instalatutako framework bertsioa egiaztatzen du eta zain dauden migrazio guztiak exekutatzen ditu.

9.8.5 → 9.9.0 eguneratzean `9.9.0` migrazio-pausoa exekutatzen da.

---

# 3. Composer bidezko migrazio automatikoa

Fluxua:

```text
Composer update
↓
osumionline/plugin-updater
↓
post-autoload-dump
↓
Runner::runPending()
↓
9.9.0 migrazioaren preflight-a
↓
proiektuaren aldaketa transakzionalak
↓
state.json eguneratzea
```

Migrazio-egoera da iturri autoritarioa. Horri esker migrazioak ondo exekutatzen dira nahiz eta:

- framework-aren hainbat bertsio batera saltatu;
- updater plugina Composer operazio berean instalatu;
- Composer-ek autoload event bat baino gehiago jaulki.

Composer-ek abiarazitako migrazioetan Git egiaztapenak bi fitxategi hauek bakarrik baztertzen ditu:

```text
composer.json
composer.lock
```

Aplikazio-kodeko edo beste fitxategietako aldaketek migrazioa geldiarazten jarraitzen dute, exekuzio behartua esplizituki aktibatu ezean.

---

# 4. Composer migrazioen aurrebista

Updater-ak ingurune-aldagaiak onartzen ditu.

### Dry-run

```bash
OFW_DRY_RUN=1 composer update osumionline/framework --with-dependencies
```

Honek **framework migrazioa** dry-run moduan exekutatzen du.

Garrantzitsua: Composer-ek bere pakete-operazioa egiten jarraitzen du. `OFW_DRY_RUN`-ek Osumi Framework migrazioaren proiektu-aldaketak bakarrik saihesten ditu.

### Irteera xehea

```bash
OFW_VERBOSE=1 composer update osumionline/framework --with-dependencies
```

### Segurtasun-egiaztapenak behartzea

```bash
OFW_FORCE=1 composer update osumionline/framework --with-dependencies
```

Erabili kontu handiz. Exekuzio behartua onartzen duten migrazio-segurtasun egiaztapenak saihesten ditu.

Balio boolean onartuak:

```text
1
true
yes
y
on
```

eta:

```text
0
false
no
n
off
```

---

# 5. Migrazioen CLI manuala

Framework paketeak hau eskaintzen du:

```bash
php vendor/bin/ofw-migrate --help
```

Zain dauden migrazioak exekutatzeko:

```bash
php vendor/bin/ofw-migrate
```

Ikuskapenerako gomendatutako komandoa:

```bash
php vendor/bin/ofw-migrate --dry-run --verbose
```

Aukerak:

```text
--from=VERSION
--to=VERSION
--dry-run
--force
--verbose
--no-interaction
--help
```

### `--from`

Migrazio-egoeratik jasotako jatorrizko bertsioa ordezkatzen du.

Adibidea:

```bash
php vendor/bin/ofw-migrate --from=9.8.5 --to=9.9.0
```

Erabili soilik bertsio-tarte esplizitua nahita behar duzunean.

### `--to`

Helburuko bertsioa ordezkatzen du. Ez bada adierazten, instalatutako framework bertsioa automatikoki detektatzen da.

### `--dry-run`

Planifikatutako eragiketak erakusten ditu proiektu-fitxategiak aldatu gabe.

### `--force`

Exekuzio behartua onartzen duten segurtasun-egiaztapenak saihesten ditu, Git lan-zuhaitz garbiaren egiaztapena barne.

### `--verbose`

Migrazioen eta fitxategi-eragiketen xehetasunak erakusten ditu.

### `--no-interaction`

Portaera interaktiboa desgaitzen du.

---

# 6. Git lan-zuhaitzaren babesa

Migrazio manual normal batean, Git bidez kudeatutako proiektu batek lan-zuhaitz garbia izan behar du.

Ustekabeko aldaketak badaude, migrazioa gelditzen da proiektua aldatu beharrean.

`.git` gabeko proiektuak ere onartzen dira; migrazio-kopia transakzionalak erabiltzen jarraitzen dute.

Dry-run moduak ez du lan-zuhaitz garbirik behar, ez duelako aldaketarik gordetzen.

Composer bidezko migrazio automatikoan `composer.json` eta `composer.lock` bakarrik baztertzen dira egiaztapen horretatik.

Hobe da commit edo stash egitea `--force` erabiltzea baino.

---

# 7. Zer egiten du 9.9.0 migrazioak

Migrazioak preflight osoa egiten du aplikazio-fitxategirik idatzi aurretik.

Filter zaharrak hemen bilatzen ditu:

```text
src/Filter/
```

Onartutako Filterrek Osumi Framework-en ohiko PSR-4 namespace eta fitxategi-izen konbentzioak bete behar dituzte.

Jatorrizko Filter fitxategiak **ez dira ezabatzen edo berridazten**.

Filter bakoitzeko bateragarritasun Middleware bat sortzen da hemen:

```text
src/Middleware/
```

Adibidea:

```text
src/Filter/LoginFilter.php
↓ mantentzen da

src/Middleware/LoginMiddleware.php
↓ sortutako bateragarritasun adapterra
```

Adapter sortuek Filter originala fase honetan bakarrik exekutatzen dute:

```php
OMiddleware::PHASE_BEFORE
```

---

# 8. Filter zaharraren emaitzaren bihurketa

Adapterrak Filter emaitza 9.9 Middleware kontratura bihurtzen du.

### Filter zuzena

Emaitza zaharra:

```php
[
	'status' => 'ok',
	'id' => 42
]
```

testuinguru bihurtzen da:

```php
[
	'context' => [
		'status' => 'ok',
		'id' => 42
	]
]
```

Hau irakur daiteke:

```php
$login = $req->getMiddleware(
	'Login'
);
```

edo:

```php
$id = $req->getMiddlewareValue(
	'Login',
	'id'
);
```

### Huts egindako Filterra

Zuzena ez den Filter emaitza `stop` bihurtzen da HTTP 403rekin.

### Redirect zaharra

Filterrak `return` balioan URL balioduna itzultzen badu, adapterrak sortzen du:

- HTTP 302
- `Location` goiburua
- `stop`

Horrek legacy portaera mantentzen du migrazioan.

---

# 9. Kodearen transformazio automatikoak

Migrazioak `src/Filter/` eta `src/Middleware/` kanpoko kode bateragarria eraldatzen du.

## `ORequest`

Aurretik:

```php
$login = $req->getFilter(
	'Login'
);
```

Ondoren:

```php
$login = $req->getMiddleware(
	'Login'
);
```

## DTOak

Aurretik:

```php
#[ODTOField(
	filter: 'Login',
	filterProperty: 'id'
)]
public ?int $idUser = null;
```

Ondoren:

```php
#[ODTOField(
	middleware: 'Login',
	middlewareProperty: 'id'
)]
public ?int $idUser = null;
```

## Ibilbideak

Aurretik:

```php
ORoute::get(
	'/profile',
	ProfileComponent::class,
	[
		LoginFilter::class
	]
);
```

Ondoren:

```php
ORoute::get(
	'/profile',
	ProfileComponent::class,
	[
		'before' => [
			\Osumi\OsumiFramework\App\Middleware\LoginMiddleware::class
		]
	]
);
```

Onartutako `ORoute` deietako Filter array literalak `before` Middleware zerrendetara bihurtzen dira.

---

# 10. Middleware konfigurazio globala

Fitxategi hau ez badago:

```text
src/Middleware/Middlewares.php
```

migrazioak sortzen du:

```php
<?php

declare(strict_types=1);

namespace Osumi\OsumiFramework\App\Middleware;

use Osumi\OsumiFramework\Core\OMiddleware;

OMiddleware::setGlobal([
	OMiddleware::PHASE_BEFORE => [],
	OMiddleware::PHASE_AFTER_RENDER => [],
	OMiddleware::PHASE_AFTER_RESPONSE => []
]);
```

Lehendik badago, bere edukia zehazki mantentzen da.

---

# 11. Automatikoki migratzen ez diren kasuak

Migrazioa nahita gelditzen da kodea modu seguruan eraldatu ezin duenean.

### Ibilbideetako Filter adierazpen dinamikoak

Ez da onartzen:

```php
$filters = [
	LoginFilter::class
];

ORoute::get(
	'/profile',
	ProfileComponent::class,
	$filters
);
```

Migrazio automatikorako ibilbideetako Filter adierazpenek klase-array literalak izan behar dute.

### `ORequest` metodo legacy-ak

Eskuz aldatu behar dira:

```php
$req->getFilters()
$req->setFilter(...)
$req->setFilters(...)
```

Migrazioa gelditzen da dei horiek aurkitzen baditu.

### Ebatzi ezin diren Filter erreferentziak

Migratu daitekeen Filter definizio batekin lotu ezin den Filter bati erreferentzia egiten dion ibilbidea baztertzen da.

### Lehendik dauden Middlewareekin gatazkak

Sortu beharreko Middleware fitxategia lehendik edukia desberdinarekin badago, migrazioa gelditzen da gainidatzi beharrean.

### Fitxategi-egitura ez-seguruak

Esteka sinbolikoen bidezko ibilbideak eta proiektu-bide ez-seguruak baztertzen dira.

Migrazioa nahita kontserbadorea da: kode anbiguoa eskuz migratu behar da, bere asmoa asmatzen saiatu beharrean.

---

# 12. Segurtasun transakzionala eta rollback-a

Aldaketak sistema transakzional baten bidez idazten dira.

Kopiak hemen gordetzen dira:

```text
ofw/tmp/migrations/
```

Transakzio bakoitzak timestamp/identifikatzaile ausazkoa duen direktorio propioa eta aldatu diren fitxategien manifest bat dauka.

Migrazio-egoera aplikazioaren aldaketen transakzio berean idazten da.

Eragiketa batek huts egiten badu:

1. aldatutako fitxategiak leheneratzen dira;
2. huts egindako migrazioak sortutako fitxategiak ezabatzen dira;
3. egoera proiektuarekin batera leheneratzen da;
4. migrazioa errorearekin amaitzen da.

Ondo bukatutako transakzioen kopiak diskoan mantentzen dira ikuskapenerako.

---

# 13. Migrazio-egoera

Egoera hemen gordetzen da:

```text
ofw/tmp/state.json
```

9.9.0 ondo amaitu ondoren:

```json
{
	"last_migrated": "9.9.0"
}
```

Egoera-fitxategirik ez badago, runner-ak `0.0.0` erabiltzen du hasierako migrazio-bertsio gisa eta instalatutako helburura arteko pauso aplikagarri guztiak hautatzen ditu.

Horri esker migrazio-motorra existitu aurretik sortutako proiektuak eguneratu daitezke.

Ondorengo exekuzio normal batek ez du 9.9.0 berriro aplikatzen.

---

# 14. Idempotentzia

Migrazio-sistema idempotentea izateko diseinatuta dago.

Adibidez:

- Egoerak exekuzio normal batean bukatutako pausoak errepikatzea saihesten du.
- Lehendik sortutako adapter bat onartzen da edukia zehazki berdina bada.
- Lehendik dagoen `Middlewares.php` mantentzen da.
- Bigarren exekuzio normal batek ez du 9.9.0 migrazioa zain aurkitzen.

Ez erabili `--from` bukatutako migrazio bat nahita berriro hautatzeko, ondorioak ezagutzen ez badituzu.

---

# 15. Migrazioaren ondorengo egiaztapena

Migrazioaren ondoren:

1. Berrikusi `src/Middleware/` barruan sortutako fitxategiak.
2. Berrikusi eraldatutako ibilbideak.
3. Berrikusi `middleware` / `middlewareProperty` erabiltzen dituzten DTOak.
4. Bilatu runtime legacy erabilerak.
5. Exekutatu test guztiak.
6. Egin autentifikazio/baimen proba funtzionalak.
7. Egin commit migratutako kodearekin.

Bilaketa erabilgarriak:

```text
getFilter(
getFilters(
setFilter(
setFilters(
filterProperty
```

Normala da `src/Filter/`-eko legacy klaseak oraindik egotea bateragarritasun adapterrak erabiltzen diren bitartean.

---

# 16. Sortutako adapterrak Middleware natibo bihurtzea

Sortutako adapterrak bateragarritasun-zubia dira, ez gomendatutako azken arkitektura.

Migratutako proiektua egiaztatu ondoren, Filter logika pixkanaka Middleware klasera eraman daiteke.

Middleware natibo batek hau erabiltzen du:

```php
public static function handle(
	string $phase,
	array $data
): array
```

eta emaitza esplizituak itzultzen ditu, adibidez:

```php
return [
	'context' => [
		'id' => 42
	]
];
```

edo:

```php
return [
	'stop' => true,
	'status_code' => 401,
	'message' => 'Unauthorized'
];
```

Gomendatutako prozesua:

```text
Filter legacy-a
↓
sortutako bateragarritasun Middlewarea
↓
egiaztapen funtzionala
↓
logika Middleware natibora eraman
↓
erabiltzen ez den Filterra ezabatu
```

Mantendu ahal denean sortutako Middleware klasearen izena, dagoeneko migratutako ibilbideak eta testuinguru-izen publikoak berriro aldatu behar ez izateko.

Adapter guztiak bihurtu ondoren, `src/Filter/` ezaba daiteke beharrezko legacy logikarik geratzen ez bada.

---

# 17. Middlewareen gaitasun berriak

Middleware natiboak ez daude Filter zaharren portaerara mugatuta.

Fase hauetan exekuta daitezke:

```text
before
afterRender
afterResponse
```

Honako hauek argitaratu edo alda ditzakete:

- testuingurua
- gorputza
- goiburuak
- HTTP egoera
- `stop` bidezko errore-erantzunak

Middleware globalak, talde habiaratuetakoak eta ibilbidekoak fase bakoitzean ordena honetan metatzen dira:

```text
globala
↓
kanpoko taldea
↓
barneko taldea
↓
ibilbidea
```

Ikusi:

```text
docs/eu/concepts/middlewares.md
```

9.9 Middleware API osoa ezagutzeko.

---

# 18. Garatzaileak egin beharrekoa

9.8.5etik eguneratzen diren aplikazioetan:

1. Ziurtatu PHP 8.5+ erabiltzen dela.
2. Baimendu `osumionline/plugin-updater` Composer konfigurazioan.
3. Egin commit edo stash tokiko aldaketekin.
4. Eguneratu Osumi Framework Composer bidez.
5. Berrikusi migrazio automatikoaren irteera.
6. Konpondu eskuz migratzaileak adierazitako onartu gabeko legacy egiturak.
7. Exekutatu test osoak eta proba funtzionalak.
8. Egin commit migratutako kodearekin.
9. Aukeran, ordezkatu bateragarritasun adapterrak Middleware natiboekin.

Filterrik erabiltzen ez duten proiektuetan ere, 9.9 migrazioak beharrezkoa denean `src/Middleware/Middlewares.php` sortzen du eta migrazio-egoera erregistratzen du.

---

# 19. Aurreko bertsioekiko bateragarritasuna

9.9.0k nahita kentzen du Filter runtime arkitektura.

Adapter automatikoek eguneratze-bide bat eskaintzen dute onartutako legacy proiektuentzat, baina 9.9ko kode berriak Middlewareak erabili behar ditu.

Ez gehitu Filter berririk migrazioaren ondoren.
