diff --git a/docs/README.md b/docs/README.md index 551614c..aa3434c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -14,30 +14,30 @@ atingi zona X, citeste fisierul Y"). Restul se deschid doar la declansator. | `reguli_lucru.md` | intotdeauna, la inceput de sesiune | | `orchestrare-subagenti.md` | cand delegi, cand verifici ce intoarce un subagent, la predarea contextului | | `monitorizare-context.md` | instalarea hook-urilor de prag de context si de revizie a docs | -| `fluxul_svn_git.md` | orice commit / `svn update` / `roa_sync`; ce e interzis pe `main` in COMUN | +| `fluxul_svn_git.md` | orice commit / `svn update` / `roa_sync` -> skill `roa-git-svn-commit` | | `scripturi-uzuale.md` | exista deja un script pentru sarcina asta? (roa_sync, curatenie, livrare, diagnostice) | | **VFP** | | -| `cautare_vcx_vct.md` | cauti cod in `.vcx`/`.scx`/`.frx`/`.mnx` | -| `flux-editare-vfp-text.md` | editezi `.vc2`/`.sc2` + write-back; **invariantele si `*p:`/`*m:`** | -| `conventie_encoding_cp1252.md` | fisierul editat are diacritice (cp1250, nu cp1252) | +| `cautare_vcx_vct.md` | cauti cod in `.vcx`/`.scx`/`.frx`/`.mnx` -> skill `roa-vfp-text-edit` | +| `flux-editare-vfp-text.md` | editezi `.vc2`/`.sc2` + write-back; invariantele si `*p:`/`*m:` -> skill `roa-vfp-text-edit` | +| `conventie_encoding_cp1252.md` | fisierul editat are diacritice (cp1250, nu cp1252) -> skill `roa-vfp-text-edit` | | `inventar-comun.md` | inainte de cod nou: exista deja o functie/clasa comuna? | | `conventie_ux_formulare.md` | adaugi/rearanjezi controale pe formular | | `capcana_grid_controlsource.md` | grid needitabil pe formular cu 2+ grid-uri | | `capcana_grid_preferinte_utilizator.md` | adaugi o coloana intr-un grid deja livrat | -| `conventie_go_recno.md` | `GO` pe un `Recno()` capturat | -| `conventie_null_vfp.md` | garzi pe valori NULL din Oracle | +| `conventie_go_recno.md` | `GO` pe un `Recno()` capturat -> skill `roa-vfp-go-recno` | +| `conventie_null_vfp.md` | garzi pe valori NULL din Oracle -> skill `roa-vfp-null-guards` | | `conventie_goexecutor_alter_table.md` | `ALTER TABLE` pe cursorul de la `oExecute()` | | **Testare** | | -| `depanare_testare_vfp.md` | rulare headless, depanare bug runtime, capcane VFP | -| `testare-ui-vfp.md` | test cu formular real + screenshots (harness UI) | +| `depanare_testare_vfp.md` | rulare headless, depanare bug runtime, capcane VFP -> skill `roa-vfp-headless-test` | +| `testare-ui-vfp.md` | test cu formular real + screenshots (harness UI) -> skill `roa-vfp-headless-test` | | **Oracle** | | | `conventie_mediu_oracle.md` | te conectezi la dev/test, alegi schema, rulezi un script de pachet | -| `conexiuni-tunel-ssh-odbc.md` | ajungi la un Oracle de PRODUCTIE prin tunel SSH (Bitvise) + alias TNS + DSN ODBC | -| `scripturi-migrare-db.md` | modifici schema (tabele/view-uri/pachete); compatibilitate 10.2 | -| `publicare-scripturi-db.md` | publici scripturile catre clienti | -| `oracle_export.md` | reexporti sursa unui pachet PL/SQL | -| `depanare-pack-update.md` | actualizarea ROA nu se finalizeaza la un client | -| `depanare-spatiu-oracle.md` | spatiu plin la un client | +| `conexiuni-tunel-ssh-odbc.md` | ajungi la un Oracle de PRODUCTIE prin tunel SSH (Bitvise) + alias TNS + DSN ODBC -> skill `roa-oracle-production-access` | +| `scripturi-migrare-db.md` | modifici schema (tabele/view-uri/pachete); compatibilitate 10.2 -> skill `roa-oracle-migration` | +| `publicare-scripturi-db.md` | publici scripturile catre clienti -> skill `roa-oracle-migration` | +| `oracle_export.md` | reexporti sursa unui pachet PL/SQL -> skill `roa-oracle-migration` | +| `depanare-pack-update.md` | actualizarea ROA nu se finalizeaza la un client -> skill `roa-oracle-diagnostic` | +| `depanare-spatiu-oracle.md` | spatiu plin la un client -> skill `roa-oracle-diagnostic` | | **Domeniu** | | | `flux-modificare-stergere-nota-jurnal.md` | modificare/stergere nota; ce face `PACK_CONTAFIN` | | `tipuri_documente_facturare.md` | `VANZARI.TIP` si seturile de contare `ID_SET` | diff --git a/docs/cercetare/rec_skills.md b/docs/cercetare/rec_skills.md new file mode 100644 index 0000000..ff74c99 --- /dev/null +++ b/docs/cercetare/rec_skills.md @@ -0,0 +1,59 @@ +# rec_skills - skill-uri de agent pentru suita ROA + +Data: 2026-09-16. Status: aplicat (9 skill-uri create, rutare + backstop puse in docs). + +## Decizie + +- Skill-ul este **proprietarul procedurii**; docurile din `COMUN\docs` raman **referinta + conditionata**, deschisa doar cand o ramura cere detaliu. Motiv: sa nu se incarce contextul de + doua ori si sa nu existe doi proprietari pentru aceeasi regula. (Suprapunerea masurata inainte + de unificare: 18-42% din liniile corpului unui skill erau identice cu linii din docuri.) +- Fiecare SKILL.md: frontmatter doar `name` + `description` (comun ambelor host-uri), corp + auto-suficient cu secventele `Cand se foloseste / Pasi (sau Regula) / Capcane / Criterii de + acceptare si dovada / Scripturi / Referinta (doar la nevoie)`, cel mult 1 pointer conditio nat la + un doc. +- Skill-urile traiesc in `COMUN\skills\\SKILL.md`, versionate in `comun.git`. +- Sunt expuse host-urilor prin symlink in `%USERPROFILE%\.claude\skills\` - director citit si de + Claude Code, si de opencode - fara copiere: `COMUN\utile\leaga_skills.ps1` (idempotent, `-DryRun`). +- Declansarea automata vine din `description` (ambele host-uri); "de fiecare data" vine din + **backstop-ul always-on**: `reguli_lucru.md` pct. 7 (citit la fiecare sesiune) + `AGENTS.md` + (pentru opencode, care nu citeste `CLAUDE.md`) + ancora in `CLAUDE.md`. + +## Inventar + +| Skill | Deschide cand (zonele) | +|---|---| +| `roa-vfp-text-edit` | editare `.vcx/.scx` pe text (`.vc2/.sc2`), cautare in binare, encoding cp1250, write-back | +| `roa-vfp-headless-test` | rulare/depanare teste VFP headless, harness UI + screenshots | +| `roa-git-svn-commit` | commit / `svn update` / `roa_sync` in COMUN | +| `roa-oracle-migration` | scriere + publicare scripturi de migrare, re-export pachet PL/SQL | +| `roa-oracle-diagnostic` | update ROA blocat la client, tablespace/disc plin | +| `roa-oracle-production-access` | acces Oracle de productie (tunel SSH + TNS + DSN ODBC) | +| `roa-vfp-null-guards` | garzi pe valori NULL din Oracle in VFP | +| `roa-vfp-go-recno` | `GO` pe un `Recno()` capturat sau primit ca parametru | +| `roa-oracle-sqlexec-no-data` | procedura PL/SQL cu `SELECT ... INTO` apelata din VFP (randuri pierdute tacut) | + +## Cum se adauga un skill nou + +1. Creezi `COMUN\skills\\SKILL.md` (contractul de mai sus; `name` = numele folderului, + lowercase-cu-cratima). +2. Rulezi `COMUN\utile\leaga_skills.ps1` (creeaza symlink-ul in `%USERPROFILE%\.claude\skills\`). +3. Adaugi o linie de rutare in `reguli_lucru.md` pct. 7 si in `AGENTS.md` (`README.md` pentru + index). Nu duplici regula din docs: skill-ul o detine. +4. Verifici cu cele doua asertiuni: (a) nicio linie din `CLAUDE.md`/`AGENTS.md`/`reguli_lucru.md`/ + `README.md` nu ruteaza o zona acoperita catre un doc; (b) fiecare skill are cel mult 1 pointer + conditio nat la un doc. + +## Verificari la data aplicarii + +- 9/9 skill-uri: ASCII pur, fara BOM, `name` = folder, descriere <= 1024, exact 1 bullet sub + `## Referinta (doar la nevoie)`. +- 0 rute reziduale zona -> doc in `CLAUDE.md`, `AGENTS.md`, `reguli_lucru.md`, `README.md`. +- `leaga_skills.ps1`: 4 create apoi idempotent (0 create, 9 ok); director real cu acelasi nume + niciodata sters (nici cu `-Force`). + +## Neaplicat / de facut manual + +- Commit: git pe branch (`claude/...`), fara push; `svn commit` + `roa_sync` + merge raman la + Marius (fluxul SVN+git din `fluxul_svn_git.md`). +- Pe celelalte calculatoare: `git pull` in `COMUN\` + `leaga_skills.ps1` (o data). diff --git a/docs/reguli_lucru.md b/docs/reguli_lucru.md index 62e5d0f..0850133 100644 --- a/docs/reguli_lucru.md +++ b/docs/reguli_lucru.md @@ -96,7 +96,7 @@ garda fara caz in datele de test nu e garda moarta (regula 6); `/ponytail-audit` pe tot arborele nu se ruleaza aici. 4. Testare headless (fara IDE): `vfp9.exe -A -T "" ` din PowerShell. - Mediu, sabloane, capcane, depanare: `depanare_testare_vfp.md`. + Mediu, sabloane, capcane, depanare: skill roa-vfp-headless-test (headless si UI; criteriile lui blocheaza "gata"). Rularile intermediare acopera doar familiile de teste atinse de modificarea curenta; suita completa, inclusiv testele de garda pe zonele vecine, se ruleaza doar la rularea finala — garzile exista fiindca schimbarile cad de regula in cod partajat (`COMUN`), vizibil in toate @@ -107,41 +107,32 @@ **0,5s** intre teste, nu implicitul de 12 minute / 3s, rezervat rularii finale unde chiar conteaza sa distingi "atarnat" de "lent". Tinta: o rulare intermediara sta in secunde-minute, nu ore — daca depaseste, lista e prea larga sau timeout-ul prea mare. -5. Editare .vcx/.scx pe text (cache, cp1250 byte-safe, fidelity-check): `flux-editare-vfp-text.md`. - Cautare in binare: `cautare_vcx_vct.md`. Versiunile `.??2` sunt instantanee, pot fi mai vechi - decat binarul — verifica mtime inainte de concluzii; continutul real e in `.PJX`. +5. Editare `.vcx`/`.scx` pe text, cautare in binare: skill roa-vfp-text-edit (cache, cp1250 + byte-safe, fidelity-check si membrii noi sunt in procedura lui). Versiunile `.??2` sunt + instantanee, pot fi mai vechi decat binarul - verifica mtime inainte de concluzii; continutul + real e in `.PJX`. 6. Delegare: implementarile, testele, verificarile si cercetarile se dau unor subagenti Sonnet in background (lane-uri paralele); sesiunea principala doar orchestreaza si verifica, ca sa nu i se umple contextul. Misiuni lungi: subagenti proaspeti per sarcina (max ~200-250k tokens/subagent), nu unul singur cu context acumulat; handoff compact pe disc. Verificarea a ce se intoarce si modelul de lucru (backlog de story-uri mici): `orchestrare-subagenti.md`. 7. Conventii obligatorii, de citit cand atingi zona respectiva: - - editezi `.vc2`/`.sc2` sau `.prg` cu diacritice (ex. `programe\ocautare.prg`, unde `s`-urile cu - virgula din `masina`/`si contul`/`transa` sunt octetul `0xBA`) -> fisierele sunt **cp1250** - desi antetul FoxBin2Prg declara `CPID="1252"`; Edit/Write corup TOT fisierul (nu doar linia - atinsa), ireversibil, la fiecare scriere - scrie continut nou strict ASCII. Cens obligatoriu - **inainte SI dupa** fiecare editare (la stricare CRESTE, nu scade): - `od -An -tx1 | tr ' ' '\n' | grep -v '^$' | awk '$1>"7f"' | sort | uniq -c`. Tabelul - complet de octeti, sensul censului la stricare si procedura de recuperare din git/svn -> - `conventie_encoding_cp1252.md`; - - adaugi o PROPRIETATE sau o METODA noua intr-o clasa `.vc2`/`.sc2` -> `flux-editare-vfp-text.md`, - sectiunea "Membri noi de clasa": fara intrarea `*p:`/`*m:` in `*` - membrul trece fidelity-check-ul, dar VFP nu-l vede si prima salvare din IDE il sterge tacut; + - editezi `.vc2`/`.sc2` sau `.prg` cu diacritice -> skill roa-vfp-text-edit (el detine procedura; criteriile lui blocheaza "gata"); + - adaugi o PROPRIETATE sau o METODA noua intr-o clasa `.vc2`/`.sc2` -> skill roa-vfp-text-edit (membrul nou si `*p:`/`*m:` sunt in procedura lui; criteriile lui blocheaza "gata"); - adaugi/rearanjezi controale pe formulare sau coloane in grid -> `conventie_ux_formulare.md`; - grid needitabil pe formular cu 2+ grid-uri -> `capcana_grid_controlsource.md`; - adaugi o coloana intr-un grid deja livrat (ordinea din clasa e neutralizata de preferintele salvate per utilizator) -> `capcana_grid_preferinte_utilizator.md`; - - `GO` pe un `Recno()` capturat/primit ca parametru -> `conventie_go_recno.md`; + - `GO` pe un `Recno()` capturat/primit ca parametru -> skill roa-vfp-go-recno (el detine procedura; criteriile lui blocheaza "gata"); - `ALTER TABLE` pe cursorul intors de `goExecutor.oExecute()` -> `conventie_goexecutor_alter_table.md`; - - testare UI -> `testare-ui-vfp.md`; + - testare UI -> skill roa-vfp-headless-test (acopera si testul headless; criteriile lui blocheaza "gata"); - te conectezi la Oracle pe dev/test, alegi schema sau rulezi un script de pachet -> `conventie_mediu_oracle.md`; - - garzi pe valori NULL din Oracle -> `conventie_null_vfp.md`; - - procedura PL/SQL cu `SELECT ... INTO` chemata din VFP (linii pierdute tacut) -> - `capcana_sqlexec_no_data_found.md`; - - export date din Oracle -> `oracle_export.md`; - - actualizarea ROA nu se finalizeaza (job update, PACK_UPDATE) -> `depanare-pack-update.md`; - - modifici schema Oracle (tabele/view-uri/pachete) -> `scripturi-migrare-db.md`. + - garzi pe valori NULL din Oracle -> skill roa-vfp-null-guards (el detine procedura; criteriile lui blocheaza "gata"); + - procedura PL/SQL cu `SELECT ... INTO` chemata din VFP (linii pierdute tacut) -> skill roa-oracle-sqlexec-no-data (el detine procedura; criteriile lui blocheaza "gata"); + - export date din Oracle -> skill roa-oracle-migration (reexportul sursei de pachet e in procedura lui; criteriile lui blocheaza "gata"); + - actualizarea ROA nu se finalizeaza (job update, PACK_UPDATE) -> skill roa-oracle-diagnostic (acopera si spatiul plin; criteriile lui blocheaza "gata"); + - modifici schema Oracle (tabele/view-uri/pachete) -> skill roa-oracle-migration (scriere + publicare scripturi; criteriile lui blocheaza "gata"). 8. Eroare raportata de utilizator: nu analiza statica indelungata — scrie intai un test care o reproduce pe fluxul real; el da cauza si confirma remedierea. Analiza statica doar cat sa stii ce sa pui in test. diff --git a/skills/roa-git-svn-commit/SKILL.md b/skills/roa-git-svn-commit/SKILL.md new file mode 100644 index 0000000..0ec40bc --- /dev/null +++ b/skills/roa-git-svn-commit/SKILL.md @@ -0,0 +1,100 @@ +--- +name: roa-git-svn-commit +description: Fluxul de commit si sincronizare pentru biblioteca partajata COMUN (SVN = sursa de adevar, git = oglinda), cu arbore de decizie pentru roa_sync, write-back, aprobare explicita si svn commit tintit, ca sa nu pierzi munca necomisa. Foloseste-l OBLIGATORIU cand utilizatorul spune "am terminat, dau commit", "vreau sa comit in COMUN", "comit ce am lucrat", "sincronizeaza cu SVN", "adu ce au facut altii", "ruleaza roa_sync", "de ce nu merge git pull in COMUN" sau cere orice commit/sincronizare care atinge COMUN. Regula centrala: pe main din COMUN scrie DOAR roa_sync, commit-urile se fac tintit pe fisierele aprobate (niciodata pe tot COMUN), iar git pull in COMUN este interzis. Nu improviza ordinea pasilor si nu rula roa_sync pe un tree murdar: distruge munca necomisa. +--- + +# Commit si sincronizare in COMUN (SVN + git) + +SVN = sursa de adevar. git = oglinda. Pe `main` din COMUN scrie **doar** `roa_sync`. Comenzile le +rulezi tu; utilizatorul doar aproba - dar nimic nu se comite fara un "da" explicit de la el. + +## Cand se foloseste + +- "am terminat, dau commit", "vreau sa comit in COMUN", "comit ce am lucrat"; +- "sincronizeaza cu SVN", "adu ce au facut altii", "ruleaza roa_sync", "de ce am conflicte"; +- intrarea intr-o sesiune de lucru in proiect (sync de inceput). + +Nu se aplica altui repo decat COMUN + proiectul care il contine. Pentru editarea codului VFP +(`.vcx`/`.scx` prin `.vc2`/`.sc2`) vezi skill-ul `roa-vfp-text-edit`. + +## Pasi + +Arbore de decizie - opreste-te la primul caz care se potriveste. + +1. **Intri in proiect** -> rulezi `roa_sync.bat`, fara sa intrebi, DOAR daca `svn status` si + `git status` sunt curate. Daca nu sunt, intrebi intai (pot fi modificari nefinalizate ale + altcuiva). +2. **Ai editat `.prg` / `.md` / `.ps1` / `.sql`** (proiect sau COMUN) -> antetul la zi, testul + rulat, diff-ul scris ca fisier in `docs\`. +3. **Ai editat `.vc2` / `.sc2`** -> `txt2vcx.ps1` IMEDIAT, apoi verifici pe binar (reconversie + intr-un cache temporar + comparatie; mtime nu dovedeste nimic). Text fara write-back = + modificarea nu exista. Abia apoi antet / test / diff. +4. **Ceri aprobarea, explicit si complet**: lista fisierelor de comis + mesajul propus. Nu + presupune "da" din tacere si nu amana pentru "mai tarziu" - el nu tine minte pasul, tu il tii. +5. **A zis "da"** -> rulezi tu `svn commit` **tintit**, doar fisierele aprobate: `.prg` sau + `.scx` + `.sct`, niciodata `.sc2`. Niciodata tot COMUN (intra zgomotul de compilare VFP). +6. **Imediat dupa** -> `roa_sync.bat`. Raportezi revizia SVN si ce a intrat pe `main`. +7. **A zis "nu" / cere modificari** -> nu comiti, nu insisti, nu rulezi `roa_sync`. Lucrarea + ramane necomisa pe disc si o raportezi asa la predarea contextului. + +### Cazuri + +- **Vrei sa-ti tii munca in git** -> branch. In repo-ul proiectului: liber. In COMUN: + `claude/`, commit doar acolo, niciodata pe `main`. +- **Ai terminat branch-ul** -> proiect: merge in `main`, normal. COMUN: **fara merge**; dupa + `svn commit` continutul ajunge pe `main` ca `sync SVN rN`, iar branch-ul se sterge (doar daca + `git diff main..branch` e gol). +- **Esti pe branch in COMUN si te bate gandul la `roa_sync`** -> nu. `roa_sync` se ruleaza in + exact doua momente: la intrarea in proiect si imediat dupa `svn commit`. Pe branch cu tree + curat face `checkout main` fara sa intrebe (binarele raman de pe branch); pe branch murdar + sare peste, dar `svn update` de la pasul 1 ruleaza oricum si poate aduce binare peste ce ai + pe disc. +- **Vrei `svn update`** -> doar din stare curata, niciodata in mijlocul lucrului. Daca ai text + `.??2` editat fara write-back, fa intai write-back-ul. +- **`svn update` a dat conflict** -> opreste-te si raporteaza; binarele nu se rezolva manual. +- **Dupa `svn update` git arata fisiere modificate** -> e oglinda ramasa in urma, nu munca ta; + nu le comite de mana, le ia `roa_sync` intr-un `sync SVN rN`. +- **Vrei sa aduci ce au facut altii** -> `roa_sync.bat`. **Niciodata `git pull`**: git poarta + doar textele, nu binarele; un pull da `.sc2` nou peste `.scx/.sct` vechi, VFP compileaza + binarul, iar urmatorul `git_sync` sterge modificarea. +- **Copie de COMUN ramasa in urma** -> se aliniaza singura la primul `roa_sync.bat` rulat acolo. +- **Predai contextul** -> raporteaza explicit daca ai lasat text `.??2` editat fara write-back + (stare periculoasa). + +## Interzis + +- `git commit` / `git push` / `git merge` pe `main` in COMUN. +- `git pull` in COMUN - aduce textele fara binare; se foloseste `roa_sync.bat`. +- `git commit` pe tot COMUN sau pe `.sc2` - doar tintit, pe fisierele aprobate. +- Copierea unui fisier dintr-o copie de COMUN in alta - `svn update` il duce; copierea = + intrare dubla. +- Write-back pe `.fr2` / `.mn2` / `.lb2` / `.pj2` - nesuportat; acolo se modifica in IDE. +- Commit fara un "da" explicit de la utilizator. + +## Criterii de acceptare si dovada + +Fara dovada da/nu de mai jos, commit-ul/sincronizarea NU se raporteaza ca terminata. "Arata +bine" nu e dovada. + +1. Inainte de commit: `git status --porcelain` contine EXACT fisierele aprobate; nimic + neasteptat stagiat. +2. Dupa `svn commit`: `svn status` curat pe fisierele tintite, iar revizia SVN este raportata. +3. Dupa commit: `roa_sync.bat` a rulat si raporteaza succes (exit 0, commit `sync SVN rN` pe + `main` in COMUN, fara avertismente de conflict). +4. `git status` curat pe fisierele tintite in COMUN; branch-urile `claude/*` terminate sunt + inchise, cele active raportate. +5. Verificarea se face inainte de `svn commit`: fara "da" explicit, commit-ul nu are loc + (skill-ul nu comite din proprie initiativa). +6. Daca utilizatorul a zis "nu": dovada e absenta oricarei urme de commit sau sync in log. + +## Scripturi + +- `D:\ROA\ROAFACTURARE\roa_sync.bat` (sau `roa_sync.bat` din radacina proiectului). +- `D:\ROA\ROAFACTURARE\COMUN\scripts\roa_sync.ps1` - `-ProjectRoot `, iar `-GitOnly` + sare peste SVN si regenerarea textelor. +- `D:\ROA\UTIL\foxbin2prg\txt2vcx.ps1` si `git_sync.ps1` - doar daca ai atins binare. + +## Referinta (doar la nevoie) + +- Doar daca ai nevoie de contextul complet, citeste `COMUN\docs\fluxul_svn_git.md` + (cazuri, interdictii) pentru fluxul SVN + git. diff --git a/skills/roa-oracle-diagnostic/SKILL.md b/skills/roa-oracle-diagnostic/SKILL.md new file mode 100644 index 0000000..163b6a4 --- /dev/null +++ b/skills/roa-oracle-diagnostic/SKILL.md @@ -0,0 +1,92 @@ +--- +name: roa-oracle-diagnostic +description: Diagnostic read-only pentru doua incidente de productie la clientii ROA - actualizarea automata (PACK_UPDATE) care nu se termina si tablespace-ul/discul Oracle plin. Foloseste-l OBLIGATORIU cand utilizatorul spune "actualizarea nu se termina la clientul X", "a ramas blocat la pasul 3", "update-ul nu a mers azi", "verifica de ce n-a mers update-ul", "clientul are baza plina", "spatiu insuficient la client", "ORA-01653", "ORA-01654", "nu mai pot salva in baza", "tablespace plin" sau cere sa verifici de ce a esuat o actualizare. Ruleaza intai scriptul de diagnostic dedicat, citeste dovada exacta (starea rularii, scriptul candidat, consumatorul de spatiu, procentul tablespace-ului) si abia apoi da verdictul. Nu improviza interogari manuale, nu relansa update-ul si nu rula curatare pana nu stii pasul exact unde s-a oprit. +--- + +# Diagnostic ROA: actualizare blocata si spatiu Oracle plin + +Doua incidente, acelasi tipar: simptomul din aplicatie nu spune cauza. Fie actualizarea nu se +termina (`stare=3` fara `dataora_end`, log mut), fie baza/discul e plin (`ORA-01653`/`ORA-01654`, +blocaj brusc). Diagnostic STRICT read-only: se identifica pasul/consumatorul exact si se propune deblocarea. + +## Cand se foloseste + +- "actualizarea nu se termina la clientul X", "a ramas la pasul 3", "update-ul nu a mers azi"; +- "verifica de ce n-a mers actualizarea", "de ce nu s-a actualizat baza la client"; +- "clientul are baza plina", "spatiu insuficient", "ORA-01653", "ORA-01654", "ORA-00257"; +- orice cerere de a verifica o actualizare esuata sau un tablespace/disk plin la un client; nu + improviza interogari si nu relansa update-ul inainte de verdictul scriptului. + +## Pasi + +Ambele: intai conexiunea (tunel SSH pe 1521 + alias TNS pe `127.0.0.1` in +`D:\ROA\instantclient_19_18\tnsnames.ora`, user `contafin_oracle`), apoi scriptul dedicat. + +A. Actualizarea nu se termina (job `UPDATEROA_ZILNIC` -> `PACK_UPDATE.UpdateROA`): +1. Ruleaza `diag_actualizare.ps1 -Alias ` si citeste verdictul: pana unde a ajuns si unde e + eroarea. Lantul e secvential, o etapa picata le opreste pe toate: UpdateApp -> UpdateScripts -> + UpdateDatabaseSqlPlus. +2. `UPD_ISTORIC`: `stare` (0=start, 1=aplicatii, 2=scripturi, 3=aplicare, 4=incheiat) si + `dataora_end` gol = neincheiata; un sir oprit la aceeasi `stare` arata etapa vinovata. +3. `UPD_LOG`: `dataora_start` = rularea, `secventa`+`dataora` = ordinea, `explicatie` (CLOB) = + cauza reala. Se goleste la fiecare rulare - iei logul curent sau relansezi ca sa-l reproduce. +4. Versiuni: `UPD_DATABASE.script_date` vs `.VERSIUNE.data_script`. La `stare=3` fara + `dataora_end` cu `VERSIUNE` blocat, candidatul e primul script `UPD_DATABASE` neaplicat. +5. `script_master.log` in `DMPDIR` (`C:\DMPDIR`) pe server = mesajul real al aplicarii. Eroarea + de aici NU ajunge in `UPD_LOG`; se citeste si prin `UTL_FILE` fara RDP (util e la sfarsit). +6. Descarcare: daca etapa 1 a picat, verifica intai folderul Oracle `UPD_` pe disc + (`dbms_lob.fileexists(bfilename(...))`) si `all_directories like 'UPD%'`, nu reteaua. +7. `GetStare` refuza o rulare noua cat timp precedenta e neincheiata si n-a trecut o ora. + Deblocarea e doar sugestie - nu o executa fara acordul explicit. + +B. Spatiu Oracle plin: +1. Ruleaza `diag_spatiu.ps1 -Alias -Disc` (cu `-Disc` doar pe servere Windows) si citeste + verdictul plus topul segmentelor. +2. Tablespace + datafile: ce e plin, `maxbytes` vs `bytes`, cat mai poate creste. Un `maxbytes` + sub XE 11/12 GB nu e limita XE - e plafon pus la instalare. +3. Top consumatori: tablespace cu `maxbytes` atins, `SYSAUX` (SQL Tuning Sets/AWR/audit), fisiere + `.aud` din `adump` (NU se vad din SQL, doar cu `-Disc`), alert log/trace/ADR, FRA plina cu + `ARCHIVELOG` (`ORA-00257`/`ORA-19809`), recyclebin/UNDO/TEMP, logurile aplicatiei care cresc. +4. Daca eroarea de actualizare nu priveste obiectele atinse de script, suspecteaza intai spatiul + (ex. `ORA-01653 table SYS.INFO in tablespace SYSTEM`, ridicata din `SYS.PINFO`). + +Cand A si B se intersecteaza, verdictul leaga scriptul candidat de tablespace-ul plin. + +## Capcane + +- `UPD_LOG` se goleste la fiecare rulare - nu ai istoric; altfel relansezi orbeste. +- Eroarea din `additional_info`-ul jobului e de obicei falsa: `EmailLog` ridica `ORA-20000` (SMTP + picat) si mascheaza eroarea originala. Cauza adevarata e in `UPD_LOG`. +- UpdateApp abandoneaza TOT la primul program nedescarcat (`CT_INSUCCES`): un fisier indisponibil + blocheaza la infinit, tacut (`Fisierul NU s-a salvat pe disc.`). Verifica folderul, nu reteaua. +- Ordinea de citit cand actualizarea e muta: `UPD_ISTORIC` -> `UPD_LOG` -> `script_master.log`; + daca sari direct la logul de SQL, nu stii pe ce schema si pe ce rulare te uiti. +- Erorile de script fac `UPD_LOG` curat (`WHENEVER SQLERROR EXIT ... ROLLBACK`); semnul e + `stare=3` fara `dataora_end` + `VERSIUNE` blocat. Mesajul real e doar in `script_master.log`. +- `adrci purge` si `alter database datafile ... autoextend` sunt DOAR sugestii afisate; nu le rula + automat si niciodata fara acordul explicit al utilizatorului. +- La clienti Oracle 10g lipsesc coloane din `dba_scheduler_*` - foloseste `dba_scheduler_job_run_details`. +- `-Disc` scrie un `.ps1` temporar in `DMPDIR`; pe Linux expira dupa 60s cu mesaj. + +## Criterii de acceptare si dovada + +Fara dovezile de mai jos nu exista verdict; diagnosticul NU se raporteaza ca terminat. + +1. Verdictul scriptului e citat. Ramura A: `stare` + `dataora_end` din `UPD_ISTORIC` si linia + exacta din `UPD_LOG`/`script_master.log`. Ramura B: procentul tablespace-ului vinovat + `maxbytes`. +2. Scriptul candidat e numit exact (primul din `UPD_DATABASE` de dupa ultima versiune), nu + "undeva in etapa 3". +3. Dovada e legata de obiectele reale: daca mesajul Oracle nu priveste ce atinge scriptul, s-a + dovedit spatiul (procent + plafon), nu scriptul. +4. Deblocarea propusa e scrisa ca sugestie cu comanda exacta, neexecutata. + +## Scripturi + +- `D:\ROA\ROAFACTURARE\COMUN\utile\diag_actualizare.ps1` + `powershell -File D:\ROA\ROAFACTURARE\COMUN\utile\diag_actualizare.ps1 -Alias [-DoarLog] [-Disc]` +- `D:\ROA\ROAFACTURARE\COMUN\utile\diag_spatiu.ps1` + `powershell -File D:\ROA\ROAFACTURARE\COMUN\utile\diag_spatiu.ps1 -Alias [-Disc] [-SysPassword ] [-Top 30]` + +## Referinta (doar la nevoie) + +- Doar daca ramura A (actualizare) sau ramura B (spatiu) cere detalii, citeste `COMUN\docs\depanare-pack-update.md` si `COMUN\docs\depanare-spatiu-oracle.md`. diff --git a/skills/roa-oracle-migration/SKILL.md b/skills/roa-oracle-migration/SKILL.md new file mode 100644 index 0000000..5b63cd3 --- /dev/null +++ b/skills/roa-oracle-migration/SKILL.md @@ -0,0 +1,121 @@ +--- +name: roa-oracle-migration +description: Scrie si publica scripturi de migrare Oracle pentru suita ROA: script nou de schema (tabela, view, procedura, functie, pachet), coloana noua, numerotare YYYY_MM_DD_NN, incheiere cu UpdateVersiune + commit, import in UPD_DATABASE si arhiva lunara catre clienti, plus re-exportul sursei unui pachet PL/SQL. Foloseste skill-ul cand auzi "scrie un script de migrare pentru...", "publica scripturile catre clienti", "am nevoie de o coloana noua pe...", "exporta sursa pachetului Y", "modific un pachet", "adaug o optiune de meniu", "rulez scripturile la client". Acopera exact capcanele care nu dau nicio eroare: o instructiune fara `;` e aruncata tacut de SQL*Plus, un NN refolosit colizioneaza intre prefixe, iar o constructie 11g+ pica doar la clientul pe Oracle 10.2. Cere compatibilitate 10.2, idempotenta si sursa de referinta MARIUSM_AUTO. +--- + +# roa-oracle-migration + +Scrie scripturi de migrare Oracle si publica-le catre clienti. Detalii de context: vezi Referinta, doar cand ramura o cere. + +## Cand se foloseste + +- schimbi schema: tabela, view, procedura, functie sau pachet; +- iti trebuie o coloana noua / index / constrangere pe un obiect existent; +- scrii un script nou in `D:\ROA\DATABASE\SCRIPTURI_CLAR`; +- adaugi o optiune de meniu sau un drept (`co_..._OBIECTE.sql`); +- publici scripturile catre clienti (import in `UPD_DATABASE` + arhiva lunara); +- re-exporti sursa unui pachet PL/SQL sau citesti un corp de pachet (`oracle_export.md`). + +Un agent **scrie** scriptul, nu il aplica. Rularea pe o schema se face doar la cererea explicita +a lui Marius. + +## Pasi + +1. Confirma ca sursa de referinta `MARIUSM_AUTO` (pe `ROA_CENTRAL`) e la zi: compara scripturile + din `SCRIPTURI_CLAR` cu inregistrarile din `VERSIUNE`. Daca lipseste vreunul, opreste-te si + semnaleaza-i lui Marius. Nu porni de la sursa citita dintr-o schema de client. +2. Alege numele `_YYYY_MM_DD_NN_.sql`. Prefixe in uz: `ff`, `co`, `sys`, `ris`, + `rf`. `NN` e o secventa **unica pe zi, comuna tuturor prefixelor**. +3. Scrie scriptul ASCII, CRLF, **scoped** pe cazul tratat si **idempotent** (`merge`, + `where is null`). Un pachet sta singur in scriptul lui, fara alt DDL/DML alaturi. +4. Termina **fiecare instructiune** explicit cu `;` (sau `/` pentru blocurile PL/SQL). +5. Scrie la nivel **Oracle 10.2** - numitorul comun al parcului de clienti. Proba se face pe + serverul cel mai vechi (ROMCONSTRUCT), nu pe dev. +6. Incheie scriptul cu: + + ```sql + exec pack_migrare.UpdateVersiune(''); + commit; + ``` + + Numele se da **fara** `.sql` (extensia o adauga `UpdateVersiune`). `UpdateVersiune` e DML: + fara `commit` explicit, versiunea nu se inregistreaza si `VERSIUNE` minte. +7. Publica: intai `-DryRun`, apoi fara, conform `publicare-scripturi-db.md`: + + ```powershell + powershell -File D:\ROA\ROAFACTURARE\COMUN\utile\publicare_scripturi.ps1 -DryRun + powershell -File D:\ROA\ROAFACTURARE\COMUN\utile\publicare_scripturi.ps1 + ``` + + Publicarea = import al fiecarui `.sql` in `CONTAFIN_ORACLE.UPD_DATABASE` (pe `ROA_CENTRAL`) + **si** regenarea arhivei lunare in `Y:\ROAUPDATE\_UPDATE\`. Directorul e live. +8. Dupa publicare, strange dovezile din "Criterii de acceptare si dovada". + +## Capcane + +- **O instructiune fara `;` final e ARUNCATA fara nicio eroare.** Prima linie goala inchide + bufferul SQL*Plus; scriptul continua pana la `UpdateVersiune`, se marcheaza aplicat, iar + obiectul ramane cel vechi. `WHENEVER SQLERROR EXIT` nu prinde cazul. +- **`;` la capatul unei linii dintr-un comentariu `--` din interiorul unei instructiuni** + termina instructiunea acolo: restul `CREATE VIEW`-ului se interpreteaza linie cu linie + (`SP2-0734`, `ORA-00936` derutant). Pune `.` in loc de `;` in comentariu. Comentariile de + dinaintea instructiunii nu sunt afectate. +- **`NN` se colizioneaza intre prefixe**: acelasi numar nu se reia intr-un alt prefix in aceeasi + zi. Un script deja in `VERSIUNE` nu se reaplica; corectia se livreaza ca script nou, cu data + si `NN` noi - nu prin republicarea aceluiasi fisier. +- **Constructiile 11g+/12c+ trec pe dev dar pica la clientul 10.2** (`REGEXP_COUNT`, `CONTINUE`, + `LISTAGG`, `PIVOT`, `FETCH FIRST`, identificatori peste 30 de caractere...). Detalii in + `scripturi-migrare-db.md`. +- **Un obiect nu se poate referi la ceva creat de un script ulterior.** Daca un script creeaza + tabela si altul pachetul care o foloseste, tabela are `NN` mai mic. +- **LF in loc de CRLF** sparge parsarea pe client (`ALINES` pe `CHR(13)+CHR(10)`): tot fisierul + devine un rand. Publicarea refuza fisierele LF. +- **DDL neprefixat merge pe schema conexiunii.** Rularea manuala se face conectat pe schema + tinta (`CONTAFIN_ORACLE` pentru `co_`, schema firmei pentru `ff_`), niciodata pe un user de + lucru. `PACK_UPDATE` face singur `CONNECT` pe schema corecta. +- **`linesize` prea mic corupe tacut exportul**: SQL*Plus rupe liniile lungi, inclusiv prin + mijlocul unui identificator. Foloseste `linesize 32767`; exportul e pentru citit, nu baza + pentru un script de migrare. +- Niciodata `select` de raportare in script, `insert` fara `ID_OBIECT` explicit, sau `ID_GRUP` + fix (grupurile difera per client). + +## Criterii de acceptare si dovada + +Fara dovada nu se spune "gata". Ruleaza si pastreaza iesirea: + +- fisierul e **ASCII pur** (0 octeti > 127), fara BOM, cu **CRLF**; +- ultima linie a fiecarui `CREATE`/`ALTER`/`MERGE` se termina cu `;`; +- scriptul se termina cu `UpdateVersiune('')` urmat de `commit;`; +- `NN` e liber: nu exista rand in `VERSIUNE` si nici fisier cu acelasi `data||NN`; +- dupa aplicare, `select script_final from versiune where script_final = '.sql';` intoarce + randul si nu `..._.sql.sql`; +- `publicare_scripturi.ps1 -DryRun` listeaza scripturile fara sa scrie; arhiva generata se + citeste inapoi si se compara lungime + MD5 per fisier; +- importul compara CLOB-ul citit inapoi octet cu octet cu fisierul. + +Verificarea de ASCII + CRLF (trebuie sa intoarca `0` si `True`): + +```powershell +$b = [IO.File]::ReadAllBytes('D:\ROA\DATABASE\SCRIPTURI_CLAR\