Files
Nexus.Reader/src/NexusReader.Domain/Entities/KnowledgeUnit.cs
T
Antigravity 23acaeb705 feat: KM-RAG Polyglot Ingestion Pipeline Migration (#46)
Resolves the KM-RAG Polyglot Persistence and Background Ingestion Pipeline Migration task.

### Key Changes
1. **Infrastructure Migration**: Integrated Qdrant (for vector embeddings) and Neo4j (for concept graphs), reducing reliance on PostgreSQL pgvector storage.
2. **Concurrent Background Job**: Implemented a robust Hangfire `EbookIngestionJob` utilizing Polly exponential retries for transient 429 rate limits, executing three core ingestion tasks concurrently via `Task.WhenAll`.
3. **Data Layer**: Standardized database schemas and entities; retained `Pgvector.EntityFrameworkCore` for migration compilation compatibility.
4. **Wasm Client & Tests**: Implemented client support for semantic search and refactored related tests in `QueryTests.cs` to mock `IKnowledgeService`.

### Verification Status
- **Build**: Successfully compiles with `dotnet build NexusReader.slnx --no-restore` (0 errors).
- **Tests**: All 5 unit tests pass cleanly with `dotnet test NexusReader.slnx --no-restore`.

**Resolve** #47

---------

Co-authored-by: Marek Jasiński <jasins.marek@gmail.com>
Reviewed-on: #46
Reviewed-by: Marek Jaisński <jasins.marek@gmail.com>
Co-authored-by: Antigravity <antigravity@google.com>
Co-committed-by: Antigravity <antigravity@google.com>
2026-05-20 18:15:28 +00:00

40 lines
1.1 KiB
C#

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using NexusReader.Domain.Enums;
namespace NexusReader.Domain.Entities;
public class KnowledgeUnit
{
[Key]
[MaxLength(128)]
public string Id { get; set; } = string.Empty; // Hash(Source + Content + Version)
public Guid? EbookId { get; set; }
[ForeignKey(nameof(EbookId))]
public virtual Ebook? Ebook { get; set; }
[Required]
[MaxLength(50)]
public string Version { get; set; } = "1.0";
[Required]
public KnowledgeUnitType Type { get; set; }
[Required]
public string Content { get; set; } = string.Empty;
public string? MetadataJson { get; set; } // e.g. { "page": 1, "path": "Chapter 1 > Intro" }
[Required]
[MaxLength(128)]
public string TenantId { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
// Relationships
public ICollection<KnowledgeUnitLink> OutgoingLinks { get; set; } = new List<KnowledgeUnitLink>();
public ICollection<KnowledgeUnitLink> IncomingLinks { get; set; } = new List<KnowledgeUnitLink>();
}