19 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, COMUN\docs\flux-editare-vfp-text.md for the shared per-round workflow (baseline backups, review patches, fidelity check), and docs/flux-editare-vfp-text.md for the ROAGEST-specific parameters.
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.
Mod de lucru: delegare către subagenți + review înainte de commit
Preferințele lui Marius pentru sesiunile pe acest proiect:
- 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.
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.