Files
roaimob/CLAUDE.md

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/.PJT is a Visual FoxPro project file; building means opening it in the Visual FoxPro 9 IDE and using Project > Build to recompile .prg.FXP and relink roaimob.exe. Individual source files can be recompiled with COMPILE <file>.prg from the VFP command window.
  • Run: The compiled roaimob.exe is not meant to be launched directly in production — Programe/roaimob.prg checks verific_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). A Debug_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 shared goExecutor object (oExecutor class, registered from the DECABAZA classlib) via SQL strings like begin 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). Each op_* 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 through goExecutor and return an Empty object with a lSucces flag 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 .sql files (istoric_amortizare_contabila.sql, istoric_amortizare_fiscala.sql) are ad hoc reporting/audit queries against this schema, not migrations. COMUN/Drepturi utilizatori/*.sql define 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 builds SET PATH TO across Date;Include;Ferestre;Grafice;Clase;Meniuri;Programe;Rapoarte;COMUN;COMUN\... and then issues a long, order-sensitive sequence of SET PROCEDURE TO ... ADDITIVE and SET CLASSLIB TO ... ADDITIVE statements to register dozens of shared .prg procedure libraries and .vcx class 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 globals gnIdFirma/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.txt records the expected DB schema stamp (format YYYY_MM_DD_NN) checked against the server on launch.

  • Localization: Locale/ + the locale classlib + a goLocale object read settings.ini ([locale] lang, llocale) to select the UI language; Romanian is the default and the translation path is largely dormant (glTraducere defaults to .F.).

  • Changelog convention: changelog_roaimob.txt holds 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.