Folderul docs\ era pana acum in afara oricarui control de versiuni - nici git, nici SVN - desi contine planurile pe puncte, proiectarile si rapoartele de cercetare pe care se sprijina modificarile din cod. O stergere acolo era definitiva. Fisierele intermediare (handoff-uri intre sesiuni, diff-uri deja aplicate) au fost sterse inainte, nu versionate: ce era durabil in ele a intrat in antetele fisierelor de test la care se refereau. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
17 KiB
Cercetare: coloane de audit pe VANZARI / VANZARI_DETALII (creare/modificare/stergere)
Status: COMPLET (read-only)
Intrebare
Marius cere pentru audit, pe documentele de facturare: data crearii, utilizatorul crearii, data modificarii si utilizatorul modificarii (daca e cazul), data stergerii si utilizatorul stergerii (daca e cazul).
1. Ce exista deja (structura DB)
Interogat direct all_tab_columns pe ROA_CENTRAL (schema live).
VANZARI — coloane relevante pentru audit:
| Coloana | Tip | Nullable | Rol |
|---|---|---|---|
ID_UTIL |
NUMBER | NOT NULL | utilizatorul crearii — completat la fiecare INSERT |
DATAORA |
DATE | NOT NULL | data/ora crearii — completat la fiecare INSERT |
STERS |
NUMBER | NOT NULL | flag sters (0/1) |
ID_UTILS |
NUMBER | NULL | utilizatorul care a sters — completat doar la stergere |
DATAORAS |
DATE | NULL | data/ora stergerii — completata doar la stergere |
DATA_ACT |
DATE | NULL | data contabila/de inregistrare (propaga in ACT, DOCUMENTE, JV2007, RUL), NU e "data modificarii" — vezi sectiunea 2 |
DATA_FACTURAT, ID_UTILFACT |
DATE / NUMBER | NULL | specifice actiunii "facturare din aviz", nu audit general pe document |
DATAORA_EXP |
DATE | NOT NULL | data expedierii/listarii, nu e audit de scriere |
DATAORA_DESCARCAT |
DATE | NULL | data descarcarii gestiunii, nu e audit de scriere |
DATA_SCAD |
DATE | NULL | data scadenta, nimic de audit |
Nu exista nicio coloana dedicata "utilizator modificare" / "data modificare" pe VANZARI
(gen ID_UTIL_MODIF / DATA_MODIF). DATA_ACT a fost verificata explicit in cod
(EXPORT:14439-14500, modifica_date_factura) si e o data contabila propagata in ACT/DOCUMENTE/
JV2007/RUL, nu un marcaj de audit "cine/cand a modificat".
Conventia casei (adaugat, verificat de sesiunea principala): VANZARI are deja tiparul o
pereche utilizator+data per eveniment: ID_UTIL/DATAORA (creare), ID_UTILS/DATAORAS
(stergere), ID_UTILFACT/DATA_FACTURAT (facturare din aviz — a treia pereche, omisa din
inventarul initial). Cu aceasta a treia pereche vizibila, tiparul e limpede: o pereche noua de
"modificare" (ID_UTIL_MODIF/DATA_MODIF sau echivalent) s-ar aseza natural langa celelalte trei,
ca nume si ca forma — nu ar fi o conventie noua, ci continuarea uneia deja existente.
VANZARI_DETALII — coloane relevante:
| Coloana | Tip | Nullable | Rol |
|---|---|---|---|
VALIDAT, ID_UTIL_VALID, DATAORA_VALID |
NUMBER/NUMBER/DATE | NULL pe ultimele doua | validare, alt concept decat creare |
STERS, ID_UTILS, DATAORAS |
NUMBER/NUMBER/DATE | NULL pe ultimele doua | stergere linie |
DATAORA_DESCARCAT |
DATE | NULL | descarcare gestiune |
Pe VANZARI_DETALII nu exista nicio coloana de "creare" (nici ID_UTIL, nici DATAORA proprii
liniei) — creatorul/data liniei se deduce indirect din antetul VANZARI al documentului parinte.
2. Cine scrie coloanele si cand
Creare (ID_UTIL, DATAORA pe VANZARI): scrise o singura data, la INSERT INTO VANZARI
din PACK_FACTURARE.scrie_in_vanzari (EXPORT:13598-13640), apelata pe drumul principal de emitere
(scrie_factura2, EXPORT:6020 -> lantul de finalizeaza_*). Valorile vin din
pack_facturare.nid_util si V_DATAORA — utilizatorul si momentul sesiunii curente la INSERT.
Exista un al doilea INSERT INTO VANZARI (EXPORT:14930, in finalizeaza_avize_lucrare,
EXPORT:14854-...) — ruta specifica avizelor de lucrare, tot cu ID_UTIL/DATAORA completate la
INSERT. Ambele rute de emitere completeaza consecvent aceste doua coloane — nu s-a gasit niciun
INSERT in VANZARI care sa le lase NULL.
Nu exista niciun UPDATE VANZARI SET ID_UTIL = ... sau SET DATAORA = ... in tot pachetul
(cautare directa, zero rezultate) — deci, in afara de INSERT-ul initial, aceste doua coloane nu sunt
niciodata rescrise pe randul existent. Coerent cu design-ul de azi: singura cale de "modificare" a
antetului identitar e modifica_date_factura (care NU atinge ID_UTIL/DATAORA, doar serie/numar/
data/scadenta/delegat/etc., vezi plan_13...md:796-801), sau stergere+reemitere ca document nou.
Stergere (ID_UTILS, DATAORAS, STERS): scrise consecvent in ambele proceduri de stergere:
sterge_factura(EXPORT:5432-5607):UPDATE VANZARI SET STERS = V_STERS, ID_UTILS = V_ID_UTIL, DATAORAS = V_DATAORA WHERE ID_VANZARE = ...(EXPORT:5496-5499) si acelasi tipar peVANZARI_DETALII(EXPORT:5560-5564), peCOMENZI_ELEMENTEsiCTR_RATE_FACTURIcand e cazul.sterge_proforma(EXPORT:5610-...): acelasi tipar (verificat header-ul procedurii; corpul complet urmeaza acelasi model deUPDATE ... SET STERS/ID_UTILS/DATAORAS).
Concluzie punct 2: coloanele existente sunt scrise consecvent pe toate rutele identificate —
nu exista ruta de creare care sa lase ID_UTIL/DATAORA NULL, nici ruta de stergere care sa sara
peste ID_UTILS/DATAORAS.
CORECTIE (verificata de sesiunea principala, nu de mine): afirmatia initiala "#6 nu atinge niciun
camp de audit" era gresita pentru VANZARI_DETALII. Pe partea de nota contabila
(pack_contafin.finalizeaza_modificare_nota, apelat din oscrie_in_fisiere) ramane adevarat ca se
realiniaza doar VANZARI.COD prin actualizeaza_vanzari
(COMUN\docs\flux-modificare-stergere-nota-jurnal.md:95), iar VANZARI.ID_FACT "nu e atins de
niciun pas al secventei" (:101-102) — dar editarea liniilor de factura din #6
(COMUN\programe\ofacturare_editare.prg) scrie id_utils/dataoras pe VANZARI_DETALII, in
trei locuri:
ofacturare_editare.prg:492-494— marcarea unei linii ca stearsa:sters = 1impreuna cuid_utils/dataoras. Aici folosirea corespunde exact semanticii "stergere".ofacturare_editare.prg:501-505—UPDATE vanzari_detalii SET sters = 0, cantitate = ..., pret = ..., id_utils = ..., dataoras = sysdate— perechea de "stergere" e scrisa odata custers = 0, deci pe un rand viu, nesters.ofacturare_editare.prg:522-525—INSERT INTO vanzari_detalii (..., id_utils, dataoras) VALUES (...)— perechea e populata pe un rand proaspat inserat, care nu a fost sters niciodata.
Concluzia corecta: in codul livrat al lui #6, perechea ID_UTILS/DATAORAS pe
VANZARI_DETALII e folosita ca marcaj "cine a umblat ultima data pe linia asta", nu strict ca
"sters de/la". Consecinta pentru orice raport de audit: ID_UTILS/DATAORAS NU pot fi citite
ca "sters de/la" fara sa se puna si STERS in conditie — altfel liniile adaugate sau modificate la
o editare (nesterse) apar gresit drept sterse. Pe VANZARI (antet), ramane adevarat ca #6 atinge
doar COD — nu s-a gasit nicio scriere pe ID_UTIL, DATAORA, DATA_ACT, ID_UTILS sau
DATAORAS la nivel de antet in acest flux.
3. Ce se intampla la regenerare (stergere + reemitere, #13 / S9)
Important: acest mecanism NU e inca implementat. Descrierea "stergere + reemitere" e planul
#13, sectiunea S9 (docs\plan_13_unificare_formular_facturare.md:3484-3568), marcata "PROIECTAT" /
"VERIFICAT ca e realizabila", nu cod livrat. Feature-ul aflat azi in lucru pe branch-ul curent (#6)
e alt mecanism (editare la nivel de linie de nota, sectiunea 2 mai sus), nu regenerare.
Raspuns la intrebarea critica: DA, se pierde, exact cum ai suspectat.
Mecanismul S9, asa cum e proiectat: documentul vechi primeste soft-delete (sterge_factura, ca
azi) -> ID_UTILS/DATAORAS ale randului vechi devin utilizatorul/momentul editarii (corect,
asta chiar e semantica lor). Documentul nou se scrie pe acelasi drum de emitere ca la creare
(scrie_factura2 -> scrie_in_vanzari -> INSERT INTO VANZARI, sectiunea 2 de mai sus) — acelasi
INSERT care completeaza ID_UTIL/DATAORA din utilizatorul si momentul curente. Niciun pas din
S9 nu citeste sau transporta ID_UTIL/DATAORA ale documentului vechi catre cel nou — cautare
directa in tot planul (ID_UTIL , DATAORA ) nu gaseste nicio mentiune a preservarii lor la
regenerare. Deci, cu proiectarea de azi a S9: "data crearii" a documentului reemis devine data
regenerarii, iar "utilizatorul crearii" devine cel care a declansat editarea — informatia despre
cine/cand a fost creat initial documentul se pierde tacut, exact temerea din brief.
Atenuare (verificata de sesiunea principala): pierderea nu e totala, ci reconstruibila din
lant, nu direct pe document. Randul vechi ramane in tabel cu STERS = 1 si cu ID_UTILS/
DATAORAS completate — iar acea stergere este momentul modificarii. Cum ID_FACT se pastreaza
peste regenerare (sectiunea E/S9 mai jos), un raport de audit poate urca lantul ID_FACT -> gasi
randul vechi sters -> citi DATAORA/ID_UTIL de pe acela ca fiind "data/utilizator crearii
originale". Asta atenueaza, dar nu inlocuieste o pereche explicita: cere parcurgerea lantului de
randuri sterse in loc de o citire directa pe documentul curent, si se rupe daca vreodata ID_FACT
nu mai e pastrat identic (de exemplu la o a doua regenerare, daca lantul nu ramane liniar).
Precedentul ID_FACT exista si e citat corect in brief, si arata ca problema e cunoscuta ca tipar
— dar rezolvata doar pentru ID_FACT, nu si generalizata la audit. Planul dedica un mecanism
explicit ca sa evite pierderea lui ID_FACT:
- Sectiunea E (
:762-789): cerinta explicita ("documentul reemis pastreazaID_FACT"), verificarea ca azi secventa l-ar regenera necondiționat, si decizia sa fie citit din documentul vechi inainte de stergere si impus celui nou. - S9 (
:3505-3538): mecanismul concret — "ID_FACTse citeste inainte de stergere ... si se impune documentului nou, printr-un comutator folosit numai de regenerare"; plus tot efortul de a ocoli coliziuneaORA-00001pePK_DOCUMENTEcand se refoloseste acelasiID_FACT.
Acelasi tipar de mecanism ("citeste din vechi inainte de stergere, transporta explicit la INSERT-ul
nou") ar fi necesar si pentru ID_UTIL/DATAORA daca se vrea pastrata "data/utilizator creare
originala" — dar acest pas nu exista nicaieri in plan azi. Nu e o eroare de implementare, e un
gol de cerinta: planul #13 nu a fost scris cu "pastreaza si audit-ul de creare" ca obiectiv:
sectiunea 1 a acestui raport (plan_13...md:1462-1467) chiar foloseste ID_UTILS/DATAORAS
NULL ca dovada ca "nicio editare ulterioara nu s-a inregistrat" pe o factura din 2026 — ceea ce arata
ca autorii planului tratau deja ID_UTILS/DATAORAS (stergere) ca semnal indirect de "a fost
editat", dar fara sa discute explicit soarta lui ID_UTIL/DATAORA (creare) la regenerare.
4. Ce lipseste din cele sase cerute de Marius
| Cerut | Exista azi? | Observatie |
|---|---|---|
| Data crearii | DA — VANZARI.DATAORA |
Scrisa consecvent la INSERT (sectiunea 2). Sub #13/S9 asa cum e proiectat azi, s-ar suprascrie tacit la fiecare regenerare (sectiunea 3) — nimic nu o transporta din documentul vechi. |
| Utilizatorul crearii | DA — VANZARI.ID_UTIL |
Idem: scris consecvent la INSERT, dar s-ar pierde la regenerare sub #13/S9 asa cum e proiectat azi. |
| Data modificarii (daca e cazul) | NU exista coloana dedicata pe antet (VANZARI) |
Nu exista DATA_MODIF/echivalent. DATA_ACT exista dar e data contabila, nu audit. Pe VANZARI (antet), #6 nu scrie nimic. Pe VANZARI_DETALII (linie), #6 scrie dataoras chiar si pe randuri nesterse (ofacturare_editare.prg:501-505,522-525) — semnal de "ultima atingere", dar suprapus peste semantica de stergere, nu o coloana proprie de modificare. Sub #13/S9, singurul semnal indirect pe antet ar fi DATAORAS a randului vechi (marcat sters) — reconstruibil prin lant (vezi atenuarea din sectiunea 3), nu direct pe documentul curent. |
| Utilizatorul modificarii (daca e cazul) | NU exista coloana dedicata pe antet (VANZARI) |
Acelasi rationament — nu exista ID_UTIL_MODIF. Pe VANZARI_DETALII, #6 scrie id_utils si pe randuri nesterse (acelasi loc de mai sus), cu aceeasi suprapunere peste semantica de stergere. Pe antet, #13/S9 ar lasa doar ID_UTILS pe randul vechi (sters), reconstruibil prin lant, nu pe cel curent. |
| Data stergerii | DA — VANZARI.DATAORAS |
Scrisa consecvent in sterge_factura si sterge_proforma (sectiunea 2). |
| Utilizatorul stergerii | DA — VANZARI.ID_UTILS |
Idem, scris consecvent. |
Rezumat: 4 din 6 cerinte au deja coloana dedicata si scriere consecventa pe antet (creare x2,
stergere x2) — dar cele doua de "creare" sunt fragile fata de regenerarea planificata in #13,
riscand sa fie suprascrise silentios daca S9 nu adauga un pas explicit de transport (dupa modelul
deja folosit pentru ID_FACT), atenuat de faptul ca raman reconstruibile prin lant (sectiunea 3).
Cele doua de "modificare" nu au coloana proprie pe antet: pe VANZARI nici azi (#6 atinge doar
COD), nici in proiectarea #13 (regenerarea confunda "modificare" cu "creare noua" + "stergere
veche"); pe VANZARI_DETALII, #6 reutilizeaza ID_UTILS/DATAORAS ca semnal de "ultima
atingere" chiar pe linii nesterse — util ca indiciu, dar ambiguu fara STERS in conditie, si tot nu
e o pereche explicita de "modificare" pe care un raport sa o citeasca direct fara ambiguitate.
Verificat direct vs dedus vs neacoperit
Nota de provenienta: sectiunile 1-2 si structura raportului sunt cercetarea mea initiala.
Corectia despre ofacturare_editare.prg:492-494,501-505,522-525 (sectiunea 2, editarea #6 pe
VANZARI_DETALII), perechea ID_UTILFACT/DATA_FACTURAT (sectiunea 1) si atenuarea prin lant
ID_FACT (sectiunea 3) au fost verificate si furnizate de sesiunea principala, nu de mine — le-am
integrat ca atare, marcate explicit in text la locul lor.
Verificat direct (citit in cod / rulat pe DB):
- Structura
all_tab_columnspentruVANZARIsiVANZARI_DETALII(interogare live peROA_CENTRAL, sectiunea 1) — a mea; reconfirmata independent de sesiunea principala, inclusiv filtrarea explicita pe%MODIF%(zero rezultate). INSERT INTO VANZARIdinscrie_in_vanzari(EXPORT:13598-13640) si al doilea dinfinalizeaza_avize_lucrare(EXPORT:14930) — sursa luiID_UTIL/DATAORA— a mea.- Zero rezultate la cautarea
UPDATE VANZARI SET ... ID_UTIL/DATAORAin tot pachetul — confirmat prin grep direct pe fisierul export — a mea. sterge_facturacomplet (EXPORT:5432-5607) — scriereaSTERS/ID_UTILS/DATAORASpeVANZARI(:5496-5499) siVANZARI_DETALII(:5560-5564) — a mea.modifica_date_factura(EXPORT:14439-14500) — confirmat caDATA_ACTe propagata catreACT/DOCUMENTE/JV2007/RUL, deci e data contabila, nu audit — a mea.COMUN\docs\flux-modificare-stergere-nota-jurnal.md:95,101-102— editarea #6 (nota contabila) atinge doarVANZARI.COD, nuID_FACT, si nu s-a gasit nicio scriere pe coloanele de audit de antet in acel flux — a mea, ramane corecta doar pentruVANZARI, nu pentruVANZARI_DETALII.ofacturare_editare.prg:492-494, 501-505, 522-525— scriereaid_utils/dataoraspeVANZARI_DETALII, inclusiv pe randuri nesterse — a sesiunii principale, eu nu am citit acest fisier (nu era in perimetrul cercetarii initiale, care s-a concentrat pe pachetul PL/SQL).- Sectiunile E si S9 din
docs\plan_13_unificare_formular_facturare.md(mecanismul de pastrare aID_FACT) si absenta oricarei mentiuniID_UTIL/DATAORAin tot documentul (cautare directa, singurele hit-uri sunt in alt context, sectiunea 1 din acest raport) — a mea.
Dedus (nu verificat direct, dar sustinut de dovezile de mai sus):
- Ca S9, DACA se implementeaza exact cum e proiectat azi in plan, ar suprascrie
ID_UTIL/DATAORAla regenerare — dedus din faptul ca reemiterea foloseste acelasiINSERT INTO VANZARIca emiterea normala, si niciun pas de transport nu e mentionat in plan. Nu exista inca implementare de rulat. sterge_proforma(EXPORT:5610-...) urmeaza acelasi tipar casterge_factura— verificat doar header-ul si inceputul; nu am citit tot corpul procedurii linie cu linie (structura generala insa se potriveste, fiind aceeasi familie de proceduri din acelasi pachet).
Neacoperit:
- Nu am verificat daca exista si alte cai de INSERT/UPDATE pe
VANZARIin afaraPACK_FACTURARE(de exempluPACK_MIGRARE, migrari istorice) care ar putea lasaID_UTIL/DATAORANULL sau cu alta semantica pe date vechi — nu era in scopul intrebarii (audit pe fluxul curent).plan_13...md:844-847mentioneaza ca a existat deja o cautare exhaustiva pe toateUPDATE VANZARI(13 aparitii) in runda 7, dar cu alt scop (antet, nu audit) — nu am reluat-o eu. - Nu am verificat daca exista rapoarte/ecrane in aplicatie care deja afiseaza vreuna din aceste coloane catre utilizator (relevant pentru UX, nu pentru intrebarea de audit DB pusa aici).
- Nu am rulat interogari pe date reale (cate facturi au
ID_UTILS/DATAORASpopulate azi in productie) — brief-ul cerea structura si rutele de scriere, nu statistici.