# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## What this is **ROASTART** ("ROA Romfast Applications") is a Visual FoxPro 9 launcher/shell for the ROA business application suite. It is **not** a typical CLI/IDE-buildable project — it can only be edited and built inside the Visual FoxPro 9 IDE on Windows. - Project file: `roastart.PJX` / `roastart.PJT` (open these in VFP9 to work on the project) - Compiled output: `roastart.exe` (subsequently wrapped with **Armadillo** — see `ROASTART.ARM`) - Source language: Visual FoxPro (`.prg`), Visual Class Libraries (`.vcx` + `.vct`), Forms (`.scx` + `.sct`), Reports (`.frx` + `.frt`) - Data layer: Oracle (ODBC) — connects to `roa.romfast.ro` (previously `83.103.197.79`); local DBFs only for `Locale/` and `roastart_ref` - Comments and identifiers are in **Romanian**. Preserve that language when adding/modifying comments unless asked otherwise. - Source control: git runs in parallel with the legacy SVN (`.svn/`). SVN stays the source of truth for the VFP binaries; git (`git@gitea.romfast.ro:romfast/roastart.git`) tracks their FoxBin2Prg text versions in-tree — see the search section below. `COMUN/` is git-ignored here. ## Build / run There is no command-line build. To produce a new `roastart.exe`: 1. Open `roastart.PJX` in Visual FoxPro 9. 2. `Build → Build Executable…` (the project includes an internal main: `Programe\roastart.prg`). 3. Re-wrap the output with Armadillo using the settings in `ROASTART.ARM` if shipping to customers. To run the built app, double-click `roastart.exe` from the project root — paths are computed relative to it (see `gcAppPath` / `gcDirMare` in `Programe\roastart.prg`). `config.fpw` is the VFP runtime config; `roastart.ERR` is the **last build's** unresolved-symbol report (many entries are expected — they refer to symbols that exist in sister ROA applications loaded via shared `COMUN`). `diag.ps1` is unrelated to the app itself — it is a Claude Code installation diagnostic script. ## File-type conventions (read this before editing) - Edit only `.prg`, `.vcx`/`.scx` (via the VFP IDE), `.h` headers, and text/XML/INI files. - **Never hand-edit** the binary sidecars: `.FXP` (compiled prg), `.VCT` (vcx memo data), `.SCT` (scx memo data), `.FRT` (frx memo data), `.CDX` (index), `.FPT` (table memo). They are generated/managed by VFP. - **Never edit** `.BAK` files — they are stale backups left by VFP. - When a `.prg` is changed, the matching `.FXP` becomes stale until the project is rebuilt. ## Searching code inside `.vcx`/`.scx` (binary) libraries Most class/form code lives **inside binaries**, not in `.prg`, so plain grep can't read it. Like the other ROA projects, git tracks the **FoxBin2Prg text versions** (`.vc2`/`.sc2`/`.fr2`/`.mn2`/`.pj2`/`.dc2`/`.db2`), generated in-tree next to each binary — the binaries themselves are git-ignored, with SVN staying their source of truth. Refresh with `git_sync.ps1` (folder-mode, recursive, incremental): ```powershell powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\git_sync.ps1 -ProjectRoot D:\ROA\ROASTART ``` 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 (never touching the SVN working-copy binaries) and exits nonzero on failure: **do not commit while `git_sync` reports unexplained failures.** Then `Grep` the `.??2` files in-tree, citing `file:line`. Editing stays IDE-only here — the text is for reading and searching, not for write-back. 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. Its built-in defaults target ROAACNPRO, so always pass this project's paths: ```powershell $s = 'D:\ROA\UTIL\foxbin2prg\vfp_symbols.ps1' $c = @('-CacheRoot', 'D:\ROA\ROASTART', '-ProjectRoot', 'D:\ROA\ROASTART', '-IndexFile', 'D:\ROA\_vfp_textcache\roastart\_symbols.tsv') powershell -ExecutionPolicy Bypass -File $s @c -Grep '' -CodeOnly # hits labeled class.method, code only powershell -ExecutionPolicy Bypass -File $s @c -Where '.vc2:' # who owns this line powershell -ExecutionPolicy Bypass -File $s @c -Find '' # where it is DEFINED powershell -ExecutionPolicy Bypass -File $s @c -Class '' # inheritance chain + methods ``` The index (`_symbols.tsv`) rebuilds itself when the text is newer, so refresh the in-tree text first (`git_sync.ps1`) — it can't see IDE edits that were never converted. Full search guide: `COMUN\docs\cautare_vcx_vct.md`. ## Architecture ### Entry point and bootstrap (`Programe\roastart.prg`) This file is the project's main and is dense — read it first. Key responsibilities, in order: 1. **Path discovery** — derives `gcAppPath` (this app), `gcDirMare` (parent dir holding all ROA apps), `gcComunPath` = `\COMUNROA\` (sibling shared dir, separate from this repo's local `COMUN\`), `gcTempPath`. 2. **`SET PATH TO`** — appends every subdir under both the app and the shared library so subsequent `DO`/class lookups resolve. New code/classes must live under one of these dirs to be reachable. 3. **`SET CLASSLIB / SET PROCEDURE`** — preloads ~25 class libraries and procedure files. New classes/procedures should be registered here if they need to be globally available before login. 4. **Encryption FLLs** — `vfpencryption.fll` and `vfpcompression.fll` are loaded from `COMUNROA` (the sibling shared dir, *not* this repo's `COMUN/`). 5. **`UpdateRoastart()`** (in `Programe\updatecheck.prg`) — pulls a manifest XML from the ROA server and downloads/replaces sibling app binaries before the UI is shown. Touching this code path affects every customer's auto-update. 6. **App object** — `goApp = CREATEOBJECT("wzApplication")`; startup form is `Ferestre\frm_fundal.scx` (the always-on background window). The login dialog is launched from there. 7. **Error funnel** — `On Error ErrorHandler(...)` posts every runtime error to `roa.romfast.ro/errors/create_xml` via `goMyXMLHTTP` (class `MyXMLHTTP`). Endpoint host comes from `settings.ini` `[errors] host=`. 8. **Single-instance** — `TooManyInstances(1)` (defined in `oproceduri_start.prg` / class lib) uses a named semaphore + window property to focus the existing instance instead of starting a second one. ### Public globals you will see everywhere VFP-style Hungarian naming. **Do not rename or remove these without a full project search** — they're referenced from compiled `.vcx`/`.scx` resources too: - `gcAppPath`, `gcDirMare`, `gcComunPath`, `gcTempPath`, `gcSecurityPath`, `gcSecurityFile` — paths - `gcGeneralIniFile` (= `\settings.ini`) — shared ROA config - `goConn` (`oConn`) — wraps `SQLCONNECT`/`SQLDISCONNECT`, runs post-connect session setup - `goExecutor` (`oExecutor`) — wraps `SQLEXEC`; preferred way to run Oracle SQL/PLSQL. Returns `lnSucces > 0` on success; on failure read `goExecutor.cEroare` and surface it via `aMessagebox`. Use `goExecutor.oReset()` between calls when reusing. - `goApp` (`wzApplication`) — top-level app object; `goApp.OnShutDown()` is the orderly shutdown path. - `goLocale` (`Locale.vcx`) — translation; `glTraducere` toggles whether captions get translated. - `poLog` / `goLog` (`Log_Mesaje`) — diagnostic log; call `poLog.Log(, Program())`. - `goMyXMLHTTP` — error reporter (see above). - `gnIdUtil`, `gcUtil`, `gcUserName`, `glSupervizor`, `glAdministrator`, `gcAcces` — identity/authorization, populated after login. - `gnIdFirma` — currently selected company (firma). Many SQL queries scope by this. - `glFontCharSet` — font fallback flag for Eastern European charsets. ### Repository layout ``` Programe/ Top-level .prg files specific to ROASTART (entry point, update, security, version) Clase/ Visual class libraries specific to ROASTART (ostart*.vcx, appwiz_start.vcx, ofundal_start.vcx) Ferestre/ Forms (.scx) — frm_fundal is the main background window Grafice/ App-specific images (PNG/BMP/GIF/ICO) Rapoarte/ App-specific FoxPro reports (.frx) Locale/ Localization DBC + DBFs (Romana/English/etc.) COMUN/ Shared library used by ROASTART AND its sibling ROA apps: COMUN/clase/ Shared visual class libraries (_baza.vcx is the root base class, ofirma, decabaza, scrollcontainer, etc.) COMUN/programe/ Shared .prg modules (anaf_efactura, email, importfromxlsx, oproceduri_comune, etc.) COMUN/ferestre/ Shared forms COMUN/include/ Shared headers (foxpro.h, comun.h, security.h, mvc.h) COMUN/utile/ Third-party libs (ctl32, web/wwAPI/wwUtils, hpdf, nfjson/nfXml, GridExtras, GridTreeView, ListProperty, tooltip, calendar, chatbot, email) COMUN/Plugin/ Customer-specific extension scripts loaded at runtime COMUN/meniuri/ Menu definitions COMUN/datemenu/ Menu/permissions data tables COMUN/Drepturi utilizatori/ User-rights resources COMUN/Rapoarte/ Shared reports COMUN/grafice/ Shared images ../COMUNROA/ SIBLING directory (outside this repo) holding the encryption FLLs and other binaries shared at runtime by every installed ROA app. roastart.prg references it as gcComunPath. ``` The repo's `COMUN/` and the sibling `COMUNROA/` are **two different things** — `COMUN/` is source shared across the developer's apps, `COMUNROA/` is a runtime deployment dir on the customer machine. ### Auto-update mechanism Driven from `Programe\updatecheck.prg::UpdateRoastart()`: 1. Reads a server manifest (`Roastart.xml`) listing items to refresh. 2. For each item, `oUpdate.updatecheck(...)` (defined in shared `COMUN`) compares the local file version with the server's, downloads via HTTP through `wwHTTP`/`wwXMLHTTP`, and replaces in place. 3. `gcSecurityPath` (`\Security\`) holds the decoded `ROA_SECURITY.TXT` derived from the encrypted `ROA_SECURITY.XML` pulled from the server. 4. `UpdateIniROA()` in `roastart.prg` is a one-shot migration that rewrites `settings.ini` and any `instantclient*\tnsnames.ora` to swap the legacy IP `83.103.197.79` for `roa.romfast.ro`. It self-disables via `[update] is_url_roa=1`. If you change update logic, also update `changelog_roastart.txt` — it follows a date-stamped XML-comment block format: ``. Customers see this in-app. ### Database - ODBC to Oracle. Connection bootstraps from `settings.ini` and (for legacy installs) Oracle `tnsnames.ora` under a sibling `instantclient*` folder. - Default constants in `roastart.prg`: `gcHost = "jcsserver"`, `gcuserName = "contafin_ORACLE"`, `gcPassword = "123"` — these are dev defaults overridden at login by the connection form. - `versiune_db.txt` (currently `2015_04_28_02`) is the DB schema stamp the app expects; mismatch should trigger an upgrade flow on the server side. - Always run SQL through `goExecutor.oExecute(lcSql, lcCursor)` — never raw `SQLEXEC` — so the error funnel and connection retry behavior stay consistent. ## Conventions - **Variable scope prefixes** (strict — used pervasively): `g` global / `p` private / `l` local / `t` parameter, then type letter `c` char, `n` numeric, `l` logical, `d` date, `o` object, `a` array. Examples: `gcAppPath`, `lnSucces`, `tnIdGrupProg`, `goExecutor`. - **Commenting out**: VFP code uses `*!*` to mark commented-out blocks (vs. `*` for explanatory comments). When you remove code, prefer deleting it cleanly rather than adding more `*!*` graveyards — but follow the surrounding file's style if it's already heavy with them. - **Modification markers**: changes are often annotated inline as `&& modificare v 2.x.y` followed by a closing `&& modificare v 2.x.y ^`. New significant changes should follow the same convention and bump the version in `changelog_roastart.txt`. - **Error display**: use `aMessagebox(, , )` (project wrapper) rather than `MESSAGEBOX(...)` so localization and styling stay consistent. - **Cursors**: SQL results land in named cursors (`v_obiectegrup`, `cRoastartXml`, etc.). Always close prior cursors with `If Used(<name>) <newline> Use In <name> <newline> Endif` before re-issuing the query — this is the dominant idiom and avoids "cursor in use" failures.