Files
roagest/CLAUDE.md

19 KiB
Raw Blame History

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.pjx in the VFP IDE and use Project > Build to produce roagest.exe. The startup program is Programe/roagest.prg.
  • .prg files are source; .fxp/.FXP are compiled, .BAK are 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/.mpx are GENMENU-generated from .mnx; never hand-edit them.
  • SVN remains the "live" source of truth, especially for COMUN/ — use svn, not git, for the authoritative history. A git repo now runs in parallel (see "Version control: git alongside SVN" below).
  • config.fpw sets the runtime environment (CODEPAGE=1252, EXCLUSIVE=OFF, SAFETY=OFF, MULTILOCKS=ON, TALK=OFF). Don't enable SAFETY — the code relies on silent overwrite. Programe/roagest.prg re-asserts most of these plus SET DATE TO DMY, SET DECIMALS TO 4, SET EXACT ON.
  • roagest.exe refuses to start unless its own filename matches gcNumeProgram = 'ROAGEST' (IF !LIKE(gcNumeProgram + '*', ...) near the top of roagest.prg) — a guard against running a renamed/copied executable.
  • The compiler error log is roagest.ERR; the runtime log is log.txt. roagest.Stats and versiune_db.txt (format YYYY_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.prg is a near-duplicate of roagest.prg (same startup pattern, older CONT2000 naming) still present in the tree — treat it as legacy/reference, not the active entry point, unless you confirm otherwise from roagest.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 remote git@gitea.romfast.ro:romfast/roagest.git. .gitignore exclude COMUN/ (gestionat separat, vezi mai jos), .svn/, artefactele VFP compilate (*.fxp, *.bak, *.mpr, *.exe, …) și fișierele Windows uzuale.
  • COMUN/ are propriul .git separat, cu remote git@gitea.romfast.ro:romfast/comun.gitacelași repo partajat de toate aplicațiile ROA (ROAACNPRO, ROAIMOB, etc.). O modificare împinsă acolo afectează toate proiectele. Nu face push --force peste comun.git fără aprobare explicită — ar șterge istoric comun tuturor proiectelor.
  • Căutarea în cod VFP binar (.vcx/.scx) pentru acest proiect folosește vcx2txt.ps1 parametrizat 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:

  1. Refresh the cache (vcx2txt.ps1 above), especially if a VFP IDE session ran since the last refresh (IDE changes make the cache stale).
  2. Edit the .vc2/.sc2 text directly (position-sensitive format — don't reflow lines; properties are alphabetized).
  3. Review the diff on the text file like any other source change.
  4. 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-level Programe/, Clase/, Ferestre/, Meniuri/, Rapoarte/ directories. Only touch COMUN/ 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 own Programe/. ROAGEST's own Programe/ 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/_mp500 cash-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 from COMUN/programe/ via SET 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 in COMUN/clase/, not this repo's Clase/.
  • ROAGEST's own Clase/ folder is small: gestiuni.vcx, oavize.vcx, oimportxml.vcx, orapoarte_gestiuni.vcx, ovizrul.vcx, atentie.vcx. Its own Ferestre/ is also small: fundal.scx (shell form), accesindivid.scx, frm_conversii.scx, frm_schimbare_pret_tva.scx. The bulk of forms actually used are COMUN\ferestre\* (e.g. login is COMUN\ferestre\frm_login.scx).
  • SET PATH (see Programe/roagest.prg ~line 109) makes COMUN\CLASE, COMUN\FERESTRE, COMUN\PROGRAME, COMUN\GRAFICE, COMUN\RAPOARTE, COMUN\MENIURI, and the COMUN\UTILE\* helper libraries (GridExtras, ctl32, hpdf/ReportOutput, web, Excel) resolvable by bare filename, plus a sibling ..\COMUNROA\ directory (built from gcAppPath's grandparent). So SET PROCEDURE TO email.prg resolves to COMUN\PROGRAME\email.prg.

Application architecture

Startup flow (Programe/roagest.prg, procedural — no oApp/RoaApp object wraps it):

  1. Verifies the running exe is actually named ROAGEST*; sets SET CENTURY/DELETED/DATE/EXACT/... environment options.
  2. Computes gcAppPath (own folder) and gcDirMare/dirgen (suite root, one level up — e.g. D:\ROA\), builds the long SET PATH TO string across its own folders + COMUN\* + ..\COMUNROA\, then issues dozens of ordered SET CLASSLIB ... ADDITIVE and SET PROCEDURE ... ADDITIVE statements (order matters: later ADDITIVE registrations can shadow earlier same-named procedures/classes).
  3. 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).
  4. 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 optional goKeepAlive timer (avoids ODBC idle timeouts).
  5. NUMEPROGRAM = 'ROA - Gestiuni', _program = 'gest'; reads the actual version string from the built .exe's file version resource.
  6. Registers ON SHUTDOWN ShutDown() / ON ERROR ErrorHandler(...), instantiates goApp = CREATEOBJECT("wzApplication"), sets goApp.cStartupMenu to Meniuri\roagest.mpr and goApp.cStartupForm to COMUN\ferestre\frm_login.scx, then goApp.SHOW — this is the VFP event loop entry (AppWizard's Show/Run machinery), analogous to READ EVENTS in the newer apps.
  7. ErrorHandler posts errors to a remote endpoint via goMyXMLHTTP.postError(...) (host read from settings.ini's [errors] host key) in addition to showing AMESSAGEBOX. 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 (default CONTAFIN), 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-out PORNIRE/verif_ser_perm) — dead code kept for reference, not active.

Data layer

  • Backend is Oracle, reached via goConn/goExecutor (created from the DECABAZA classlib, same pattern as the sibling apps) — run queries with SQLEXEC()/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 marcat bon fiscal tables. Look in COMUN/programe/oproceduri_stocuri.prg, oproceduri_articole.prg, and oproceduri_rulaje.prg for the canonical query/view names (e.g. viz_stocuri filters on an, 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 .h include defines domain constants the way roaacnpro.h does for ROAACNPRO — Include/CONT2000.H is just a historical comment (a class-tree diagram from the old CONT2000 codebase), and Include/foxpro.h is the stock VFP header. Domain behavior (document types, movement signs, VAT handling) is expressed directly in procedure logic in COMUN/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 from COMUN\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 by goApp.cStartupMenu).
  • todo.txt is 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.02.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 (in COMUN/programe/) integrate specific fiscal printer/cash-register protocols (E500, MP500); Initializari/roagest_bon.xml/roagest_mp500.xml are their config templates.
  • ANAF e-Factura / SAFT: COMUN/programe/anaf_efactura.prg provides 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 cu model: 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) cu vcx2txt.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.