Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A5okKjUKMM5Xk1egq2w81P
11 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project overview
ROAIMOB is the "Imobilizari" (Fixed Assets) module of ROA, a large Romanian ERP suite built by ROA Romfast SRL. It is a Visual FoxPro 9 desktop application (not Delphi) backed by an Oracle database. The app manages Romanian fixed-asset accounting: asset registration, depreciation (amortizare), revaluation (reevaluare), custodian/location transfers (gestiune), transformation of in-progress assets into tangible/intangible fixed assets, inventory lists, and related reports.
This repo (D:\ROA\ROAIMOB) is just one module. It lives alongside dozens of sibling ROA* apps under D:\ROA (ROACASA, ROAFACTURARE, ROASAL, ROAHOTEL, ROAGEST, etc.), all sharing a common library normally found at D:\ROA\COMUNROA (outside this repo). This repo also vendors its own local snapshot of shared code under ./COMUN (clase, ferestre, programe, rapoarte, meniuri, utile) — treat ./COMUN as this app's copy of shared infrastructure, not ROAIMOB-specific business logic, unless a file clearly deals with imob_*/asset concerns.
Version control: Subversion (.svn present at the root and inside COMUN\) remains the "live" source of truth, especially for COMUN\ — use svn, not git, for actual source changes and history there. A git repo now runs in parallel (git@gitea.romfast.ro:romfast/roaimob.git, branch main), synced manually from SVN snapshots; it exists for tooling (search, diffing, AI-assisted work), not as the system of record. COMUN\ has its own separate git repo (its own .git, gitignored from the root repo via COMUN/ in .gitignore) tracking git@gitea.romfast.ro:romfast/comun.git — the same shared repo used by every ROA app's COMUN\ (e.g. ROAACNPRO). Don't force-push either repo, especially comun.git, without explicit approval — it's shared history across all ROA projects.
Common commands
No build scripts, Makefiles, package manifests, CI config, or test suite exist in this repo — do not invent any.
- Build: There is no scripted/CLI build.
roaimob.PJX/.PJTis a Visual FoxPro project file; building means opening it in the Visual FoxPro 9 IDE and using Project > Build to recompile.prg→.FXPand relinkroaimob.exe. Individual source files can be recompiled withCOMPILE <file>.prgfrom the VFP command window. - Run: The compiled
roaimob.exeis not meant to be launched directly in production —Programe/roaimob.prgchecksverific_start()and refuses to run unless started by the central ROA launcher ("START"), which passes a single semicolon-delimited parameter string (host;user;password;idutil;idprogram;...) including the Oracle schema (gcS, e.g.CONTAFIN), company id (gnIdFirma), and fiscal period (gnAn/gnLuna). ADebug_Start()bypass exists for local/dev launches (defined outside this repo, in the shared COMUNROA tree). - Lint/tests: none present.
Searching inside compiled VFP binaries (foxbin2prg)
Git tracks the FoxBin2Prg text versions of the VFP binaries (.vc2/.sc2/.fr2/.mn2/.lb2/.pj2/.dc2/.db2), generated in-tree next to each binary — not the binaries themselves, which are git-ignored. Refresh with git_sync.ps1 (folder-mode, recursive, incremental):
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\git_sync.ps1 -ProjectRoot D:\ROA\ROAIMOB
Run it at the start of every session and before any git commit so the text matches the binaries. It converts in a temp staging area and copies back only the text, continues past per-file failures, and exits nonzero on any failure: do not commit while git_sync reports unexplained failures. Then search the .??2 files in-tree with Grep (e.g. PROCEDURE do_salvare), citing file:line.
Editing: write-back text→binary via txt2vcx.ps1 is supported only for .vc2/.sc2 (vcx/scx); .frx/.mnx/.lbx/.pjx/.dbc/.dbf are editable only in the VFP IDE (no write-back). See D:\ROA\UTIL\foxbin2prg\CLAUDE.md and COMUN\docs\flux-editare-vfp-text.md.
Grep can't tell which class/method a hit inside a .vc2 belongs to (the class header may be thousands of lines above it, and ~2/3 of the file is properties/metadata). vfp_symbols.ps1 indexes the line range of every class/method/procedure and labels hits with their owner — use it before any txt2vcx.ps1 edit to get the exact line range of the method you are changing. Its built-in defaults target ROAACNPRO, so always pass this project's paths:
$s = 'D:\ROA\UTIL\foxbin2prg\vfp_symbols.ps1'
$c = @('-CacheRoot', 'D:\ROA\ROAIMOB', '-ProjectRoot', 'D:\ROA\ROAIMOB', '-IndexFile', 'D:\ROA\_vfp_textcache\roaimob\_symbols.tsv')
powershell -ExecutionPolicy Bypass -File $s @c -Grep '<expression>' -CodeOnly # hits labeled class.method, code only
powershell -ExecutionPolicy Bypass -File $s @c -Where '<file>.vc2:<line>' # who owns this line
powershell -ExecutionPolicy Bypass -File $s @c -Find '<name>' # where it is DEFINED
powershell -ExecutionPolicy Bypass -File $s @c -Class '<class name>' # inheritance chain + methods
The index (_symbols.tsv) rebuilds itself when the text is newer, so refresh the text first — it can't see IDE edits that were never converted. Full search guide: COMUN\docs\cautare_vcx_vct.md.
Architecture
-
Thin client / DB-heavy split: VFP forms (
Ferestre/*.scx,Clase/*.vcx) only collect input and display data. Actual persistence and business rules live in Oracle PL/SQL packages (e.g.pack_imob.inreg_majorare,pack_imob.inreg_reevaluare), invoked through a sharedgoExecutorobject (oExecutorclass, registered from theDECABAZAclasslib) via SQL strings likebegin pack_imob.inreg_reevaluare(...); end;. When tracing a feature, expect to jump from a VFP form/procedure straight into an Oracle package call — the interesting logic is often server-side, not in the.prg. -
Asset operations funnel through
Programe/oproceduri_operatii.prg, keyed by a fixed "cod operatie" enum documented in a comment block at the top of that file (1 introducere, 2 preluare, 3 transformare in MF, 4 iesire din gestiune, 5 intrare in gestiune, 6 majorare, 7 reevaluare, 8 schimbarea DNS, 9 recalculare cota, 10 conservare, 11 scoatere din conservare, 12 modificare cu istoric, 13 inchidere, 14 schimbare DNS + reevaluare). Eachop_*procedure (op_majorare,op_reevaluare,op_schimbaredns_reevaluare,op_conservare,op_schimbaredns,op_gest,op_modificare,op_transformare_mf,op_adaugare_la_mf) follows the same pattern: show a modal form to collect data, then call the matching Oracle package procedure throughgoExecutorand return anEmptyobject with alSuccesflag plus the collected fields. -
Data model uses Oracle views/tables prefixed
IMOB_(imob_vnom_mf= asset master/nomenclator,imob_voperatii_mf= operation history,imob_vlista_mf= current asset list,imob_vcalcul_rate= depreciation rate calculations,imob_conturi= account-code mapping). "MF" throughout the codebase means mijloc fix (fixed asset). Root-level.sqlfiles (istoric_amortizare_contabila.sql,istoric_amortizare_fiscala.sql) are ad hoc reporting/audit queries against this schema, not migrations.COMUN/Drepturi utilizatori/*.sqldefine the user-rights/permission object catalog, shared across this and sibling apps (subfolders reference ROACASA, ROADEF, ROALUCRARI). -
Startup wiring (
Programe/roaimob.prg) is the place to look when something "isn't found": it buildsSET PATH TOacrossDate;Include;Ferestre;Grafice;Clase;Meniuri;Programe;Rapoarte;COMUN;COMUN\...and then issues a long, order-sensitive sequence ofSET PROCEDURE TO ... ADDITIVEandSET CLASSLIB TO ... ADDITIVEstatements to register dozens of shared.prgprocedure libraries and.vcxclass libraries globally. Later entries can shadow earlier ones with the same procedure/class name, so order in this file matters when debugging "wrong version of a procedure ran" issues. -
Multi-tenant context: the app operates against one Oracle schema per company (
gcS, default'CONTAFIN') and tracks the active company/fiscal period in globalsgnIdFirma/gnAn/gnLuna, plus branch (id_sucursala). Most business queries and package calls are scoped by these. -
Self-update: on startup the app calls
oUpdate.updatecheck()(oupdate.prg/wwcodeupdate.prg) against an update server;versiune_db.txtrecords the expected DB schema stamp (formatYYYY_MM_DD_NN) checked against the server on launch. -
Localization:
Locale/+ thelocaleclasslib + agoLocaleobject readsettings.ini([locale] lang,llocale) to select the UI language; Romanian is the default and the translation path is largely dormant (glTraduceredefaults to.F.). -
Changelog convention:
changelog_roaimob.txtholds HTML-comment-wrapped, dated (dd/mm/yyyy) entries per version (ROAIMOB - X.Y.Z), each with Romanian-language notes tagged:nou:(new),:modificare:(change),:eroare:(bug fix), or:adaugare:(addition). Follow this exact format/tagging when documenting a change here. -
Unrelated nested project:
COMUN/utile/chatbot/is a standalone Flowise-embed HTML support chatbot (chatbot_maria.html) with its own README.md and CLAUDE.md. It has no relation to the FoxPro/Oracle asset-management app — don't conflate its guidance with ROAIMOB itself.
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.
Project insights (docs/)
docs/ holds short, concrete notes discovered while working on real tasks — flows (e.g. transformare imobilizare in curs -> MF), pack_imob procedures, IMOB_* table layout — that go beyond what CLAUDE.md 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.