Reguli de lucru in CLAUDE.md: stil de raspuns scurt, changelog compact, curatenie (diff/handoff/temporare) inainte de commit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9uDgDfUQXbh2Neib36CN8
22 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this is
ROAGEST is a Visual FoxPro 9 desktop application (Romanian-language) for gestiune de stocuri și mărfuri — goods/inventory management: purchases (achiziție, NIR — notă intrare recepție), sales, warehouse transfers, stock (stoc), consumption vouchers (bon consum), inventory counts (inventar), price changes (schimbare preț), and cash-register (casă de marcat, e500/mp500) integration. It backs onto an Oracle database (gcS schema, default CONTAFIN) reached through the shared goExecutor/goConn SQL pass-through objects. It is one member of the larger "ROA" suite built by ROA Romfast SRL (ROAACNPRO, ROAIMOB, ROACONT, ROACASA, ROADEF, etc.) and lives alongside its siblings under D:\ROA.
The code, comments, menus, and changelog are all in Romanian — match that language when editing user-facing strings, comments, and changelog entries.
Architecturally, ROAGEST is older-generation than ROAACNPRO/ROAIMOB: those apps instantiate oApp as a subclass of the shared RoaApp framework class (COMUN/programe/roa.prg) with an ordered initializeaza* method pipeline. ROAGEST does not use RoaApp at all — COMUN/programe/roa.prg exists in this repo (vendored, shared with the other apps) but is unreferenced. Instead, Programe/roagest.prg is a long, monolithic startup script that manually chains SET PATH/SET CLASSLIB ... ADDITIVE/SET PROCEDURE ... ADDITIVE statements and instantiates goApp = CREATEOBJECT("wzApplication") — the classic VFP "Application Wizard" base class (defined in COMUN/clase/appwiz.vcx). Don't assume the RoaApp/initializeaza* conventions documented for ROAACNPRO/ROAIMOB apply here.
Build, run, version control
- Build/run requires the Visual FoxPro 9 IDE on Windows. There is no command-line build. Open
roagest.pjxin the VFP IDE and use Project > Build to produceroagest.exe. The startup program isPrograme/roagest.prg. .prgfiles are source;.fxp/.FXPare compiled,.BAKare backups. Edit the.prg. The.scx/.sct(forms),.vcx/.vct(class libraries),.frx/.frt(reports), and.mnx/.mnt/.mpr(menus) are VFP binary/generated artifacts — edit them in the VFP IDE, not by hand..mpr/.mpxare GENMENU-generated from.mnx; never hand-edit them.- SVN remains the "live" source of truth, especially for
COMUN/— usesvn, notgit, for the authoritative history. A git repo now runs in parallel (see "Version control: git alongside SVN" below). config.fpwsets the runtime environment (CODEPAGE=1252,EXCLUSIVE=OFF,SAFETY=OFF,MULTILOCKS=ON,TALK=OFF). Don't enableSAFETY— the code relies on silent overwrite.Programe/roagest.prgre-asserts most of these plusSET DATE TO DMY,SET DECIMALS TO 4,SET EXACT ON.roagest.exerefuses to start unless its own filename matchesgcNumeProgram = 'ROAGEST'(IF !LIKE(gcNumeProgram + '*', ...)near the top ofroagest.prg) — a guard against running a renamed/copied executable.- The compiler error log is
roagest.ERR; the runtime log islog.txt.roagest.Statsandversiune_db.txt(formatYYYY_MM_DD_NN, e.g.2026_01_21_02) track build/DB-schema stamps checked against the update server on launch (COMUN/programe/oupdate.prg,wwcodeupdate.prg). Programe/cont2000.prgis a near-duplicate ofroagest.prg(same startup pattern, olderCONT2000naming) still present in the tree — treat it as legacy/reference, not the active entry point, unless you confirm otherwise fromroagest.pjx's main-file setting.
Version control: git alongside SVN
Git rulează în paralel cu SVN-ul legacy, nu îl înlocuiește. SVN rămâne sursa "vie" pentru COMUN/, sincronizat manual către git; nu rula comenzi svn din git și nu presupune că git-ul e la zi cu ultimele modificări SVN dacă nu a fost sincronizat explicit.
- Repo-ul principal (rădăcina acestui folder) e propriul lui
.git, cu remotegit@gitea.romfast.ro:romfast/roagest.git..gitignoreexcludeCOMUN/(gestionat separat, vezi mai jos),.svn/, artefactele VFP compilate (*.fxp,*.bak,*.mpr,*.exe, …) și fișierele Windows uzuale. COMUN/are propriul.gitseparat, cu remotegit@gitea.romfast.ro:romfast/comun.git— același repo partajat de toate aplicațiile ROA (ROAACNPRO, ROAIMOB, etc.). O modificare împinsă acolo afectează toate proiectele. Nu facepush --forcepestecomun.gitfără aprobare explicită — ar șterge istoric comun tuturor proiectelor.- Căutarea în cod VFP binar (
.vcx/.scx) pentru acest proiect foloseștevcx2txt.ps1parametrizat pentru ROAGEST (vezi secțiunea de mai jos) — cache separat,D:\ROA\_vfp_textcache\roagest, nu-l amesteca cu cache-urile altor proiecte.
Searching code inside .vcx/.scx (binary) libraries
Most class/form code lives inside binaries (.vcx+.vct, .scx+.sct, …), not in .prg, so plain grep can't read it cleanly. To search method/procedure bodies, convert the binaries to their TEXT form first and grep the text, using the shared foxbin2prg tool already built at D:\ROA\UTIL\foxbin2prg\FoxBin2Prg.EXE:
& 'D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1' -Project 'D:\ROA\ROAGEST\roagest.pjx' -ProjectRoot 'D:\ROA\ROAGEST' -CacheRoot 'D:\ROA\_vfp_textcache\roagest' -Types vcx,scx,frx,mnx
This reads the file list straight from roagest.pjx, so it only converts the .vcx/.scx/.frx/.mnx this project actually references — not all of COMUN\ (most of which is unused by any one app). It's incremental and safe to re-run after IDE edits. Output lands in D:\ROA\_vfp_textcache\roagest\ as .vc2/.sc2/.fr2/.mn2 text mirrors — Grep those.
For .vcx/.scx, code edits no longer require the VFP IDE — the flow is now:
- Refresh the cache (
vcx2txt.ps1above), especially if a VFP IDE session ran since the last refresh (IDE changes make the cache stale). - Edit the
.vc2/.sc2text directly (position-sensitive format — don't reflow lines; properties are alphabetized). - Review the diff on the text file like any other source change.
- Write back with
txt2vcx.ps1(D:\ROA\UTIL\foxbin2prg\txt2vcx.ps1 -TextFile <path\to\file.vc2> -ProjectRoot 'D:\ROA\ROAGEST' -CacheRoot 'D:\ROA\_vfp_textcache\roagest') — it regenerates and recompiles the binary in a staging folder, fidelity-checks it against the edited text, then copies it into the project only if that check passes.
.mnx/.frx stay read-only in this flow (menus still need GENMENU in the IDE; reports are too fragile to round-trip) — edit those in the VFP IDE as before. Targets under COMUN\ need -AllowComun plus explicit approval, since a change there affects every ROA app. See D:\ROA\UTIL\foxbin2prg\CLAUDE.md for full details and COMUN\docs\flux-editare-vfp-text.md for the shared per-round workflow (baseline backups, review patches, fidelity check) plus the per-project parameters (including ROAGEST's).
The COMUN shared framework
COMUN/ is shared, framework-level code used by every ROA app — it is not specific to ROAGEST. Treat it as a vendored library:
- A change in
COMUN/affects all ROA applications. Prefer making app-specific changes in this repo's top-levelPrograme/,Clase/,Ferestre/,Meniuri/,Rapoarte/directories. Only touchCOMUN/when the fix genuinely belongs to the shared framework. - Unusually for this app, most of the actual "gestiune" business logic lives in
COMUN/programe/, not in this repo's ownPrograme/. ROAGEST's ownPrograme/folder has only ~24 files (roagest.prg,gestiuni.prg,cont2000.prg,oimportdinxml.prg,ofactureaza.prg,exportare.prg,fisa_ob_inventar.prg,update_nomenclator.prg,suma_in_vorbe.prg,actualizari.prg,cumplun-furn.prg,inchidere_k.prg,ovariabile_globale.prg,shutdown.prg), while the core stock/article/movement procedures —oproceduri_stocuri.prg,oproceduri_articole.prg,oproceduri_rulaje.prg,oproceduri_casademarcat.prg(+_e500/_mp500cash-register variants),oproceduri_facturare.prg,oproceduri_obinv.prg(fixed-asset-in-use items),anaf_efactura.prg(ANAF e-Factura),osecurity.prg,oproceduri_configurare.prg,oproceduri_listari.prg,oproceduri_retete.prg,orapoarte.prg— all resolve fromCOMUN/programe/viaSET PATH. Likewise most class libraries used (onomenclatoare,stocuri.vcx,rulaje.vcx,ointroduceri*,oinventar,orapoarte_gestiuni,bon_fisc,onom_articole,onom_retete,ferestre_oracle,configurare.vcx,serii_numere.vcx, …) live inCOMUN/clase/, not this repo'sClase/. - ROAGEST's own
Clase/folder is small:gestiuni.vcx,oavize.vcx,oimportxml.vcx,orapoarte_gestiuni.vcx,ovizrul.vcx,atentie.vcx. Its ownFerestre/is also small:fundal.scx(shell form),accesindivid.scx,frm_conversii.scx,frm_schimbare_pret_tva.scx. The bulk of forms actually used areCOMUN\ferestre\*(e.g. login isCOMUN\ferestre\frm_login.scx). SET PATH(seePrograme/roagest.prg~line 109) makesCOMUN\CLASE,COMUN\FERESTRE,COMUN\PROGRAME,COMUN\GRAFICE,COMUN\RAPOARTE,COMUN\MENIURI, and theCOMUN\UTILE\*helper libraries (GridExtras, ctl32, hpdf/ReportOutput, web, Excel) resolvable by bare filename, plus a sibling..\COMUNROA\directory (built fromgcAppPath's grandparent). SoSET PROCEDURE TO email.prgresolves toCOMUN\PROGRAME\email.prg.
Application architecture
Startup flow (Programe/roagest.prg, procedural — no oApp/RoaApp object wraps it):
- Verifies the running exe is actually named
ROAGEST*; setsSET CENTURY/DELETED/DATE/EXACT/...environment options. - Computes
gcAppPath(own folder) andgcDirMare/dirgen(suite root, one level up — e.g.D:\ROA\), builds the longSET PATH TOstring across its own folders +COMUN\*+..\COMUNROA\, then issues dozens of orderedSET CLASSLIB ... ADDITIVEandSET PROCEDURE ... ADDITIVEstatements (order matters: laterADDITIVEregistrations can shadow earlier same-named procedures/classes). - Parses the launch parameter string (
tparam, semicolon-delimited:host;user;password;idutil;idprogram;...;an;luna;schema;idfirma) when launched by the central ROA launcher; otherwise falls back to hardcoded dev defaults (JCSSERVER/CONTAFIN_ORACLE). - Sets up cross-cutting globals:
goLog/poLog(Log_Mesaje.prg),goLocale(Romanian by default,glTraducere = .F.— translation path largely dormant),goExecutor/goConn(Oracle SQL pass-through),goExport,goMyXMLHTTP(remote error reporting), and an optionalgoKeepAlivetimer (avoids ODBC idle timeouts). NUMEPROGRAM = 'ROA - Gestiuni',_program = 'gest'; reads the actual version string from the built.exe's file version resource.- Registers
ON SHUTDOWN ShutDown()/ON ERROR ErrorHandler(...), instantiatesgoApp = CREATEOBJECT("wzApplication"), setsgoApp.cStartupMenutoMeniuri\roagest.mprandgoApp.cStartupFormtoCOMUN\ferestre\frm_login.scx, thengoApp.SHOW— this is the VFP event loop entry (AppWizard'sShow/Runmachinery), analogous toREAD EVENTSin the newer apps. ErrorHandlerposts errors to a remote endpoint viagoMyXMLHTTP.postError(...)(host read fromsettings.ini's[errors] hostkey) in addition to showingAMESSAGEBOX.Cleanup()/ShutDown()release class libs, procedures, and the menu stack on exit.
Globals convention
Same g/gc/gn/gl Hungarian-ish prefixing as the rest of the suite (g = global, gc/gn/gl = char/numeric/logical, m. = memory-variable scoping), declared PUBLIC/PRIVATE directly in roagest.prg rather than promoted by a framework object:
goApp(AppWizard app object),goConn/goExecutor(Oracle connection + SQL executor),goLog/poLog(logger),goLocale,goExport,goCalendar,goFirma.gcS= Oracle schema (defaultCONTAFIN),gnIdFirma,gnAn/gnLuna(working year/month),gcAppPath(this app's folder),gcDirMare/dirgen(suite root, e.g.D:\ROA\),gcSecurityPath/gcSecurityFile(DIRGEN + 'Security\ROA_SECURITY.TXT'),gcGeneralIniFile/gcSettingsFile(DIRGEN + 'settings.ini').- Legacy holdovers from the pre-Oracle (
CONT2000) codebase are still declared even though mostly unused now:nror[65000],RTVA[22,2],SER_PERM/SER_PERI/VERSIUNE(commented out), old disk-serial license-check functions (decodare1,HEXDEC,DECTOBIN, the commented-outPORNIRE/verif_ser_perm) — dead code kept for reference, not active.
Data layer
- Backend is Oracle, reached via
goConn/goExecutor(created from theDECABAZAclasslib, same pattern as the sibling apps) — run queries withSQLEXEC()/the executor wrapper; results come back as VFP cursors. - Domain tables/views follow Romanian/domain naming:
stoc,rulaje/rull(stock movements),act(documents/NIR),articole/nomenclator,gestiuni(warehouses/locations),casa de marcatbon fiscal tables. Look inCOMUN/programe/oproceduri_stocuri.prg,oproceduri_articole.prg, andoproceduri_rulaje.prgfor the canonical query/view names (e.g.viz_stocurifilters onan,luna,id_sucursala,id_gestiune). Initializari/holds XML templates for cash-register integrations (roagest_bon.xml(.tmpl),roagest_mp500.xml(.tmpl),euro500t.txt(.tmpl),euro500t_erori.xml(.tmpl)).Locale/is a full VFP database (locale.dbc+.dbf/.cdx) for the (largely dormant) translation feature, not just an .ini.
Domain quick reference
- No app-specific
.hinclude defines domain constants the wayroaacnpro.hdoes for ROAACNPRO —Include/CONT2000.His just a historical comment (a class-tree diagram from the oldCONT2000codebase), andInclude/foxpro.his the stock VFP header. Domain behavior (document types, movement signs, VAT handling) is expressed directly in procedure logic inCOMUN/programe/oproceduri_*.prg, not centralized constants — expect to trace behavior through those procedures rather than a single defines file. Rapoarte/*.frx(24 report layouts in this repo, more resolved fromCOMUN\RAPOARTE) name the real workflows:rap_nirtransfer_achi(NIR/transfer receiving),rap_centralizator_intrari/_intrari2,rap_centralizator_iesiri/_iesiri2(in/out summaries),rap_fisa_magazie_fifo(FIFO stock card),rap_gest_val_subgrupe/_gestc(valued stock by subgroup),rap_vechime_stocuri(stock aging),rap_marfuri_lista_centr/_desf/_valoric(goods lists),rap_vanzari_comp_cant/_val/_web(sales comparisons),rap_instiintaripret(price-change notices),rap_inchidere_k,rap_stoc_obinv(inventory-use objects),rap_rul_consum_lucrari_articole/_centralizator_consum_lucrari(consumption vouchers).Meniuri/menu names map to the app's top-level operations:achi*(achiziții/purchases),vanz*(vânzări/sales),consum*(bon consum),transfer*(stock transfers),config*(configurare),casademarcat/casamarcat(fiscal cash registers),obinvent(obiecte de inventar),stoc,rulaje,list*/rapoarte(reports),roagest.mnx/.mpr(the root startup menu, referenced bygoApp.cStartupMenu).todo.txtis an informal running work list (Romanian,ok/OK-prefixed = done, otherwise pending) — recent items concern store inventory (inventar magazin), FIFO stock cards, and VAT-rate handling during the 19%→21% transition; useful as a quick pulse on active/recent pain points but not authoritative documentation.- VAT/TVA is time-sensitive here too: recent changelog entries (v2.11.0–2.11.2) explicitly prepare the app for the 21%/11% rates effective 2025-08-01 while still supporting 19%/9%/5% for prior periods — the same "rate by document period, not 'current' rate" caution as the other ROA apps applies.
- Cash register / fiscal integration:
oproceduri_casademarcat.prg,oproceduri_casa_marcat_e500.prg,oproceduri_casa_marcat_mp500.prg(inCOMUN/programe/) integrate specific fiscal printer/cash-register protocols (E500, MP500);Initializari/roagest_bon.xml/roagest_mp500.xmlare their config templates. - ANAF e-Factura / SAFT:
COMUN/programe/anaf_efactura.prgprovides e-invoicing against ANAF, shared with sibling apps.
Changelog & release convention
changelog_roagest.txt is the user-facing release log (188KB, going back to v1.0.x). Newest entry goes at the top, in this exact HTML-comment block format (Romanian, DD/MM/YYYY):
<!--
21/01/2026
ROAGEST - 2.11.5
:nou:
<what changed>
:modificare:
<what changed>
-->
Tags in use: :nou: (new feature), :modificare: (change), :eroare: (bug fix), and occasionally :adaugare: (addition) — match this exact tag vocabulary (a lone historical :modfiicare: typo exists; don't repeat it). Bump the MAJOR.MINOR.PATCH version (currently 2.11.5) when you add an entry. The app checks for updates on startup (COMUN/programe/oupdate.prg, wwcodeupdate.prg) against versiune_db.txt's schema stamp; the runtime reads its own version from the built .exe's file version resource.
Intrările sunt simple și compacte — doar strictul necesar pentru utilizatori. O singură intrare consolidată per livrare (versiunea o dă Marius), fără pași intermediari, fără runde, fără mecanisme interne și fără erori apărute și corectate în interiorul aceleiași lucrări nelivrate.
Mod de lucru: delegare către subagenți + review înainte de commit
Preferințele lui Marius pentru sesiunile pe acest proiect:
- Orchestrare pe misiuni lungi: niciodată un singur subagent care acumulează context pe multe sarcini înlănțuite — sesiunea principală orchestrează subagenți proaspeți per sarcină (prag: max ~200–250k tokens per subagent, apoi handoff + agent nou), cu handoff compact pe disc; regula comună tuturor proiectelor ROA:
COMUN\docs\orchestrare-subagenti.md. - Delegare: modificările de cod de volum/rutină (aplicarea unei propuneri din
docs/propuneri_*.md, editări pe cache-ul text + write-back, actualizări de documentație, rulări de teste) se deleagă către subagenți Sonnet care lucrează în background (team agents — Agent tool cumodel: sonnet, lane-uri paralele unde e posibil), iar sesiunea principală doar orchestrează și monitorizează: împarte planul pe lane-uri, transmite constatările între agenți, verifică rezultatele (diff, teste, fidelity) și intervine direct doar la deblocări (procese agățate), decizii și verificări. - Fără commit fără review: nu da commit din proprie inițiativă pe modificări de cod — Marius vrea întâi să vadă diff-ul. Pentru binarele VFP (
.vcx/.scx), diff-ul lizibil se face pe forma text: regenerează textul din binarul vechi (HEAD din git) cuvcx2txt.ps1 -Sourceși compară-l cu textul editat din cache (git diff --no-index). Commit doar după ce Marius confirmă pe diff. - Curățenie înainte de commit: la finalul unei lucrări se șterg patch-urile de review (
docs/diff_runda*.patch), handoff-urile, planurile de rundă, logurile brute de regresie/repro și backup-urile*.pre_runda*.bak(proiect,COMUN, cache text) — abia apoi commit.
Stil de raspuns: scurt si concret
Marius vrea raspunsuri clare, concise, fara vorbarie. Regula, nu preferinta.
- Starea si ce urmeaza, nu povestea. Ce e gata, ce e stricat, ce trebuie decis, ce urmeaza — in liste scurte, cu fisier si linie. Fara reconstituirea drumului pana la rezultat.
- Fara naratiune de proces: ce a raportat fiecare agent, cine ce a corectat, cum au fost
coordonate benzile. Intra in
docs/, nu in raspuns. - Fara laude si fara reluari. Nu repeta ce s-a spus deja in conversatie.
- Detaliile tehnice lungi (dovezi, iesiri de test, metodologie) se scriu in fisier si se trimite la el, nu se copiaza in raspuns.
- Cand e ceva de decis: enunta decizia si optiunile in cateva randuri, cu recomandarea ta.
Reguli de lucru si testare
Inainte de orice modificare de cod sau testare, citeste COMUN\docs\reguli_lucru.md.
Nu e optional si nu e doar context: contine regulile de livrare (diff ca fisier + aprobare
inainte de write-back), comentariile (max o linie), modificarile minime, harnessul de testare
headless si — la punctul 7 — lista de conventii obligatorii per zona atinsa (encoding cp1252 la
editarea .vc2/.sc2, UX formulare/griduri, GO pe Recno(), goExecutor + ALTER TABLE,
testare UI, export Oracle). Fisierul e index: urmeaza linkurile relevante pentru sarcina curenta.
Depanare detaliata: COMUN\docs\depanare_testare_vfp.md.
Skill routing
When the user's request matches an available skill, invoke it via the Skill tool. When in doubt, invoke the skill.
Key routing rules:
- Product ideas/brainstorming → invoke /office-hours
- Strategy/scope → invoke /plan-ceo-review
- Architecture → invoke /plan-eng-review
- Design system/plan review → invoke /design-consultation or /plan-design-review
- Full review pipeline → invoke /autoplan
- Bugs/errors → invoke /investigate
- QA/testing site behavior → invoke /qa or /qa-only
- Code review/diff check → invoke /review
- Visual polish → invoke /design-review
- Ship/deploy/PR → invoke /ship or /land-and-deploy
- Save progress → invoke /context-save
- Resume context → invoke /context-restore
Project insights (docs/)
docs/ holds short, concrete notes discovered while working on real tasks — hidden flows, gotchas, key procedures/packages, relevant tables — that go beyond what this file covers. See docs/README.md for the index. Proactively offer to update docs/ whenever you uncover a non-obvious project insight while fixing a bug or investigating a flow (don't wait to be asked), so future sessions can reuse it instead of re-investigating from scratch. Keep entries concise and factual — no restating what's obvious from reading the code.