diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 1a1babc..6dc5e8d 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -46,6 +46,14 @@ - `FdsInvoiceData` / `FdsReminderData` are **pure data holders** (parse + properties). Loading, persistence and PDF generation belong in the services — never `Task.Run(...).Wait()` sync-over-async. - Data access stays SQL-first via OCORE helpers (`getSQLDataSet_async`, `setSQLValue_async`) + stored procedures; no EF Core. +## MFR ERP integration +- `MFR_RESTClient` talks to the **mfr (Mobile Field Report)** ERP over REST/OData. Its contract (base URLs, auth, OData conventions, pagination, error/retry, deep-create + document-upload) is documented in **`MFR_RESTClient/Docs/mfr_interface_description.md`** — **read it before changing the client**. +- The client uses HTTP Basic auth, a configurable timeout, and retries idempotent GETs on transient errors (429/5xx, network/timeout) with backoff. Create clients via `IMfrClientFactory` (don't `new` them). The legacy VB project files have been removed; the active project is `MFR_RESTClient.csproj`. + +## Database +- The SQL schema source of truth is the **`Fuchs_Database`** SSDT project. The backend is SQL-first (stored procedures, table types like `fds__tt__bankingtransactions`, functions via OCORE helpers — no EF Core). +- When you change a stored proc name/params or a table type, update **both** the SSDT project and the calling C# in the same change. Verify every `[dbo].[…]` the backend calls actually exists in `Fuchs_Database`. + ## Bank statement parsing (MT940 + CAMT) - Two parsers feed the same banking pipeline: the external `MT940Parser` (SWIFT text) and the in-repo **`CAMTParser`** project (ISO 20022 camt.052/053/054 XML). - `BankingService.ParseToDatatable` **auto-detects** the format (XML → CAMT, else MT940) and maps both into the `fds__tt__bankingtransactions` schema. The `bam/up` handler and the frontend file picker accept both (`.sta/.mt940/.txt` and `.xml/.camt`). diff --git a/CLAUDE.md b/CLAUDE.md index 4360a52..618ceef 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -39,6 +39,14 @@ - `FdsInvoiceData` / `FdsReminderData` are **pure data holders**; load/persist/render belongs in services. No `Task.Run(...).Wait()` sync-over-async. - Data access is SQL-first via OCORE helpers + stored procedures (no EF Core). +## MFR ERP integration +- `MFR_RESTClient` is the REST/OData client for the **mfr (Mobile Field Report)** ERP. Its contract (base URLs, auth, OData conventions, pagination, error/retry, deep-create + document-upload) is in **`MFR_RESTClient/Docs/mfr_interface_description.md`** — read it before changing the client. +- HTTP Basic auth; configurable timeout; idempotent GETs retry on transient errors (429/5xx, network/timeout) with backoff. Create clients via `IMfrClientFactory`. Active project is `MFR_RESTClient.csproj` (legacy `.vbproj` removed). + +## Database +- Schema source of truth: **`Fuchs_Database`** SSDT project. SQL-first backend (stored procs, table types e.g. `fds__tt__bankingtransactions`, functions via OCORE — no EF Core). +- Changing a proc signature or table type → update the SSDT project **and** the calling C# together; verify every `[dbo].[…]` the backend calls exists in `Fuchs_Database`. + ## Bank statement parsing (MT940 + CAMT) - `MT940Parser` (external, SWIFT text) and **`CAMTParser`** (in-repo, ISO 20022 camt.052/053/054 XML) feed the same pipeline. - `BankingService.ParseToDatatable` auto-detects (XML → CAMT, else MT940) → `fds__tt__bankingtransactions`. `bam/up` + the frontend accept both formats. `CAMTParser` is namespace-agnostic. Keep both column mappings aligned with the banking schema. @@ -57,4 +65,5 @@ ## Documentation map - `Fuchs/Docs/ARCHITECTURE.md` — solution architecture (keep current when structure changes). - `Fuchs/Docs/USER_GUIDE.md` — end-user process guide. +- `MFR_RESTClient/Docs/mfr_interface_description.md` — mfr ERP REST/OData interface contract. - `.github/instructions/*.instructions.md` — domain-specific contributor guidance. diff --git a/Fuchs/Docs/ARCHITECTURE.md b/Fuchs/Docs/ARCHITECTURE.md index b02d2b6..ec193ba 100644 --- a/Fuchs/Docs/ARCHITECTURE.md +++ b/Fuchs/Docs/ARCHITECTURE.md @@ -13,7 +13,8 @@ The **Fuchs Intranet** solution is a line-of-business web application for **Seba |---|---|---| | **Fuchs** | ASP.NET Core Web (MVC) | Main web application — the intranet | | **Fuchs_DataService** | Console / Windows Service (Topshelf) | Background data sync service (MFR ERP polling) | -| **MFR_RESTClient** | Class Library | REST/OData client for the MFR ERP system | +| **MFR_RESTClient** | Class Library | REST/OData client for the MFR ERP system. The REST/OData contract is documented in `MFR_RESTClient/Docs/mfr_interface_description.md`. | +| **Fuchs_Database** | SSDT (SQL project) | Source of truth for the `fuchs_fds` SQL schema (tables, table types, functions, stored procedures the backend calls). | | **OCORE** | Class Library (shared) | Core utilities: SQL, crypto, email, IO, logging | | **OCORE_web** | Class Library (shared) | Web utilities: MVC helpers, middleware, auth, captcha | | **OCORE_web_pdf** | Class Library (shared) | PDF generation (MigraDoc/PDFsharp, HTML→PDF) | @@ -425,3 +426,14 @@ public class MfrClientFactory : IMfrClientFactory, IDisposable - `BankingService` (`IBankingService`) accepts **both** MT940 (SWIFT text, via the external `MT940Parser`) and **CAMT** (ISO 20022 camt.052/053/054 XML, via the in-repo `CAMTParser`). - `ParseToDatatable` **auto-detects** the format from content (XML → CAMT, else MT940) and maps either into the `fds__tt__bankingtransactions` schema; the `bam/up` handler and the frontend upload accept both. - `CAMTParser` matches elements by **local name** (namespace-agnostic) so it works across every camt schema version. When the banking schema changes, keep the MT940 and CAMT column mappings in `BankingService` aligned. + +## 10. MFR ERP Integration + +- `MFR_RESTClient` is the REST/OData client for the **mfr (Mobile Field Report)** ERP. Its integration contract — base URLs, auth, OData conventions, pagination, error/retry semantics, deep-create and document-upload endpoints — is documented in **`MFR_RESTClient/Docs/mfr_interface_description.md`**. Consult that file before changing the client. +- The client uses HTTP Basic auth, a configurable timeout/user-agent, and **retries idempotent GETs** on transient failures (HTTP 429/5xx, network/timeout) with exponential backoff + jitter (honouring `Retry-After`). `ReadODataAllPages` follows `@odata.nextLink` pagination. +- `Fuchs_DataService` (Topshelf worker) polls MFR on a timer and syncs entities + invoice files; the web app creates clients via `IMfrClientFactory`. + +## 11. Database + +- The SQL schema lives in the **`Fuchs_Database`** SSDT project (source of truth). The backend is SQL-first: it calls stored procedures, table-valued types (e.g. `fds__tt__bankingtransactions`) and functions via OCORE ADO.NET helpers. +- When changing a stored procedure's name/parameters or a table type, update both the SSDT project and the calling C# in the same change, and keep the MT940/CAMT banking column mappings aligned with `fds__tt__bankingtransactions`.