The Blazor Book Library is a modern web application built with a clear separation of concerns, leveraging Blazor for a dynamic frontend and F# with Event Sourcing (Sharpino) for a robust, traceable backend.
graph TB
subgraph "Frontend & HTTP APIs"
UI["Razor Components (.razor)<br/>(Interactive Server/WASM)"]
CLIENT["Blazor Client Project<br/>(Shared UI Logic)"]
CATALOG["Catalog REST API<br/>(CatalogController: /api/catalog)"]
end
subgraph "Application Layer (F# Services & Interop)"
SVC["Domain Services<br/>(BookService, AuthorService, etc.)"]
EXT["External API Services<br/>(GoogleBooks, Gemini Embeddings)"]
SERIAL["Bibliographic Serializers<br/>(FormatSerializers: Dublin Core, MARC, MODS, ONIX, etc.)"]
end
subgraph "Domain Layer (Sharpino + F#)"
CMD["Commands & Events"]
AGG["Aggregates<br/>(Book, Author, User, Loan)"]
VIEWER["State Viewers<br/>(Materialized Views)"]
end
subgraph "Infrastructure & Data"
PGC["PostgreSQL (Identity DB)<br/>(EF Core Context)"]
PGE["PostgreSQL (Event Store)<br/>(Sharpino.PgStorage)"]
PGV["PostgreSQL (Vector DB)<br/>(pgvector extension)"]
SNAP["Snapshots Cabinet"]
end
%% Relationships
UI --> SVC
CLIENT -.-> UI
CATALOG --> SVC
CATALOG --> SERIAL
SVC --> CMD
SVC --> VIEWER
SVC --> EXT
CMD --> AGG
AGG --> PGE
VIEWER --> SNAP
SNAP --> PGE
PGC --- UI
SVC --> PGV
EXT -- "Vectorized Data" --> PGV
- Interactive Modes: Supports both
InteractiveServer(hosting on the server) andInteractiveWebAssembly(client-side execution) for optimal user experience. - UI Components: Uses
QuickGridfor data density and performance, and custom components likeBookSearchToolbarfor complex filtering. - Barcode & Vision Integration: Utilizes JS-interop with
ZXingfor real-time ISBN scanning via device cameras, and camera OCR capture for multi-paper tables of contents and covers. - Interactive Geo-Location Mapping: Utilizes JS-interop with Leaflet (
tenantMap.js) for visual pin-placement of library and user geographical coordinates. - Conversational Assistant UI: Provides the AI Librarian interface with multi-turn chat, grounded markdown citations (
book://protocol), and voice/speech interaction. - Catalog Interoperability REST API (
CatalogController): Exposes headless endpoints under/api/catalogfor external systems and OPAC networks, enabling queries by ISBN, SBN code, or aggregate GUID with format negotiation (?format=andAcceptheader) and multi-tenant isolation.
- CQRS Pattern: Decouples write operations (Commands) from read operations (Viewers/Queries).
- Event Sourcing: Instead of storing the current state, the system stores the sequence of events that led to that state. This provides a full audit trail and the ability to rebuild state at any point in time.
- Sharpino Integration: A specialized library that handles the heavy lifting of event persistence, aggregate execution, and state caching.
- Domain Value Objects: Enforces strict invariants using F# types, including validated
Coordinatesand immutable tenant aggregate state. - Bibliographic Serialization Engine (
FormatSerializers): Pure, side-effect-free F# serialization functions transforming domain models into Dublin Core (DCMES 1.1), MARC21/MARCXML, MODS 3.0, ONIX for Books 3.0, BibTeX, Schema.org (JSON-LD), JSON, and CSV.
- Domain Services: Thin wrappers in F# that orchestrate command execution and state retrieval.
- External Services: Integrates with the Google Books API for metadata lookup and uses Gemini AI for synthetic description generation, vision recognition, and high-performance vector embedding creation.
- AI Librarian RAG Engine: Orchestrates conversational state with vector similarity retrieval to build grounded context for Gemini, citing specific books and papers.
- Proximity & Geo-Location Services: Calculates spherical great-circle distances via the Haversine formula in
TenantService(GetAllowedTenantsByProximityAsync), coupled with client-side coordinate persistence (UserLocationService).
- Dual Database Strategy:
- Identity DB: Uses standard SQL (via EF Core) to manage ASP.NET Identity users, roles, and security tokens.
- Event Store: Uses PostgreSQL to persist JSON-serialized events and snapshots, ensuring high consistency and scalability.
- Vector Database: A specialized PostgreSQL instance powered by the pgvector plugin. It handles vectorized (embedding) information generated by AI models (e.g., Gemini), enabling high-performance semantic searches through cosine similarity operations (
<=>). Vectors are partitioned by item type (bookfor overall volume descriptions andpaperfor individual paper abstracts and texts), enabling deep semantic indexing across complex anthologies and proceedings.
- Identity & OAuth: Integrated with Microsoft Identity and Google OAuth for secure authentication.
- Bot Protection: Implements
Recaptcha v3and a customBotScoreServiceto mitigate automated abuse. - Catalog API Security: Employs dual-tier
X-API-Keyauthentication for external catalog consumers: a global master key (Catalog:ApiKeyinappsettings.json) and per-tenant event-sourced partner keys (bbl_cat_<uniqueId>), combined with strict multi-tenant boundary checks (public vs. private circuits). See tenantkey.md for full architectural details. - Localization: Full support for
it-ITanden-USvia standard .NET localization patterns (IStringLocalizer).
- Anonymization Strategy: To honor GDPR "Right to be Forgotten" while maintaining event stream integrity, the system implements a "Ghosting" pattern.
- Identity Anonymization: The ASP.NET Identity record is anonymized (email/username randomized, personal fields cleared) and permanently disabled.
- Event Integrity: The underlying F# aggregates (e.g.,
User) remain resolvable by their IDs, ensuring that historical records like loans or reservations don't "break" when a user departs.
- Inconsistency Management: Due to the distributed nature of the Event Store (source of truth) and the Vector Database (materialized view), inconsistencies can arise (e.g., deleted events not propagated, or vector database crashes).
- Reconciliation Service: A specialized service provides high-level corrective actions:
- Orphan Purging: Identifies and removes vectors that reference book IDs no longer present in the Event Store.
- State Syncing: Scans the Event Store for books that reference a vector ID, verifies its existence in pgvector, and resets the book's state if the reference is broken.