# Code This folder is where the actual project codebase lives, built incrementally by the `dev-team` agent during sprint execution. It starts empty; `process/00_project_onboarding.md` should run before any code is added here. ## Solution `EnvelopeRenderer.slnx` (open with `dotnet` or Visual Studio 2022+): - `src/EnvelopeRenderer.Cli` — the render CLI. Argument/exit-code contract documented in [`CLI_CONTRACT.md`](CLI_CONTRACT.md); text-only template format in [`TEMPLATE_FORMAT.md`](TEMPLATE_FORMAT.md). - `src/EnvelopeRenderer.Debenu` — isolates the vendor-generated Debenu interop wrapper (linked, unmodified) in its own project so its lack of nullable annotations doesn't leak warnings elsewhere. - `src/EnvelopeRenderer.Cli.Tests` — xUnit tests for the CLI (chosen as the test framework in the absence of a project-wide pick; see `project_config.md`), including one integration test that renders through the real Debenu DLL. - `src/EnvelopeRenderer.Desktop` — the WinForms operator shell. Picks template/CSV/output paths, launches `EnvelopeRenderer.Cli` as a child process against the contract in `CLI_CONTRACT.md`, and shows live progress plus a completion summary while it runs (Sprint 1, Batches 4-5). Contains only Form/UI wiring — see "Running the desktop app" below. - `src/EnvelopeRenderer.Desktop.Core` — UI-independent logic behind the desktop shell (input validation, CLI argument construction, CLI executable discovery, process launch/lifetime tracking, `PROGRESS` stream parsing, and status/summary formatting). Plain `net10.0`, no WinForms dependency, so it's fully unit testable. - `src/EnvelopeRenderer.Desktop.Tests` — xUnit tests for `EnvelopeRenderer.Desktop.Core`. ``` dotnet build EnvelopeRenderer.slnx dotnet test EnvelopeRenderer.slnx dotnet run --project src/EnvelopeRenderer.Cli -- --help # Rendering needs a Debenu license key — see "Debenu license key" in CLI_CONTRACT.md DEBENU_LICENSE_KEY="$(cat ../key.txt)" dotnet run --project src/EnvelopeRenderer.Cli -- \ --template sample-data/sample-envelope-template.xml \ --csv "sample-data/87700 - 999999 - Wilson Township.csv" \ --output out.pdf ``` ## Running the desktop app ``` dotnet run --project src/EnvelopeRenderer.Desktop ``` `EnvelopeRenderer.Desktop.csproj` references `EnvelopeRenderer.Cli.csproj` as a project reference purely so a normal `dotnet build`/`dotnet run` always produces a freshly built `EnvelopeRenderer.Cli.exe` copied next to `EnvelopeRenderer.Desktop.exe` — the desktop app never calls into the CLI's code directly, it only launches that `.exe` as a child process with `--template`/`--csv`/`--output` set from the three pickers, per `CLI_CONTRACT.md`. If the CLI executable has been moved or is deployed separately, point the desktop app at it with the `ENVELOPERENDERER_CLI_PATH` environment variable (see [`Launch/CliExecutablePathResolver.cs`](src/EnvelopeRenderer.Desktop.Core/Launch/CliExecutablePathResolver.cs)). Rendering needs a Debenu license key (see "Debenu license key" in `CLI_CONTRACT.md`) — since the desktop app's child CLI process only inherits whatever environment variables were already present when the desktop app itself was launched (typically none, for a double-clicked `.exe`), the simplest way to supply it here is to drop a `key.txt` file next to `EnvelopeRenderer.Cli.exe` in the build output folder; the CLI finds it automatically without any environment variable setup. The render runs in a hidden child process — the desktop app now reads its `PROGRESS`/`ERROR:` stdout/stderr streams itself (Sprint 1, Batch 5: "Show render progress and completion summary") rather than leaving a separate visible console window, per `CLI_CONTRACT.md`. While a render is running, the status label shows live, non-technical updates (e.g. "128 record(s) processed, 2.1s elapsed..."); once the process exits, it shows a completion summary — success totals and elapsed time on exit `0`, or the failure reason (from the CLI's `failure` progress event, falling back to its stderr `ERROR:` lines for a pre-render validation failure that never reached the render loop) on any other exit code. The Render button stays disabled for the whole run and is only re-enabled once the process actually exits, not the moment it starts, so an operator can't launch a second render against the same output while one is still in flight. A *launch* failure (the CLI executable itself couldn't be started, e.g. missing or moved) is still reported via an inline status message and a message box, distinct from a *render* failure. Note: the CLI/render pipeline does not currently expose a "warning" concept anywhere (e.g. no missing-image placeholder handling exists yet — that belongs to a not-yet-built epic, `backlog/epics/07_dynamic_and_network_image_handling.md`, for a template format that doesn't support images in this text-only slice). The completion summary therefore reports only the fields the CLI actually exposes today (elapsed time, records completed, success/failure) and omits a warning count rather than fabricate one — see [`Launch/RenderCompletionSummaryFormatter.cs`](src/EnvelopeRenderer.Desktop.Core/Launch/RenderCompletionSummaryFormatter.cs). ## Seed assets - Sample CSV data lives in `code/sample-data/87700 - 999999 - Wilson Township.csv`. - A representative text-only #10 envelope template lives in `code/sample-data/sample-envelope-template.xml`. - Debenu interop source lives in `code/vendor/debenu/interop/DebenuPDFLibraryDLL1013.cs`. - Debenu 64-bit DLL lives in `code/vendor/debenu/x64/DebenuPDFLibrary64DLL1013.dll`. - Debenu 32-bit DLL lives in `code/vendor/debenu/x86/DebenuPDFLibraryDLL1013.dll`.