Files
admin/_docs/02_document/modules/common_database_schema_holder.md
T
Oleksandr Bezdieniezhnykh a77b3f8a59 [AZ-529] [AZ-530] Cycle-2 documentation refresh
Refreshes _docs/02_document/ to reflect the cycle-2 auth-modernization
+ CMMC hardening landings (AZ-531..AZ-538). Authoritative source for
the ripple set is ripple_log_cycle2.md.

Covered:
- architecture.md (section 1 rewritten, ADRs 6-9 added)
- data_model.md (sessions, audit_events, user columns, migrations)
- system-flows.md (F1 rewritten; F11-F17 added; F2/F7/F9 minor)
- module-layout.md (cycle-2 sub-component table)
- diagrams/flows/flow_login.md (dual-token + MFA)
- components/{01_data_layer,03_auth_and_security,05_admin_api}
- modules/ (12 new, 8 modified — full Argon2id/ES256/MFA/refresh
  /mission/session/audit/jwks rollup)
- tests/{blackbox,security,traceability-matrix}

Step 13 (Update Docs) output for cycle 2.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 09:22:53 +03:00

2.6 KiB

Module: Azaion.Common.Database.AzaionDbSchemaHolder

Purpose

Static holder for the linq2db MappingSchema that maps C# entities to PostgreSQL table/column naming conventions and handles custom type conversions.

Cycle 1 (2026-05-13)DetectionClass mapping added (AZ-513).

Cycle 2 (2026-05-14)AuditEvent and Session mappings added; User.MfaRecoveryCodes mapped as DataType.BinaryJson (jsonb) to satisfy Npgsql's strict OID matching for jsonb columns (AZ-534).

Public Interface

Member Type Description
MappingSchema static readonly MappingSchema Pre-built schema with column name and type mappings

Internal Logic

Static constructor:

  1. Creates a MappingSchema with a global callback that converts all column names to snake_case via StringExtensions.ToSnakeCase.
  2. Uses FluentMappingBuilder to configure the entities:
    • User — table "users", Id PK (Guid), Role text with Enum.Parse round-trip, UserConfig JSON via Newtonsoft.Json round-trip, MfaRecoveryCodes (AZ-534) as DataType.BinaryJson so Npgsql sends the jsonb OID instead of text (otherwise inserts fail with "column is of type jsonb but expression is of type text").
    • DetectionClass — table "detection_classes", Id PK + identity (DB-assigned).
    • AuditEvent (AZ-537+534) — table "audit_events", Id PK + identity.
    • Session (AZ-531+535+533+534) — table "sessions", Id PK (Guid). All other columns rely on the snake_case auto-mapping.

Dependencies

  • User, RoleEnum, DetectionClass, AuditEvent, Session entities
  • UserConfig (for the JSON conversion)
  • StringExtensions.ToSnakeCase
  • linq2db MappingSchema, FluentMappingBuilder
  • Newtonsoft.Json

Consumers

  • DbFactory.LoadOptions — passes MappingSchema to DataOptions.UseMappingSchema() for both read and write DataOptions (single shared instance).

Data Models

Defines the ORM mapping for users, detection_classes, audit_events, sessions tables.

Configuration

None — all mappings are compile-time. The MappingSchema is built once at first use of the static class and shared across the entire process.

External Integrations

None directly; mappings are used when queries execute against PostgreSQL.

Security

None.

Tests

Exercised end-to-end via the e2e suite. Misconfigured jsonb mapping would surface as a 42804 Postgres error (column is of type jsonb but expression is of type text) on the first MFA confirm — covered by e2e/Azaion.E2E/Tests/MfaLoginTests.cs.