{"path":"NexusReader.Data/Migrations/20260428184727_InitialPostgres.cs","purpose":"An Entity Framework Core migration that creates the initial PostgreSQL schema for identity tables, application user/ebook tables and a semantic knowledge cache for the NexusReader application.","classification":{"role":"database-config","layer":"data","confidence":0.9,"evidence":["class InitialPostgres derives from Migration (line 10)","uses MigrationBuilder to CreateTable, CreateIndex and DropTable (lines 15-250, 255-281)","imports Npgsql.EntityFrameworkCore.PostgreSQL.Metadata (line 3)"]},"className":"InitialPostgres","methods":[{"name":"Up","line":13,"endLine":250,"signature":"(migrationBuilder: MigrationBuilder) -> void","purpose":"Creates database tables, constraints and indexes needed for initial application schema on Postgres (identity tables, semantic cache, ebooks) during migration up.","calls":[],"actions":[{"id":"create-table_15","kind":"mapping","label":"Create AspNetRoles","line":15,"detail":"migrationBuilder.CreateTable(name: \"AspNetRoles\", columns: { Id, Name, NormalizedName, ConcurrencyStamp }, primary key Id)","visibility":"detail-only","confidence":0.7},{"id":"create-table_29","kind":"mapping","label":"Create AspNetUsers","line":29,"detail":"migrationBuilder.CreateTable(name: \"AspNetUsers\", columns include AITokenLimit, AITokensUsed, TenantId, CurrentPlan, identity fields..., primary key Id)","visibility":"detail-only","confidence":0.7},{"id":"create-table_58","kind":"mapping","label":"Create SemanticKnowledgeCache","line":58,"detail":"migrationBuilder.CreateTable(name: \"SemanticKnowledgeCache\", columns: ContentHash (PK), JsonData, ModelId, PromptVersion, CreatedAt)","visibility":"detail-only","confidence":0.7},{"id":"create-table_73","kind":"mapping","label":"Create AspNetRoleClaims","line":73,"detail":"migrationBuilder.CreateTable(name: \"AspNetRoleClaims\", Id (identity), RoleId, ClaimType, ClaimValue) with FK -> AspNetRoles(Id)","visibility":"detail-only","confidence":0.7},{"id":"create-table_94","kind":"mapping","label":"Create AspNetUserClaims","line":94,"detail":"migrationBuilder.CreateTable(name: \"AspNetUserClaims\", Id (identity), UserId, ClaimType, ClaimValue) with FK -> AspNetUsers(Id)","visibility":"detail-only","confidence":0.7},{"id":"create-table_115","kind":"mapping","label":"Create AspNetUserLogins","line":115,"detail":"migrationBuilder.CreateTable(name: \"AspNetUserLogins\", composite PK(LoginProvider, ProviderKey), UserId) with FK -> AspNetUsers(Id)","visibility":"detail-only","confidence":0.7},{"id":"create-table_135","kind":"mapping","label":"Create AspNetUserRoles","line":135,"detail":"migrationBuilder.CreateTable(name: \"AspNetUserRoles\", composite PK(UserId, RoleId)) with FKs -> AspNetRoles(Id), AspNetUsers(Id)","visibility":"detail-only","confidence":0.7},{"id":"create-table_159","kind":"mapping","label":"Create AspNetUserTokens","line":159,"detail":"migrationBuilder.CreateTable(name: \"AspNetUserTokens\", composite PK(UserId, LoginProvider, Name)) with FK -> AspNetUsers(Id)","visibility":"detail-only","confidence":0.7},{"id":"create-table_179","kind":"mapping","label":"Create Ebooks","line":179,"detail":"migrationBuilder.CreateTable(name: \"Ebooks\", columns: Id (PK, Guid), Title, Author, FilePath, CoverUrl, AddedDate, LastReadDate, UserId) with FK -> AspNetUsers(Id)","visibility":"detail-only","confidence":0.7},{"id":"create-index_203","kind":"mapping","label":"Indexes on identity and domain tables","line":203,"detail":"CreateIndex calls for RoleId, NormalizedName (unique), UserId, NormalizedEmail, NormalizedUserName (unique), Ebooks.UserId, SemanticKnowledgeCache.ContentHash (unique)","visibility":"detail-only","confidence":0.7}]},{"name":"Down","line":253,"endLine":281,"signature":"(migrationBuilder: MigrationBuilder) -> void","purpose":"Drops the tables created by Up in reverse order to roll back the migration.","calls":[],"actions":[{"id":"drop-table_255","kind":"mapping","label":"Drop AspNetRoleClaims","line":255,"detail":"migrationBuilder.DropTable(name: \"AspNetRoleClaims\")","visibility":"detail-only","confidence":0.7},{"id":"drop-table_258","kind":"mapping","label":"Drop AspNetUserClaims","line":258,"detail":"migrationBuilder.DropTable(name: \"AspNetUserClaims\")","visibility":"detail-only","confidence":0.7},{"id":"drop-table_261","kind":"mapping","label":"Drop AspNetUserLogins","line":261,"detail":"migrationBuilder.DropTable(name: \"AspNetUserLogins\")","visibility":"detail-only","confidence":0.7},{"id":"drop-table_264","kind":"mapping","label":"Drop AspNetUserRoles","line":264,"detail":"migrationBuilder.DropTable(name: \"AspNetUserRoles\")","visibility":"detail-only","confidence":0.7},{"id":"drop-table_267","kind":"mapping","label":"Drop AspNetUserTokens","line":267,"detail":"migrationBuilder.DropTable(name: \"AspNetUserTokens\")","visibility":"detail-only","confidence":0.7},{"id":"drop-table_270","kind":"mapping","label":"Drop Ebooks","line":270,"detail":"migrationBuilder.DropTable(name: \"Ebooks\")","visibility":"detail-only","confidence":0.7},{"id":"drop-table_273","kind":"mapping","label":"Drop SemanticKnowledgeCache","line":273,"detail":"migrationBuilder.DropTable(name: \"SemanticKnowledgeCache\")","visibility":"detail-only","confidence":0.7},{"id":"drop-table_276","kind":"mapping","label":"Drop AspNetRoles","line":276,"detail":"migrationBuilder.DropTable(name: \"AspNetRoles\")","visibility":"detail-only","confidence":0.7},{"id":"drop-table_279","kind":"mapping","label":"Drop AspNetUsers","line":279,"detail":"migrationBuilder.DropTable(name: \"AspNetUsers\")","visibility":"detail-only","confidence":0.7}]}],"types":[{"name":"AspNetRoles","kind":"entity","line":15,"purpose":"Identity roles table used by ASP.NET Identity.","fields":[{"name":"Id","type":"string","required":true,"line":19,"description":"Primary key"},{"name":"Name","type":"string","required":false,"line":20,"description":"Role name (max 256)"},{"name":"NormalizedName","type":"string","required":false,"line":21,"description":"Normalized role name (max 256)"},{"name":"ConcurrencyStamp","type":"string","required":false,"line":22,"description":"Concurrency token"}]},{"name":"AspNetUsers","kind":"entity","line":29,"purpose":"Application users table extended with tenant and AI token tracking fields.","fields":[{"name":"Id","type":"string","required":true,"line":33,"description":"Primary key"},{"name":"AITokenLimit","type":"int","required":true,"line":34,"description":"AI token quota"},{"name":"AITokensUsed","type":"int","required":true,"line":35,"description":"AI tokens consumed"},{"name":"TenantId","type":"Guid","required":true,"line":36,"description":"Tenant identifier"},{"name":"CurrentPlan","type":"string","required":true,"line":37,"description":"User subscription plan"},{"name":"UserName","type":"string","required":false,"line":38,"description":"Username (max 256)"},{"name":"Email","type":"string","required":false,"line":40,"description":"Email (max 256)"},{"name":"EmailConfirmed","type":"bool","required":true,"line":42,"description":"Email confirmed flag"}]},{"name":"SemanticKnowledgeCache","kind":"entity","line":58,"purpose":"Stores cached semantic embeddings/metadata keyed by content hash to avoid recomputation.","fields":[{"name":"ContentHash","type":"string","required":true,"line":62,"description":"Primary key and content fingerprint (max 64)"},{"name":"JsonData","type":"string","required":true,"line":63,"description":"Serialized semantic data"},{"name":"ModelId","type":"string","required":true,"line":64,"description":"Model identifier used for semantic generation"},{"name":"PromptVersion","type":"string","required":true,"line":65,"description":"Prompt/version tag (max 10)"},{"name":"CreatedAt","type":"DateTime","required":true,"line":66,"description":"Record creation timestamp"}]},{"name":"Ebooks","kind":"entity","line":179,"purpose":"Represents ebooks uploaded or tracked by users in the application.","fields":[{"name":"Id","type":"Guid","required":true,"line":183,"description":"Primary key"},{"name":"Title","type":"string","required":true,"line":184,"description":"Ebook title (max 255)"},{"name":"Author","type":"string","required":true,"line":185,"description":"Author name (max 255)"},{"name":"FilePath","type":"string","required":true,"line":186,"description":"Filesystem path or storage reference"},{"name":"CoverUrl","type":"string","required":false,"line":187,"description":"Optional cover image URL"},{"name":"AddedDate","type":"DateTime","required":true,"line":188,"description":"When the ebook was added"},{"name":"LastReadDate","type":"DateTime?","required":false,"line":189,"description":"Optional last-read timestamp"},{"name":"UserId","type":"string","required":true,"line":190,"description":"FK to AspNetUsers(Id)"}]},{"name":"AspNetRoleClaims / AspNetUserClaims / AspNetUserLogins / AspNetUserRoles / AspNetUserTokens","kind":"entity","line":73,"purpose":"Standard ASP.NET Identity auxiliary tables for claims, logins, roles and tokens.","fields":[{"name":"Id / composite keys","type":"int / composite","required":true,"line":77,"description":"Primary keys; some identity columns with FKs to AspNetRoles/AspNetUsers"}]}],"serviceRegistrations":[],"startupActions":[],"dependencies":[],"patterns":["EF Core Migration","Schema Migration","Identity (ASP.NET Core Identity)"],"domainConcepts":["User","Ebook","SemanticKnowledgeCache","Identity Roles/Claims"],"keyDetails":"Postgres-specific migration using Npgsql value generation strategy for integer identity columns, unique indexes on normalized name/email and FK relationships between AspNetUsers and Ebooks; semantic cache keyed by ContentHash to deduplicate semantic computations.","orchestrationMethods":[],"typedContracts":[{"name":"AspNetRoles","kind":"entity","line":15,"fieldCount":4,"evidencePaths":["NexusReader.Data/Migrations/20260428184727_InitialPostgres.cs"]},{"name":"AspNetUsers","kind":"entity","line":29,"fieldCount":8,"evidencePaths":["NexusReader.Data/Migrations/20260428184727_InitialPostgres.cs"]},{"name":"SemanticKnowledgeCache","kind":"entity","line":58,"fieldCount":5,"evidencePaths":["NexusReader.Data/Migrations/20260428184727_InitialPostgres.cs"]},{"name":"Ebooks","kind":"entity","line":179,"fieldCount":8,"evidencePaths":["NexusReader.Data/Migrations/20260428184727_InitialPostgres.cs"]},{"name":"AspNetRoleClaims / AspNetUserClaims / AspNetUserLogins / AspNetUserRoles / AspNetUserTokens","kind":"entity","line":73,"fieldCount":1,"evidencePaths":["NexusReader.Data/Migrations/20260428184727_InitialPostgres.cs"]}],"persistenceInteractions":[],"externalInteractions":[],"evidenceAnchors":[{"kind":"typed-contract","label":"AspNetRoles","line":15,"summary":"entity with 4 fields.","confidence":0.8,"evidencePaths":["NexusReader.Data/Migrations/20260428184727_InitialPostgres.cs"]},{"kind":"typed-contract","label":"AspNetUsers","line":29,"summary":"entity with 8 fields.","confidence":0.8,"evidencePaths":["NexusReader.Data/Migrations/20260428184727_InitialPostgres.cs"]},{"kind":"typed-contract","label":"SemanticKnowledgeCache","line":58,"summary":"entity with 5 fields.","confidence":0.8,"evidencePaths":["NexusReader.Data/Migrations/20260428184727_InitialPostgres.cs"]},{"kind":"typed-contract","label":"Ebooks","line":179,"summary":"entity with 8 fields.","confidence":0.8,"evidencePaths":["NexusReader.Data/Migrations/20260428184727_InitialPostgres.cs"]}],"cacheMetadata":{"schemaVersion":2,"analysisVersion":"2026-05-23.cache-v1","contentChecksum":"06ca9cccdf816f211a25f3817a1f7281209cf9af5f4748ab41bf53eabc133e90","sourceByteSize":13530,"analyzedAt":"2026-05-23T16:23:45.444Z","technology":"dotnet"}}