ath fix
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
> **Authoritative for:** backend architecture, business rules, and the data model (the 38-entity schema).
|
||||
> **Navigation:** you arrived here from `00-CORE.md`. API request/response contracts are in `11-BACKEND-PHASE1.md`. Frontend rules are in `20-FRONTEND.md`. Record work in `Backend/PROGRESS.md`.
|
||||
> **Scope basis:** SRS v1.1. Costing = FIFO · Multi-warehouse · Single-tenant · RBAC deferred (user identity stamped) · approvals auto/config-gated · vendor invoice + 3-way match deferred to Accounting.
|
||||
> **Authentication:** delegated to the **external AuthHex identity provider** (separate service). ERPCore is a **resource server** that only *validates* AuthHex's RS256 JWTs — it does not issue tokens or own a login endpoint. See A.4 (Authentication / Audit actor). RBAC (per-endpoint) still deferred.
|
||||
> **Authentication:** identity is owned by the **external AuthHex identity provider** (separate service), but as of 2026-07-16 the frontend no longer calls AuthHex directly — all login/registration/recovery/2FA/session traffic is proxied through ERPCore's own `AuthController` (`Controllers/AuthController.cs`, `Services/Auth/*`), which forwards to AuthHex and delivers the resulting session as httpOnly Secure cookies (docs/02-SECURITY.md §B.2). ERPCore still does not mint or sign tokens itself — it only forwards to and validates AuthHex's RS256 JWTs. See A.4 (Authentication / Audit actor) and `11-BACKEND-PHASE1.md §2.0` for the endpoint list. RBAC (per-endpoint) still deferred.
|
||||
|
||||
---
|
||||
|
||||
@@ -49,7 +49,8 @@ HTTP ─► Controller ─► Service ─► Repository ─► UnitOfWork / ErpD
|
||||
|
||||
## A.4 Cross-cutting
|
||||
- **Errors:** RFC 7807 `ProblemDetails` (framework default). Domain exceptions in `System/Errors` carry a stable `code`; a middleware maps them to `ProblemDetails`. Catalog in `11-BACKEND-PHASE1.md §7`.
|
||||
- **Authentication:** ERPCore is a **resource server**. It validates JWTs issued by the **external AuthHex IdP** — algorithm **RS256** (asymmetric RSA), issuer `AuthHex`, audience `AuthHexClient`. AuthHex exposes **no JWKS/OIDC discovery**, so ERPCore is configured with AuthHex's **RSA public key statically** (rotation is a manual config update). Tokens live ~1000 min (prod) / 60 min (dev). A single **door authorization policy** requires an ERP `UserTypeCode`/`RoleCode` claim (AuthHex is a shared IdP, so a valid token alone is not enough); **per-endpoint RBAC stays deferred**.
|
||||
- **Authentication:** ERPCore validates JWTs issued by the **external AuthHex IdP** — algorithm **RS256** (asymmetric RSA), issuer `AuthHex`, audience `AuthHexClient`. AuthHex exposes **no JWKS/OIDC discovery**, so ERPCore is configured with AuthHex's **RSA public key statically** (rotation is a manual config update). Tokens live ~1000 min (prod) / 60 min (dev). A single **door authorization policy** requires an ERP `UserTypeCode`/`RoleCode` claim (AuthHex is a shared IdP, so a valid token alone is not enough); **per-endpoint RBAC stays deferred**.
|
||||
- **Auth proxy:** `AuthController` (`Controllers/AuthController.cs`) is ERPCore's only endpoint group that talks to AuthHex over HTTP — via `IAuthHexClient` (`Infra/Auth/AuthHex/AuthHexClient.cs`, `AuthHex:BaseUrl` config) — and the only place that issues httpOnly `erp_at`/`erp_rt` session cookies (`Infra/Auth/AuthCookieWriter.cs`) plus the `XSRF-TOKEN` double-submit cookie checked by `ValidateCsrfAttribute` on mutating actions. The JWT bearer handler also accepts the `erp_at` cookie as a fallback (`JwtAuthExtensions`'s `OnMessageReceived`) when no `Authorization` header is present, so every other controller keeps working unchanged whether a caller sends a Bearer header or relies on the cookie session.
|
||||
- **Audit actor:** the token carries no `sub`/`nameid`; identity is AuthHex's custom **`UserId` (GUID)** claim. An `ICurrentUser` abstraction (`Infra/Auth`) resolves the acting user from a **local shadow user** — the GUID is mapped (JIT-provisioned) to a local `int` `users.user_id` that all FKs reference (see C.7). Services stamp mutations with it. **Never** trust a `createdBy` from the request body.
|
||||
- **Concurrency:** mutable resources carry a `RowVersion` (`[Timestamp] byte[]`), surfaced as `ETag`; `PUT`/`PATCH` require `If-Match` → `412` on mismatch.
|
||||
- **Numbering:** document numbers come from `NumberSequence` (per doc type, per year), issued inside the same transaction as the document.
|
||||
@@ -200,7 +201,7 @@ UI: responsive; count/pick screens handheld-friendly; status badges; mandatory-f
|
||||
|---|---|---|
|
||||
| NFR-01 | Performance | Single item/warehouse enquiry + valuation < 2s under normal load; ledger posting transactional, < 1s per line. |
|
||||
| NFR-02 | Integrity | FIFO layer consumption atomic and concurrency-safe; no double-consumption of remaining qty. |
|
||||
| NFR-03 | Security | Users authenticated via the external AuthHex IdP; **password hashing (BCrypt) is AuthHex's responsibility** — ERPCore validates tokens only. Every action attributed to a user and logged. (Role-based enforcement deferred, FR-X-01.) |
|
||||
| NFR-03 | Security | Users authenticated via the external AuthHex IdP, proxied through ERPCore's `AuthController` (docs/11 §2.0); **password hashing (BCrypt) is AuthHex's responsibility** — ERPCore forwards credentials and validates the resulting tokens only, never storing or hashing passwords itself. Every action attributed to a user and logged. (Role-based enforcement deferred, FR-X-01.) |
|
||||
| NFR-04 | Auditability | Audit trail immutable, retained per policy; ledger append-only. |
|
||||
| NFR-05 | Reliability | No stock transaction partially commits; full rollback on failure. |
|
||||
| NFR-06 | Scalability | Growth in items/warehouses/ledger without redesign; ledger indexed for time-series queries. |
|
||||
|
||||
Reference in New Issue
Block a user