Fuchs_DataService
Explains an mfr merge that failed with "String or binary data would be truncated": SQL Server
(message 8152, or 2628 below compatibility level 150 / without VERBOSE_TRUNCATION_WARNINGS)
does not name the column, and the merge proc copies the staging table into both the
mfr__tt__* table type and the mfr__* target. After such a failure the staged
is compared against the narrower of the two declared widths, so the
error log names the column, the longest value and an entity Id.
Runs only on the failure path — no cost for a successful merge.
One column whose staged values exceed the declared width.
One column whose staged values exceed the declared width.
8152 = classic truncation message; 2628 = verbose variant (compat level 150+).
Char width of every bounded string column of the target table and of its
mfr__tt__ table type (same naming rule as the mfr__updt__ merge proc);
where both declare the column the narrower wins. MAX columns (max_length = -1) are omitted.
Expects parameter @tablename.
Rows of → column name → max chars (case-insensitive).
String columns of holding at least one value longer than the
declared width, one entry per column with the longest value's length and row Id.
Columns without a known width (MAX or not declared) are never reported.
Log-friendly summary; "none detected" when the batch fits the declared widths.
Logs every SQL error through the worker's structured alone — which, when
this worker runs hosted inside the Fuchs web app (ADR 0010), also reaches the OCORE MultiLogger
SQL sink at Warning+ (ADR 0024) and lands in the same fds__debuglog table
FdsDebug.DebugLog used to write to directly. Calling both here would double-write
every row, which is exactly what the original 2026-09-16 log review's back-to-back
"mfr__getSchema"/"fds__getUpdateableRequests" deadlock entries were heading towards once the
SQL sink went live — so this class no longer calls FdsDebug.DebugLog. Passing a
logger is optional; falls back to the static
(set once in Program.cs) so a failing stored procedure is never silently dropped.
FdsDebug.DebugLog remains the primary/only DB-attribution path for every other
call site in this project that doesn't separately log through — it was
deliberately not migrated onto the generic pipeline (see ADR 0024's Consequences).
Max parallel invoice-file downloads (independent per file).
Entity table plus its navigation tables, without blanks: the list of tables whose
(empty) shape is loaded. Empty when the entity table itself is unknown.
Failure path only: names the staged columns wider than the target table / table type allow.
Never throws — a failed lookup is reported in the returned text instead.
Holds the application supplied by the host (the Fuchs web app).
Fuchs_DataService is a library — it has no configuration of its own; the host owns the
connection strings and MFR credentials and injects them via ,
which Program.cs calls once at startup before any use.
Download-filename sanitising shared by every path that hands a document to the browser —
stored documents () and documents regenerated on a miss
(IntranetController.HandleReportDoc, ADR 0025) — so both produce the same name for the
same DocumentName. DocumentName is derived from the user-typed invoice title, so it can carry
path separators ("Wartung 2025/26"), stray editor markup and characters Windows rejects.
Raw DocumentName (may be null, empty, or wrapped in <p>).
Used when nothing usable remains after cleanup.