diff --git a/docker-compose.yml b/docker-compose.yml index d32c884..610de47 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,9 @@ services: + # --- PostgreSQL (pgvector) --- postgres: image: pgvector/pgvector:pg17 container_name: rag-postgres + restart: unless-stopped environment: POSTGRES_DB: rag POSTGRES_USER: rag @@ -19,9 +21,11 @@ services: timeout: 5s retries: 5 + # --- Redis --- redis: image: redis:7-alpine container_name: rag-redis + restart: unless-stopped ports: - "6379:6379" volumes: @@ -34,9 +38,11 @@ services: timeout: 5s retries: 5 + # --- RabbitMQ --- rabbitmq: image: rabbitmq:3-management container_name: rag-rabbitmq + restart: unless-stopped environment: RABBITMQ_DEFAULT_USER: rag RABBITMQ_DEFAULT_PASS: rag123 @@ -53,10 +59,55 @@ services: timeout: 10s retries: 5 + # --- MongoDB (im-system) --- + mongo: + image: mongo:7 + container_name: rag-mongo + restart: unless-stopped + environment: + MONGO_INITDB_ROOT_USERNAME: mongo + MONGO_INITDB_ROOT_PASSWORD: mongo123 + ports: + - "27017:27017" + volumes: + - mongodata:/data/db + networks: + - rag-network + healthcheck: + test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"] + interval: 5s + timeout: 5s + retries: 5 + + # --- RustFS (S3 compatible, file-system) --- + rustfs: + image: rustfs/rustfs:latest + container_name: rag-rustfs + restart: unless-stopped + environment: + RUSTFS_ROOT_USER: minioadmin + RUSTFS_ROOT_PASSWORD: minioadmin + command: server /data --console-address ":9001" + ports: + - "9000:9000" + - "9001:9001" + volumes: + - rustfsdata:/data + networks: + - rag-network + healthcheck: + test: ["CMD", "sh", "-c", "nc -z localhost 9000"] + interval: 5s + timeout: 5s + retries: 5 + start_period: 10s + volumes: pgdata: redisdata: rabbitdata: + mongodata: + rustfsdata: networks: rag-network: diff --git a/docker/initdb/init.sql b/docker/initdb/init.sql index 0aa0fc2..72d31d8 100644 --- a/docker/initdb/init.sql +++ b/docker/initdb/init.sql @@ -1 +1,19 @@ +-- pgvector for rag database +\c rag; CREATE EXTENSION IF NOT EXISTS vector; + +-- Create databases for other services (idempotent) +\c postgres; +DO $$ +BEGIN + IF NOT EXISTS (SELECT FROM pg_database WHERE datname = 'im_system') THEN + PERFORM dblink_exec('dbname=postgres', 'CREATE DATABASE im_system'); + END IF; + IF NOT EXISTS (SELECT FROM pg_database WHERE datname = 'workflow') THEN + PERFORM dblink_exec('dbname=postgres', 'CREATE DATABASE workflow'); + END IF; + IF NOT EXISTS (SELECT FROM pg_database WHERE datname = 'file_system') THEN + PERFORM dblink_exec('dbname=postgres', 'CREATE DATABASE file_system'); + END IF; +END +$$; diff --git a/src/RAG.Api/Program.cs b/src/RAG.Api/Program.cs index c44f5db..b5c0a46 100644 --- a/src/RAG.Api/Program.cs +++ b/src/RAG.Api/Program.cs @@ -7,11 +7,12 @@ using Volo.Abp.DependencyInjection; var builder = WebApplication.CreateBuilder(args); // OTel 日志导出 +var otlpEndpoint = builder.Configuration["OpenTelemetry:OtlpEndpoint"] ?? "http://localhost:4316"; builder.Logging.AddOpenTelemetry(logging => { logging.AddOtlpExporter(options => { - options.Endpoint = new Uri("http://192.168.1.154:4316"); + options.Endpoint = new Uri(otlpEndpoint); }); }); diff --git a/src/RAG.Api/RAGApiModule.cs b/src/RAG.Api/RAGApiModule.cs index 677c898..cd6dcda 100644 --- a/src/RAG.Api/RAGApiModule.cs +++ b/src/RAG.Api/RAGApiModule.cs @@ -27,6 +27,7 @@ public class RAGApiModule : AbpModule var config = services.GetConfiguration(); // OpenTelemetry + var otlpEndpoint = config["OpenTelemetry:OtlpEndpoint"] ?? "http://localhost:4316"; services.AddOpenTelemetry() .ConfigureResource(r => r .AddService(serviceName: "rag-backend", serviceVersion: "1.0.0")) @@ -36,7 +37,7 @@ public class RAGApiModule : AbpModule .AddEntityFrameworkCoreInstrumentation() .AddOtlpExporter(options => { - options.Endpoint = new Uri("http://192.168.1.154:4316"); + options.Endpoint = new Uri(otlpEndpoint); })) .WithMetrics(metrics => metrics .AddAspNetCoreInstrumentation() @@ -44,7 +45,7 @@ public class RAGApiModule : AbpModule .AddRuntimeInstrumentation() .AddOtlpExporter((exporterOptions, readerOptions) => { - exporterOptions.Endpoint = new Uri("http://192.168.1.154:4316"); + exporterOptions.Endpoint = new Uri(otlpEndpoint); })); // FastEndpoints + Swagger diff --git a/src/RAG.Api/appsettings.json b/src/RAG.Api/appsettings.json index f6190d0..a71a36a 100644 --- a/src/RAG.Api/appsettings.json +++ b/src/RAG.Api/appsettings.json @@ -25,8 +25,8 @@ "RabbitMq": { "Host": "localhost", "Port": 5672, - "Username": "guest", - "Password": "guest" + "Username": "rag", + "Password": "rag123" }, "Jwt": { "SigningKey": "RagJwtSecretKey2026MustBeAtLeast32CharsLong!", @@ -36,6 +36,9 @@ "Cookie": { "Secure": false }, + "OpenTelemetry": { + "OtlpEndpoint": "http://localhost:4316" + }, "Ai": { "BaseUrl": "http://localhost:1234/v1", "ApiKey": "lm-studio", diff --git a/src/RAG.Infrastructure/Persistence/Configurations/ChatMessageConfiguration.cs b/src/RAG.Infrastructure/Persistence/Configurations/ChatMessageConfiguration.cs index 6dca63a..f1bb6cc 100644 --- a/src/RAG.Infrastructure/Persistence/Configurations/ChatMessageConfiguration.cs +++ b/src/RAG.Infrastructure/Persistence/Configurations/ChatMessageConfiguration.cs @@ -10,12 +10,17 @@ public class ChatMessageConfiguration : IEntityTypeConfiguration { builder.ToTable("chat_messages"); builder.HasKey(m => m.Id); - builder.Property(m => m.Id).ValueGeneratedNever(); + builder.Property(m => m.Id).ValueGeneratedNever().HasComment("消息ID"); - builder.Property(m => m.Content).IsRequired(); - builder.Property(m => m.Role).IsRequired(); + builder.Property(m => m.ConversationId).HasComment("所属会话ID"); + builder.Property(m => m.Role).IsRequired().HasComment("消息角色:System=0, User=1, Assistant=2"); + builder.Property(m => m.Content).IsRequired().HasComment("消息内容"); + builder.Property(m => m.TokenUsage).HasComment("本次消息消耗的Token数"); - builder.Property(m => m.CreatedBy).HasMaxLength(100); - builder.Property(m => m.UpdatedBy).HasMaxLength(100); + // IAuditable + builder.Property(m => m.CreatedBy).HasMaxLength(100).HasComment("创建人"); + builder.Property(m => m.CreatedAt).HasComment("创建时间"); + builder.Property(m => m.UpdatedBy).HasMaxLength(100).HasComment("更新人"); + builder.Property(m => m.UpdatedAt).HasComment("更新时间"); } } diff --git a/src/RAG.Infrastructure/Persistence/Configurations/ConversationConfiguration.cs b/src/RAG.Infrastructure/Persistence/Configurations/ConversationConfiguration.cs index d81bdd0..7b1fdbd 100644 --- a/src/RAG.Infrastructure/Persistence/Configurations/ConversationConfiguration.cs +++ b/src/RAG.Infrastructure/Persistence/Configurations/ConversationConfiguration.cs @@ -10,15 +10,23 @@ public class ConversationConfiguration : IEntityTypeConfiguration { builder.ToTable("conversations"); builder.HasKey(c => c.Id); - builder.Property(c => c.Id).ValueGeneratedNever(); + builder.Property(c => c.Id).ValueGeneratedNever().HasComment("会话ID"); - builder.Property(c => c.Title).HasMaxLength(200).IsRequired(); - builder.Property(c => c.KnowledgeBaseId).IsRequired(false); + builder.Property(c => c.Title).HasMaxLength(200).IsRequired().HasComment("会话标题"); + builder.Property(c => c.UserId).HasComment("所属用户ID"); + builder.Property(c => c.KnowledgeBaseId).IsRequired(false).HasComment("关联知识库ID,null表示普通对话"); - builder.Property(c => c.CreatedBy).HasMaxLength(100); - builder.Property(c => c.UpdatedBy).HasMaxLength(100); - builder.Property(c => c.IsDeleted).HasDefaultValue(false); - builder.Property(c => c.OperatorIP).HasMaxLength(50); + // IAuditable + builder.Property(c => c.CreatedBy).HasMaxLength(100).HasComment("创建人"); + builder.Property(c => c.CreatedAt).HasComment("创建时间"); + builder.Property(c => c.UpdatedBy).HasMaxLength(100).HasComment("更新人"); + builder.Property(c => c.UpdatedAt).HasComment("更新时间"); + + // ISoftDelete + builder.Property(c => c.IsDeleted).HasDefaultValue(false).HasComment("是否已软删除"); + + // IHasOperatorIP + builder.Property(c => c.OperatorIP).HasMaxLength(50).HasComment("操作者IP地址"); builder.HasOne(c => c.User) .WithMany() diff --git a/src/RAG.Infrastructure/Persistence/Configurations/DocumentChunkConfiguration.cs b/src/RAG.Infrastructure/Persistence/Configurations/DocumentChunkConfiguration.cs index ed5da96..7c91b5c 100644 --- a/src/RAG.Infrastructure/Persistence/Configurations/DocumentChunkConfiguration.cs +++ b/src/RAG.Infrastructure/Persistence/Configurations/DocumentChunkConfiguration.cs @@ -10,13 +10,19 @@ public class DocumentChunkConfiguration : IEntityTypeConfiguration c.Id); - builder.Property(c => c.Id).ValueGeneratedNever(); + builder.Property(c => c.Id).ValueGeneratedNever().HasComment("文档分块ID"); - builder.Property(c => c.Content).IsRequired(); - builder.Ignore(c => c.Embedding); + builder.Property(c => c.DocumentId).HasComment("所属文档ID"); + builder.Property(c => c.Content).IsRequired().HasComment("分块文本内容"); + builder.Property(c => c.ChunkIndex).HasComment("分块序号,从0开始"); + builder.Property(c => c.TokenCount).HasComment("分块Token数量"); + builder.Ignore(c => c.Embedding); // 向量字段使用pgvector,不通过EF Core映射 - builder.Property(c => c.CreatedBy).HasMaxLength(100); - builder.Property(c => c.UpdatedBy).HasMaxLength(100); + // IAuditable + builder.Property(c => c.CreatedBy).HasMaxLength(100).HasComment("创建人"); + builder.Property(c => c.CreatedAt).HasComment("创建时间"); + builder.Property(c => c.UpdatedBy).HasMaxLength(100).HasComment("更新人"); + builder.Property(c => c.UpdatedAt).HasComment("更新时间"); builder.HasIndex(c => c.DocumentId); } diff --git a/src/RAG.Infrastructure/Persistence/Configurations/DocumentConfiguration.cs b/src/RAG.Infrastructure/Persistence/Configurations/DocumentConfiguration.cs index d23fb35..af3c6ab 100644 --- a/src/RAG.Infrastructure/Persistence/Configurations/DocumentConfiguration.cs +++ b/src/RAG.Infrastructure/Persistence/Configurations/DocumentConfiguration.cs @@ -10,17 +10,28 @@ public class DocumentConfiguration : IEntityTypeConfiguration { builder.ToTable("documents"); builder.HasKey(d => d.Id); - builder.Property(d => d.Id).ValueGeneratedNever(); + builder.Property(d => d.Id).ValueGeneratedNever().HasComment("文档ID"); - builder.Property(d => d.Title).HasMaxLength(500).IsRequired(); - builder.Property(d => d.FileName).HasMaxLength(500).IsRequired(); - builder.Property(d => d.FilePath).HasMaxLength(1000).IsRequired(); - builder.Property(d => d.ContentType).HasMaxLength(100).IsRequired(); + builder.Property(d => d.KnowledgeBaseId).HasComment("所属知识库ID"); + builder.Property(d => d.Title).HasMaxLength(500).IsRequired().HasComment("文档标题"); + builder.Property(d => d.FileName).HasMaxLength(500).IsRequired().HasComment("原始文件名"); + builder.Property(d => d.FilePath).HasMaxLength(1000).IsRequired().HasComment("文件存储路径"); + builder.Property(d => d.FileSize).HasComment("文件大小(字节)"); + builder.Property(d => d.ContentType).HasMaxLength(100).IsRequired().HasComment("文件MIME类型"); + builder.Property(d => d.ChunkCount).HasComment("分块数量"); + builder.Property(d => d.Status).HasComment("文档状态:Pending=0, Processing=1, Completed=2, Failed=3"); - builder.Property(d => d.CreatedBy).HasMaxLength(100); - builder.Property(d => d.UpdatedBy).HasMaxLength(100); - builder.Property(d => d.IsDeleted).HasDefaultValue(false); - builder.Property(d => d.OperatorIP).HasMaxLength(50); + // IAuditable + builder.Property(d => d.CreatedBy).HasMaxLength(100).HasComment("创建人"); + builder.Property(d => d.CreatedAt).HasComment("创建时间"); + builder.Property(d => d.UpdatedBy).HasMaxLength(100).HasComment("更新人"); + builder.Property(d => d.UpdatedAt).HasComment("更新时间"); + + // ISoftDelete + builder.Property(d => d.IsDeleted).HasDefaultValue(false).HasComment("是否已软删除"); + + // IHasOperatorIP + builder.Property(d => d.OperatorIP).HasMaxLength(50).HasComment("操作者IP地址"); builder.HasMany(d => d.Chunks) .WithOne(c => c.Document) diff --git a/src/RAG.Infrastructure/Persistence/Configurations/KnowledgeBaseConfiguration.cs b/src/RAG.Infrastructure/Persistence/Configurations/KnowledgeBaseConfiguration.cs index 599b732..1584f67 100644 --- a/src/RAG.Infrastructure/Persistence/Configurations/KnowledgeBaseConfiguration.cs +++ b/src/RAG.Infrastructure/Persistence/Configurations/KnowledgeBaseConfiguration.cs @@ -10,16 +10,26 @@ public class KnowledgeBaseConfiguration : IEntityTypeConfiguration k.Id); - builder.Property(k => k.Id).ValueGeneratedNever(); + builder.Property(k => k.Id).ValueGeneratedNever().HasComment("知识库ID"); - builder.Property(k => k.Name).HasMaxLength(200).IsRequired(); - builder.Property(k => k.Description).HasMaxLength(1000); - builder.Property(k => k.EmbeddingModel).HasMaxLength(100).IsRequired(); + builder.Property(k => k.Name).HasMaxLength(200).IsRequired().HasComment("知识库名称"); + builder.Property(k => k.Description).HasMaxLength(1000).HasComment("知识库描述"); + builder.Property(k => k.EmbeddingModel).HasMaxLength(100).IsRequired().HasComment("嵌入模型名称"); + builder.Property(k => k.ChunkSize).HasComment("分块大小(字符数)"); + builder.Property(k => k.ChunkOverlap).HasComment("分块重叠大小(字符数)"); + builder.Property(k => k.Status).HasComment("知识库状态:Active=0, Inactive=1"); - builder.Property(k => k.CreatedBy).HasMaxLength(100); - builder.Property(k => k.UpdatedBy).HasMaxLength(100); - builder.Property(k => k.IsDeleted).HasDefaultValue(false); - builder.Property(k => k.OperatorIP).HasMaxLength(50); + // IAuditable + builder.Property(k => k.CreatedBy).HasMaxLength(100).HasComment("创建人"); + builder.Property(k => k.CreatedAt).HasComment("创建时间"); + builder.Property(k => k.UpdatedBy).HasMaxLength(100).HasComment("更新人"); + builder.Property(k => k.UpdatedAt).HasComment("更新时间"); + + // ISoftDelete + builder.Property(k => k.IsDeleted).HasDefaultValue(false).HasComment("是否已软删除"); + + // IHasOperatorIP + builder.Property(k => k.OperatorIP).HasMaxLength(50).HasComment("操作者IP地址"); builder.HasMany(k => k.Documents) .WithOne(d => d.KnowledgeBase) diff --git a/src/RAG.Infrastructure/Persistence/Configurations/MenuConfiguration.cs b/src/RAG.Infrastructure/Persistence/Configurations/MenuConfiguration.cs index b5abe1c..b37657a 100644 --- a/src/RAG.Infrastructure/Persistence/Configurations/MenuConfiguration.cs +++ b/src/RAG.Infrastructure/Persistence/Configurations/MenuConfiguration.cs @@ -10,27 +10,36 @@ public class MenuConfiguration : IEntityTypeConfiguration { builder.ToTable("menus"); builder.HasKey(m => m.Id); - builder.Property(m => m.Id).ValueGeneratedNever(); + builder.Property(m => m.Id).ValueGeneratedNever().HasComment("菜单ID"); - builder.Property(m => m.Name).HasMaxLength(100).IsRequired(); - builder.Property(m => m.Path).HasMaxLength(200).IsRequired(); - builder.Property(m => m.Component).HasMaxLength(200); - builder.Property(m => m.Redirect).HasMaxLength(200); - builder.Property(m => m.Title).HasMaxLength(100).IsRequired(); - builder.Property(m => m.Icon).HasMaxLength(100); - builder.Property(m => m.ActiveIcon).HasMaxLength(100); - builder.Property(m => m.Link).HasMaxLength(500); - builder.Property(m => m.Authority).HasMaxLength(200); + builder.Property(m => m.Name).HasMaxLength(100).IsRequired().HasComment("菜单名称(路由name)"); + builder.Property(m => m.Path).HasMaxLength(200).IsRequired().HasComment("路由路径"); + builder.Property(m => m.Component).HasMaxLength(200).HasComment("前端组件路径"); + builder.Property(m => m.Redirect).HasMaxLength(200).HasComment("重定向路径"); + builder.Property(m => m.ParentId).HasComment("父菜单ID,null表示顶级菜单"); + builder.Property(m => m.Title).HasMaxLength(100).IsRequired().HasComment("菜单显示标题"); + builder.Property(m => m.Icon).HasMaxLength(100).HasComment("菜单图标"); + builder.Property(m => m.ActiveIcon).HasMaxLength(100).HasComment("菜单激活状态图标"); + builder.Property(m => m.Order).HasComment("排序序号,值越小越靠前"); + builder.Property(m => m.HideInMenu).HasComment("是否在菜单中隐藏"); + builder.Property(m => m.KeepAlive).HasComment("是否缓存页面状态"); + builder.Property(m => m.AffixTab).HasComment("是否固定标签页"); + builder.Property(m => m.Link).HasMaxLength(500).HasComment("外链地址"); + builder.Property(m => m.NoBasicLayout).HasComment("是否不使用基础布局"); + builder.Property(m => m.MenuVisibleWithForbidden).HasComment("无权限时是否仍显示菜单"); + builder.Property(m => m.Authority).HasMaxLength(200).HasComment("允许访问的角色名,逗号分隔,为空表示所有已认证用户可访问"); // IAuditable - builder.Property(m => m.CreatedBy).HasMaxLength(100); - builder.Property(m => m.UpdatedBy).HasMaxLength(100); + builder.Property(m => m.CreatedBy).HasMaxLength(100).HasComment("创建人"); + builder.Property(m => m.CreatedAt).HasComment("创建时间"); + builder.Property(m => m.UpdatedBy).HasMaxLength(100).HasComment("更新人"); + builder.Property(m => m.UpdatedAt).HasComment("更新时间"); // ISoftDelete - builder.Property(m => m.IsDeleted).HasDefaultValue(false); + builder.Property(m => m.IsDeleted).HasDefaultValue(false).HasComment("是否已软删除"); // IHasOperatorIP - builder.Property(m => m.OperatorIP).HasMaxLength(50); + builder.Property(m => m.OperatorIP).HasMaxLength(50).HasComment("操作者IP地址"); // 自引用:父菜单 builder.HasOne(m => m.Parent) diff --git a/src/RAG.Infrastructure/Persistence/Configurations/PermissionConfiguration.cs b/src/RAG.Infrastructure/Persistence/Configurations/PermissionConfiguration.cs index df01e53..a779cfe 100644 --- a/src/RAG.Infrastructure/Persistence/Configurations/PermissionConfiguration.cs +++ b/src/RAG.Infrastructure/Persistence/Configurations/PermissionConfiguration.cs @@ -10,21 +10,23 @@ public class PermissionConfiguration : IEntityTypeConfiguration { builder.ToTable("permissions"); builder.HasKey(p => p.Id); - builder.Property(p => p.Id).ValueGeneratedNever(); - builder.Property(p => p.Name).HasMaxLength(100).IsRequired(); - builder.Property(p => p.Code).HasMaxLength(50).IsRequired(); - builder.Property(p => p.Description).HasMaxLength(200); - builder.Property(p => p.Group).HasMaxLength(50); + builder.Property(p => p.Id).ValueGeneratedNever().HasComment("权限ID"); + builder.Property(p => p.Name).HasMaxLength(100).IsRequired().HasComment("权限名称"); + builder.Property(p => p.Code).HasMaxLength(50).IsRequired().HasComment("权限编码,如 user:create,唯一"); + builder.Property(p => p.Description).HasMaxLength(200).HasComment("权限描述"); + builder.Property(p => p.Group).HasMaxLength(50).HasComment("权限分组"); // IAuditable - builder.Property(p => p.CreatedBy).HasMaxLength(100); - builder.Property(p => p.UpdatedBy).HasMaxLength(100); + builder.Property(p => p.CreatedBy).HasMaxLength(100).HasComment("创建人"); + builder.Property(p => p.CreatedAt).HasComment("创建时间"); + builder.Property(p => p.UpdatedBy).HasMaxLength(100).HasComment("更新人"); + builder.Property(p => p.UpdatedAt).HasComment("更新时间"); // ISoftDelete - builder.Property(p => p.IsDeleted).HasDefaultValue(false); + builder.Property(p => p.IsDeleted).HasDefaultValue(false).HasComment("是否已软删除"); // IHasOperatorIP - builder.Property(p => p.OperatorIP).HasMaxLength(50); + builder.Property(p => p.OperatorIP).HasMaxLength(50).HasComment("操作者IP地址"); builder.HasIndex(p => p.Code).IsUnique(); diff --git a/src/RAG.Infrastructure/Persistence/Configurations/RefreshTokenConfiguration.cs b/src/RAG.Infrastructure/Persistence/Configurations/RefreshTokenConfiguration.cs index 74cd8db..cd0c675 100644 --- a/src/RAG.Infrastructure/Persistence/Configurations/RefreshTokenConfiguration.cs +++ b/src/RAG.Infrastructure/Persistence/Configurations/RefreshTokenConfiguration.cs @@ -10,12 +10,17 @@ public class RefreshTokenConfiguration : IEntityTypeConfiguration { builder.ToTable("refresh_tokens"); builder.HasKey(rt => rt.Id); - builder.Property(rt => rt.Id).ValueGeneratedNever(); - builder.Property(rt => rt.Token).HasMaxLength(200).IsRequired(); + builder.Property(rt => rt.Id).ValueGeneratedNever().HasComment("刷新令牌ID"); + builder.Property(rt => rt.UserId).HasComment("关联用户ID"); + builder.Property(rt => rt.Token).HasMaxLength(200).IsRequired().HasComment("刷新令牌值,唯一"); + builder.Property(rt => rt.ExpiresAt).HasComment("令牌过期时间"); + builder.Property(rt => rt.IsRevoked).HasComment("是否已撤销"); // IAuditable - builder.Property(rt => rt.CreatedBy).HasMaxLength(100); - builder.Property(rt => rt.UpdatedBy).HasMaxLength(100); + builder.Property(rt => rt.CreatedBy).HasMaxLength(100).HasComment("创建人"); + builder.Property(rt => rt.CreatedAt).HasComment("创建时间"); + builder.Property(rt => rt.UpdatedBy).HasMaxLength(100).HasComment("更新人"); + builder.Property(rt => rt.UpdatedAt).HasComment("更新时间"); builder.HasIndex(rt => rt.Token).IsUnique(); diff --git a/src/RAG.Infrastructure/Persistence/Configurations/RoleConfiguration.cs b/src/RAG.Infrastructure/Persistence/Configurations/RoleConfiguration.cs index a358e8c..5127b91 100644 --- a/src/RAG.Infrastructure/Persistence/Configurations/RoleConfiguration.cs +++ b/src/RAG.Infrastructure/Persistence/Configurations/RoleConfiguration.cs @@ -10,19 +10,21 @@ public class RoleConfiguration : IEntityTypeConfiguration { builder.ToTable("roles"); builder.HasKey(r => r.Id); - builder.Property(r => r.Id).ValueGeneratedNever(); - builder.Property(r => r.Name).HasMaxLength(50).IsRequired(); - builder.Property(r => r.Description).HasMaxLength(200); + builder.Property(r => r.Id).ValueGeneratedNever().HasComment("角色ID"); + builder.Property(r => r.Name).HasMaxLength(50).IsRequired().HasComment("角色名称,唯一"); + builder.Property(r => r.Description).HasMaxLength(200).HasComment("角色描述"); // IAuditable - builder.Property(r => r.CreatedBy).HasMaxLength(100); - builder.Property(r => r.UpdatedBy).HasMaxLength(100); + builder.Property(r => r.CreatedBy).HasMaxLength(100).HasComment("创建人"); + builder.Property(r => r.CreatedAt).HasComment("创建时间"); + builder.Property(r => r.UpdatedBy).HasMaxLength(100).HasComment("更新人"); + builder.Property(r => r.UpdatedAt).HasComment("更新时间"); // ISoftDelete - builder.Property(r => r.IsDeleted).HasDefaultValue(false); + builder.Property(r => r.IsDeleted).HasDefaultValue(false).HasComment("是否已软删除"); // IHasOperatorIP - builder.Property(r => r.OperatorIP).HasMaxLength(50); + builder.Property(r => r.OperatorIP).HasMaxLength(50).HasComment("操作者IP地址"); builder.HasIndex(r => r.Name).IsUnique(); diff --git a/src/RAG.Infrastructure/Persistence/Configurations/RolePermissionConfiguration.cs b/src/RAG.Infrastructure/Persistence/Configurations/RolePermissionConfiguration.cs index 5832ac2..5acdb47 100644 --- a/src/RAG.Infrastructure/Persistence/Configurations/RolePermissionConfiguration.cs +++ b/src/RAG.Infrastructure/Persistence/Configurations/RolePermissionConfiguration.cs @@ -10,9 +10,13 @@ public class RolePermissionConfiguration : IEntityTypeConfiguration new { rp.RoleId, rp.PermissionId }); + builder.Property(rp => rp.RoleId).HasComment("角色ID"); + builder.Property(rp => rp.PermissionId).HasComment("权限ID"); // IAuditable - builder.Property(rp => rp.CreatedBy).HasMaxLength(100); - builder.Property(rp => rp.UpdatedBy).HasMaxLength(100); + builder.Property(rp => rp.CreatedBy).HasMaxLength(100).HasComment("创建人"); + builder.Property(rp => rp.CreatedAt).HasComment("创建时间"); + builder.Property(rp => rp.UpdatedBy).HasMaxLength(100).HasComment("更新人"); + builder.Property(rp => rp.UpdatedAt).HasComment("更新时间"); } } diff --git a/src/RAG.Infrastructure/Persistence/Configurations/UserConfiguration.cs b/src/RAG.Infrastructure/Persistence/Configurations/UserConfiguration.cs index c7acce3..2fb1b37 100644 --- a/src/RAG.Infrastructure/Persistence/Configurations/UserConfiguration.cs +++ b/src/RAG.Infrastructure/Persistence/Configurations/UserConfiguration.cs @@ -10,21 +10,23 @@ public class UserConfiguration : IEntityTypeConfiguration { builder.ToTable("users"); builder.HasKey(u => u.Id); - builder.Property(u => u.Id).ValueGeneratedNever(); - builder.Property(u => u.Username).HasMaxLength(50).IsRequired(); - builder.Property(u => u.Email).HasMaxLength(100).IsRequired(); - builder.Property(u => u.PasswordHash).HasMaxLength(200).IsRequired(); - builder.Property(u => u.IsActive).HasDefaultValue(true); + builder.Property(u => u.Id).ValueGeneratedNever().HasComment("用户ID"); + builder.Property(u => u.Username).HasMaxLength(50).IsRequired().HasComment("用户名,唯一"); + builder.Property(u => u.Email).HasMaxLength(100).IsRequired().HasComment("邮箱地址,唯一"); + builder.Property(u => u.PasswordHash).HasMaxLength(200).IsRequired().HasComment("密码哈希值"); + builder.Property(u => u.IsActive).HasDefaultValue(true).HasComment("是否启用,停用后禁止登录"); // IAuditable - builder.Property(u => u.CreatedBy).HasMaxLength(100); - builder.Property(u => u.UpdatedBy).HasMaxLength(100); + builder.Property(u => u.CreatedBy).HasMaxLength(100).HasComment("创建人"); + builder.Property(u => u.CreatedAt).HasComment("创建时间"); + builder.Property(u => u.UpdatedBy).HasMaxLength(100).HasComment("更新人"); + builder.Property(u => u.UpdatedAt).HasComment("更新时间"); // ISoftDelete - builder.Property(u => u.IsDeleted).HasDefaultValue(false); + builder.Property(u => u.IsDeleted).HasDefaultValue(false).HasComment("是否已软删除"); // IHasOperatorIP - builder.Property(u => u.OperatorIP).HasMaxLength(50); + builder.Property(u => u.OperatorIP).HasMaxLength(50).HasComment("操作者IP地址"); builder.HasIndex(u => u.Username).IsUnique(); builder.HasIndex(u => u.Email).IsUnique(); diff --git a/src/RAG.Infrastructure/Persistence/Configurations/UserRoleConfiguration.cs b/src/RAG.Infrastructure/Persistence/Configurations/UserRoleConfiguration.cs index a37c2e9..1e290c3 100644 --- a/src/RAG.Infrastructure/Persistence/Configurations/UserRoleConfiguration.cs +++ b/src/RAG.Infrastructure/Persistence/Configurations/UserRoleConfiguration.cs @@ -10,9 +10,13 @@ public class UserRoleConfiguration : IEntityTypeConfiguration { builder.ToTable("user_roles"); builder.HasKey(ur => new { ur.UserId, ur.RoleId }); + builder.Property(ur => ur.UserId).HasComment("用户ID"); + builder.Property(ur => ur.RoleId).HasComment("角色ID"); // IAuditable - builder.Property(ur => ur.CreatedBy).HasMaxLength(100); - builder.Property(ur => ur.UpdatedBy).HasMaxLength(100); + builder.Property(ur => ur.CreatedBy).HasMaxLength(100).HasComment("创建人"); + builder.Property(ur => ur.CreatedAt).HasComment("创建时间"); + builder.Property(ur => ur.UpdatedBy).HasMaxLength(100).HasComment("更新人"); + builder.Property(ur => ur.UpdatedAt).HasComment("更新时间"); } } diff --git a/src/RAG.Infrastructure/Persistence/Migrations/20260525062123_AddColumnComments.Designer.cs b/src/RAG.Infrastructure/Persistence/Migrations/20260525062123_AddColumnComments.Designer.cs new file mode 100644 index 0000000..93da7d1 --- /dev/null +++ b/src/RAG.Infrastructure/Persistence/Migrations/20260525062123_AddColumnComments.Designer.cs @@ -0,0 +1,942 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using RAG.Infrastructure.Persistence; + +#nullable disable + +namespace RAG.Infrastructure.Persistence.Migrations +{ + [DbContext(typeof(RagDbContext))] + [Migration("20260525062123_AddColumnComments")] + partial class AddColumnComments + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "vector"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("RAG.Domain.Entities.ChatMessage", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasComment("消息ID"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasComment("消息内容"); + + b.Property("ConversationId") + .HasColumnType("uuid") + .HasComment("所属会话ID"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("创建人"); + + b.Property("Role") + .HasColumnType("integer") + .HasComment("消息角色:System=0, User=1, Assistant=2"); + + b.Property("TokenUsage") + .HasColumnType("integer") + .HasComment("本次消息消耗的Token数"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("更新人"); + + b.HasKey("Id"); + + b.HasIndex("ConversationId"); + + b.ToTable("chat_messages", (string)null); + }); + + modelBuilder.Entity("RAG.Domain.Entities.Conversation", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasComment("会话ID"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("创建人"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasComment("是否已软删除"); + + b.Property("KnowledgeBaseId") + .HasColumnType("uuid") + .HasComment("关联知识库ID,null表示普通对话"); + + b.Property("OperatorIP") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("会话标题"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("更新人"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasComment("所属用户ID"); + + b.HasKey("Id"); + + b.HasIndex("KnowledgeBaseId"); + + b.HasIndex("UserId"); + + b.ToTable("conversations", (string)null); + }); + + modelBuilder.Entity("RAG.Domain.Entities.Document", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasComment("文档ID"); + + b.Property("ChunkCount") + .HasColumnType("integer") + .HasComment("分块数量"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("文件MIME类型"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("创建人"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasComment("原始文件名"); + + b.Property("FilePath") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)") + .HasComment("文件存储路径"); + + b.Property("FileSize") + .HasColumnType("bigint") + .HasComment("文件大小(字节)"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasComment("是否已软删除"); + + b.Property("KnowledgeBaseId") + .HasColumnType("uuid") + .HasComment("所属知识库ID"); + + b.Property("OperatorIP") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); + + b.Property("Status") + .HasColumnType("integer") + .HasComment("文档状态:Pending=0, Processing=1, Completed=2, Failed=3"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasComment("文档标题"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("更新人"); + + b.HasKey("Id"); + + b.HasIndex("KnowledgeBaseId"); + + b.ToTable("documents", (string)null); + }); + + modelBuilder.Entity("RAG.Domain.Entities.DocumentChunk", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasComment("文档分块ID"); + + b.Property("ChunkIndex") + .HasColumnType("integer") + .HasComment("分块序号,从0开始"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasComment("分块文本内容"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("创建人"); + + b.Property("DocumentId") + .HasColumnType("uuid") + .HasComment("所属文档ID"); + + b.Property("TokenCount") + .HasColumnType("integer") + .HasComment("分块Token数量"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("更新人"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.ToTable("document_chunks", (string)null); + }); + + modelBuilder.Entity("RAG.Domain.Entities.KnowledgeBase", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasComment("知识库ID"); + + b.Property("ChunkOverlap") + .HasColumnType("integer") + .HasComment("分块重叠大小(字符数)"); + + b.Property("ChunkSize") + .HasColumnType("integer") + .HasComment("分块大小(字符数)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("创建人"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)") + .HasComment("知识库描述"); + + b.Property("EmbeddingModel") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("嵌入模型名称"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasComment("是否已软删除"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("知识库名称"); + + b.Property("OperatorIP") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); + + b.Property("Status") + .HasColumnType("integer") + .HasComment("知识库状态:Active=0, Inactive=1"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("更新人"); + + b.HasKey("Id"); + + b.ToTable("knowledge_bases", (string)null); + }); + + modelBuilder.Entity("RAG.Domain.Entities.Menu", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasComment("菜单ID"); + + b.Property("ActiveIcon") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("菜单激活状态图标"); + + b.Property("AffixTab") + .HasColumnType("boolean") + .HasComment("是否固定标签页"); + + b.Property("Authority") + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("允许访问的角色名,逗号分隔,为空表示所有已认证用户可访问"); + + b.Property("Component") + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("前端组件路径"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("创建人"); + + b.Property("HideInMenu") + .HasColumnType("boolean") + .HasComment("是否在菜单中隐藏"); + + b.Property("Icon") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("菜单图标"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasComment("是否已软删除"); + + b.Property("KeepAlive") + .HasColumnType("boolean") + .HasComment("是否缓存页面状态"); + + b.Property("Link") + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasComment("外链地址"); + + b.Property("MenuVisibleWithForbidden") + .HasColumnType("boolean") + .HasComment("无权限时是否仍显示菜单"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("菜单名称(路由name)"); + + b.Property("NoBasicLayout") + .HasColumnType("boolean") + .HasComment("是否不使用基础布局"); + + b.Property("OperatorIP") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); + + b.Property("Order") + .HasColumnType("integer") + .HasComment("排序序号,值越小越靠前"); + + b.Property("ParentId") + .HasColumnType("uuid") + .HasComment("父菜单ID,null表示顶级菜单"); + + b.Property("Path") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("路由路径"); + + b.Property("Redirect") + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("重定向路径"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("菜单显示标题"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("更新人"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("menus", (string)null); + }); + + modelBuilder.Entity("RAG.Domain.Entities.Permission", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasComment("权限ID"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("权限编码,如 user:create,唯一"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("创建人"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("权限描述"); + + b.Property("Group") + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("权限分组"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasComment("是否已软删除"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("权限名称"); + + b.Property("OperatorIP") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("更新人"); + + b.HasKey("Id"); + + b.HasIndex("Code") + .IsUnique(); + + b.ToTable("permissions", (string)null); + }); + + modelBuilder.Entity("RAG.Domain.Entities.RefreshToken", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasComment("刷新令牌ID"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("创建人"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone") + .HasComment("令牌过期时间"); + + b.Property("IsRevoked") + .HasColumnType("boolean") + .HasComment("是否已撤销"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("刷新令牌值,唯一"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("更新人"); + + b.Property("UserId") + .HasColumnType("uuid") + .HasComment("关联用户ID"); + + b.HasKey("Id"); + + b.HasIndex("Token") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("refresh_tokens", (string)null); + }); + + modelBuilder.Entity("RAG.Domain.Entities.Role", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasComment("角色ID"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("创建人"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("角色描述"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasComment("是否已软删除"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("角色名称,唯一"); + + b.Property("OperatorIP") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("更新人"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("roles", (string)null); + }); + + modelBuilder.Entity("RAG.Domain.Entities.RolePermission", b => + { + b.Property("RoleId") + .HasColumnType("uuid") + .HasComment("角色ID"); + + b.Property("PermissionId") + .HasColumnType("uuid") + .HasComment("权限ID"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("创建人"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("更新人"); + + b.HasKey("RoleId", "PermissionId"); + + b.HasIndex("PermissionId"); + + b.ToTable("role_permissions", (string)null); + }); + + modelBuilder.Entity("RAG.Domain.Entities.User", b => + { + b.Property("Id") + .HasColumnType("uuid") + .HasComment("用户ID"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("创建人"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("邮箱地址,唯一"); + + b.Property("IsActive") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true) + .HasComment("是否启用,停用后禁止登录"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasComment("是否已软删除"); + + b.Property("OperatorIP") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)") + .HasComment("密码哈希值"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("更新人"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasComment("用户名,唯一"); + + b.HasKey("Id"); + + b.HasIndex("Email") + .IsUnique(); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("users", (string)null); + }); + + modelBuilder.Entity("RAG.Domain.Entities.UserRole", b => + { + b.Property("UserId") + .HasColumnType("uuid") + .HasComment("用户ID"); + + b.Property("RoleId") + .HasColumnType("uuid") + .HasComment("角色ID"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("创建人"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); + + b.Property("UpdatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasComment("更新人"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("user_roles", (string)null); + }); + + modelBuilder.Entity("RAG.Domain.Entities.ChatMessage", b => + { + b.HasOne("RAG.Domain.Entities.Conversation", "Conversation") + .WithMany("Messages") + .HasForeignKey("ConversationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Conversation"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.Conversation", b => + { + b.HasOne("RAG.Domain.Entities.KnowledgeBase", "KnowledgeBase") + .WithMany() + .HasForeignKey("KnowledgeBaseId"); + + b.HasOne("RAG.Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("KnowledgeBase"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.Document", b => + { + b.HasOne("RAG.Domain.Entities.KnowledgeBase", "KnowledgeBase") + .WithMany("Documents") + .HasForeignKey("KnowledgeBaseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("KnowledgeBase"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.DocumentChunk", b => + { + b.HasOne("RAG.Domain.Entities.Document", "Document") + .WithMany("Chunks") + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.Menu", b => + { + b.HasOne("RAG.Domain.Entities.Menu", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.RefreshToken", b => + { + b.HasOne("RAG.Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.RolePermission", b => + { + b.HasOne("RAG.Domain.Entities.Permission", "Permission") + .WithMany("RolePermissions") + .HasForeignKey("PermissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("RAG.Domain.Entities.Role", "Role") + .WithMany("RolePermissions") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Permission"); + + b.Navigation("Role"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.UserRole", b => + { + b.HasOne("RAG.Domain.Entities.Role", "Role") + .WithMany("UserRoles") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("RAG.Domain.Entities.User", "User") + .WithMany("UserRoles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Role"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.Conversation", b => + { + b.Navigation("Messages"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.Document", b => + { + b.Navigation("Chunks"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.KnowledgeBase", b => + { + b.Navigation("Documents"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.Menu", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.Permission", b => + { + b.Navigation("RolePermissions"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.Role", b => + { + b.Navigation("RolePermissions"); + + b.Navigation("UserRoles"); + }); + + modelBuilder.Entity("RAG.Domain.Entities.User", b => + { + b.Navigation("UserRoles"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/RAG.Infrastructure/Persistence/Migrations/20260525062123_AddColumnComments.cs b/src/RAG.Infrastructure/Persistence/Migrations/20260525062123_AddColumnComments.cs new file mode 100644 index 0000000..bf501c8 --- /dev/null +++ b/src/RAG.Infrastructure/Persistence/Migrations/20260525062123_AddColumnComments.cs @@ -0,0 +1,2671 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace RAG.Infrastructure.Persistence.Migrations +{ + /// + public partial class AddColumnComments : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Username", + table: "users", + type: "character varying(50)", + maxLength: 50, + nullable: false, + comment: "用户名,唯一", + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "users", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "更新人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "users", + type: "timestamp with time zone", + nullable: false, + comment: "更新时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "PasswordHash", + table: "users", + type: "character varying(200)", + maxLength: 200, + nullable: false, + comment: "密码哈希值", + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "users", + type: "character varying(50)", + maxLength: 50, + nullable: false, + comment: "操作者IP地址", + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "users", + type: "boolean", + nullable: false, + defaultValue: false, + comment: "是否已软删除", + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false); + + migrationBuilder.AlterColumn( + name: "IsActive", + table: "users", + type: "boolean", + nullable: false, + defaultValue: true, + comment: "是否启用,停用后禁止登录", + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: true); + + migrationBuilder.AlterColumn( + name: "Email", + table: "users", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "邮箱地址,唯一", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "users", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "创建人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "users", + type: "timestamp with time zone", + nullable: false, + comment: "创建时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "users", + type: "uuid", + nullable: false, + comment: "用户ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "user_roles", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "更新人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "user_roles", + type: "timestamp with time zone", + nullable: false, + comment: "更新时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "user_roles", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "创建人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "user_roles", + type: "timestamp with time zone", + nullable: false, + comment: "创建时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "RoleId", + table: "user_roles", + type: "uuid", + nullable: false, + comment: "角色ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "user_roles", + type: "uuid", + nullable: false, + comment: "用户ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "roles", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "更新人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "roles", + type: "timestamp with time zone", + nullable: false, + comment: "更新时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "roles", + type: "character varying(50)", + maxLength: 50, + nullable: false, + comment: "操作者IP地址", + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + + migrationBuilder.AlterColumn( + name: "Name", + table: "roles", + type: "character varying(50)", + maxLength: 50, + nullable: false, + comment: "角色名称,唯一", + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "roles", + type: "boolean", + nullable: false, + defaultValue: false, + comment: "是否已软删除", + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false); + + migrationBuilder.AlterColumn( + name: "Description", + table: "roles", + type: "character varying(200)", + maxLength: 200, + nullable: true, + comment: "角色描述", + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "roles", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "创建人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "roles", + type: "timestamp with time zone", + nullable: false, + comment: "创建时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "roles", + type: "uuid", + nullable: false, + comment: "角色ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "role_permissions", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "更新人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "role_permissions", + type: "timestamp with time zone", + nullable: false, + comment: "更新时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "role_permissions", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "创建人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "role_permissions", + type: "timestamp with time zone", + nullable: false, + comment: "创建时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "PermissionId", + table: "role_permissions", + type: "uuid", + nullable: false, + comment: "权限ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "RoleId", + table: "role_permissions", + type: "uuid", + nullable: false, + comment: "角色ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "refresh_tokens", + type: "uuid", + nullable: false, + comment: "关联用户ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "refresh_tokens", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "更新人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "refresh_tokens", + type: "timestamp with time zone", + nullable: false, + comment: "更新时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "Token", + table: "refresh_tokens", + type: "character varying(200)", + maxLength: 200, + nullable: false, + comment: "刷新令牌值,唯一", + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200); + + migrationBuilder.AlterColumn( + name: "IsRevoked", + table: "refresh_tokens", + type: "boolean", + nullable: false, + comment: "是否已撤销", + oldClrType: typeof(bool), + oldType: "boolean"); + + migrationBuilder.AlterColumn( + name: "ExpiresAt", + table: "refresh_tokens", + type: "timestamp with time zone", + nullable: false, + comment: "令牌过期时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "refresh_tokens", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "创建人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "refresh_tokens", + type: "timestamp with time zone", + nullable: false, + comment: "创建时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "refresh_tokens", + type: "uuid", + nullable: false, + comment: "刷新令牌ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "permissions", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "更新人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "permissions", + type: "timestamp with time zone", + nullable: false, + comment: "更新时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "permissions", + type: "character varying(50)", + maxLength: 50, + nullable: false, + comment: "操作者IP地址", + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + + migrationBuilder.AlterColumn( + name: "Name", + table: "permissions", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "权限名称", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "permissions", + type: "boolean", + nullable: false, + defaultValue: false, + comment: "是否已软删除", + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false); + + migrationBuilder.AlterColumn( + name: "Group", + table: "permissions", + type: "character varying(50)", + maxLength: 50, + nullable: true, + comment: "权限分组", + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Description", + table: "permissions", + type: "character varying(200)", + maxLength: 200, + nullable: true, + comment: "权限描述", + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "permissions", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "创建人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "permissions", + type: "timestamp with time zone", + nullable: false, + comment: "创建时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "Code", + table: "permissions", + type: "character varying(50)", + maxLength: 50, + nullable: false, + comment: "权限编码,如 user:create,唯一", + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + + migrationBuilder.AlterColumn( + name: "Id", + table: "permissions", + type: "uuid", + nullable: false, + comment: "权限ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "menus", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "更新人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "menus", + type: "timestamp with time zone", + nullable: false, + comment: "更新时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "Title", + table: "menus", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "菜单显示标题", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "Redirect", + table: "menus", + type: "character varying(200)", + maxLength: 200, + nullable: true, + comment: "重定向路径", + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Path", + table: "menus", + type: "character varying(200)", + maxLength: 200, + nullable: false, + comment: "路由路径", + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200); + + migrationBuilder.AlterColumn( + name: "ParentId", + table: "menus", + type: "uuid", + nullable: true, + comment: "父菜单ID,null表示顶级菜单", + oldClrType: typeof(Guid), + oldType: "uuid", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Order", + table: "menus", + type: "integer", + nullable: false, + comment: "排序序号,值越小越靠前", + oldClrType: typeof(int), + oldType: "integer"); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "menus", + type: "character varying(50)", + maxLength: 50, + nullable: false, + comment: "操作者IP地址", + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + + migrationBuilder.AlterColumn( + name: "NoBasicLayout", + table: "menus", + type: "boolean", + nullable: false, + comment: "是否不使用基础布局", + oldClrType: typeof(bool), + oldType: "boolean"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "menus", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "菜单名称(路由name)", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "MenuVisibleWithForbidden", + table: "menus", + type: "boolean", + nullable: false, + comment: "无权限时是否仍显示菜单", + oldClrType: typeof(bool), + oldType: "boolean"); + + migrationBuilder.AlterColumn( + name: "Link", + table: "menus", + type: "character varying(500)", + maxLength: 500, + nullable: true, + comment: "外链地址", + oldClrType: typeof(string), + oldType: "character varying(500)", + oldMaxLength: 500, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "KeepAlive", + table: "menus", + type: "boolean", + nullable: true, + comment: "是否缓存页面状态", + oldClrType: typeof(bool), + oldType: "boolean", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "menus", + type: "boolean", + nullable: false, + defaultValue: false, + comment: "是否已软删除", + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false); + + migrationBuilder.AlterColumn( + name: "Icon", + table: "menus", + type: "character varying(100)", + maxLength: 100, + nullable: true, + comment: "菜单图标", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "HideInMenu", + table: "menus", + type: "boolean", + nullable: false, + comment: "是否在菜单中隐藏", + oldClrType: typeof(bool), + oldType: "boolean"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "menus", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "创建人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "menus", + type: "timestamp with time zone", + nullable: false, + comment: "创建时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "Component", + table: "menus", + type: "character varying(200)", + maxLength: 200, + nullable: true, + comment: "前端组件路径", + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Authority", + table: "menus", + type: "character varying(200)", + maxLength: 200, + nullable: true, + comment: "允许访问的角色名,逗号分隔,为空表示所有已认证用户可访问", + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "AffixTab", + table: "menus", + type: "boolean", + nullable: true, + comment: "是否固定标签页", + oldClrType: typeof(bool), + oldType: "boolean", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ActiveIcon", + table: "menus", + type: "character varying(100)", + maxLength: 100, + nullable: true, + comment: "菜单激活状态图标", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "menus", + type: "uuid", + nullable: false, + comment: "菜单ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "knowledge_bases", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "更新人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "knowledge_bases", + type: "timestamp with time zone", + nullable: false, + comment: "更新时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "Status", + table: "knowledge_bases", + type: "integer", + nullable: false, + comment: "知识库状态:Active=0, Inactive=1", + oldClrType: typeof(int), + oldType: "integer"); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "knowledge_bases", + type: "character varying(50)", + maxLength: 50, + nullable: false, + comment: "操作者IP地址", + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + + migrationBuilder.AlterColumn( + name: "Name", + table: "knowledge_bases", + type: "character varying(200)", + maxLength: 200, + nullable: false, + comment: "知识库名称", + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "knowledge_bases", + type: "boolean", + nullable: false, + defaultValue: false, + comment: "是否已软删除", + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false); + + migrationBuilder.AlterColumn( + name: "EmbeddingModel", + table: "knowledge_bases", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "嵌入模型名称", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "Description", + table: "knowledge_bases", + type: "character varying(1000)", + maxLength: 1000, + nullable: true, + comment: "知识库描述", + oldClrType: typeof(string), + oldType: "character varying(1000)", + oldMaxLength: 1000, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "knowledge_bases", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "创建人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "knowledge_bases", + type: "timestamp with time zone", + nullable: false, + comment: "创建时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "ChunkSize", + table: "knowledge_bases", + type: "integer", + nullable: false, + comment: "分块大小(字符数)", + oldClrType: typeof(int), + oldType: "integer"); + + migrationBuilder.AlterColumn( + name: "ChunkOverlap", + table: "knowledge_bases", + type: "integer", + nullable: false, + comment: "分块重叠大小(字符数)", + oldClrType: typeof(int), + oldType: "integer"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "knowledge_bases", + type: "uuid", + nullable: false, + comment: "知识库ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "documents", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "更新人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "documents", + type: "timestamp with time zone", + nullable: false, + comment: "更新时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "Title", + table: "documents", + type: "character varying(500)", + maxLength: 500, + nullable: false, + comment: "文档标题", + oldClrType: typeof(string), + oldType: "character varying(500)", + oldMaxLength: 500); + + migrationBuilder.AlterColumn( + name: "Status", + table: "documents", + type: "integer", + nullable: false, + comment: "文档状态:Pending=0, Processing=1, Completed=2, Failed=3", + oldClrType: typeof(int), + oldType: "integer"); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "documents", + type: "character varying(50)", + maxLength: 50, + nullable: false, + comment: "操作者IP地址", + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + + migrationBuilder.AlterColumn( + name: "KnowledgeBaseId", + table: "documents", + type: "uuid", + nullable: false, + comment: "所属知识库ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "documents", + type: "boolean", + nullable: false, + defaultValue: false, + comment: "是否已软删除", + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false); + + migrationBuilder.AlterColumn( + name: "FileSize", + table: "documents", + type: "bigint", + nullable: false, + comment: "文件大小(字节)", + oldClrType: typeof(long), + oldType: "bigint"); + + migrationBuilder.AlterColumn( + name: "FilePath", + table: "documents", + type: "character varying(1000)", + maxLength: 1000, + nullable: false, + comment: "文件存储路径", + oldClrType: typeof(string), + oldType: "character varying(1000)", + oldMaxLength: 1000); + + migrationBuilder.AlterColumn( + name: "FileName", + table: "documents", + type: "character varying(500)", + maxLength: 500, + nullable: false, + comment: "原始文件名", + oldClrType: typeof(string), + oldType: "character varying(500)", + oldMaxLength: 500); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "documents", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "创建人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "documents", + type: "timestamp with time zone", + nullable: false, + comment: "创建时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "ContentType", + table: "documents", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "文件MIME类型", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "ChunkCount", + table: "documents", + type: "integer", + nullable: false, + comment: "分块数量", + oldClrType: typeof(int), + oldType: "integer"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "documents", + type: "uuid", + nullable: false, + comment: "文档ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "document_chunks", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "更新人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "document_chunks", + type: "timestamp with time zone", + nullable: false, + comment: "更新时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "TokenCount", + table: "document_chunks", + type: "integer", + nullable: false, + comment: "分块Token数量", + oldClrType: typeof(int), + oldType: "integer"); + + migrationBuilder.AlterColumn( + name: "DocumentId", + table: "document_chunks", + type: "uuid", + nullable: false, + comment: "所属文档ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "document_chunks", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "创建人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "document_chunks", + type: "timestamp with time zone", + nullable: false, + comment: "创建时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "Content", + table: "document_chunks", + type: "text", + nullable: false, + comment: "分块文本内容", + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "ChunkIndex", + table: "document_chunks", + type: "integer", + nullable: false, + comment: "分块序号,从0开始", + oldClrType: typeof(int), + oldType: "integer"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "document_chunks", + type: "uuid", + nullable: false, + comment: "文档分块ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "conversations", + type: "uuid", + nullable: false, + comment: "所属用户ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "conversations", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "更新人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "conversations", + type: "timestamp with time zone", + nullable: false, + comment: "更新时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "Title", + table: "conversations", + type: "character varying(200)", + maxLength: 200, + nullable: false, + comment: "会话标题", + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "conversations", + type: "character varying(50)", + maxLength: 50, + nullable: false, + comment: "操作者IP地址", + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50); + + migrationBuilder.AlterColumn( + name: "KnowledgeBaseId", + table: "conversations", + type: "uuid", + nullable: true, + comment: "关联知识库ID,null表示普通对话", + oldClrType: typeof(Guid), + oldType: "uuid", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "conversations", + type: "boolean", + nullable: false, + defaultValue: false, + comment: "是否已软删除", + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "conversations", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "创建人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "conversations", + type: "timestamp with time zone", + nullable: false, + comment: "创建时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "conversations", + type: "uuid", + nullable: false, + comment: "会话ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "chat_messages", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "更新人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "chat_messages", + type: "timestamp with time zone", + nullable: false, + comment: "更新时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "TokenUsage", + table: "chat_messages", + type: "integer", + nullable: true, + comment: "本次消息消耗的Token数", + oldClrType: typeof(int), + oldType: "integer", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Role", + table: "chat_messages", + type: "integer", + nullable: false, + comment: "消息角色:System=0, User=1, Assistant=2", + oldClrType: typeof(int), + oldType: "integer"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "chat_messages", + type: "character varying(100)", + maxLength: 100, + nullable: false, + comment: "创建人", + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "chat_messages", + type: "timestamp with time zone", + nullable: false, + comment: "创建时间", + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone"); + + migrationBuilder.AlterColumn( + name: "ConversationId", + table: "chat_messages", + type: "uuid", + nullable: false, + comment: "所属会话ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "Content", + table: "chat_messages", + type: "text", + nullable: false, + comment: "消息内容", + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "chat_messages", + type: "uuid", + nullable: false, + comment: "消息ID", + oldClrType: typeof(Guid), + oldType: "uuid"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Username", + table: "users", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldComment: "用户名,唯一"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "users", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "更新人"); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "users", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "更新时间"); + + migrationBuilder.AlterColumn( + name: "PasswordHash", + table: "users", + type: "character varying(200)", + maxLength: 200, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldComment: "密码哈希值"); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "users", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldComment: "操作者IP地址"); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "users", + type: "boolean", + nullable: false, + defaultValue: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false, + oldComment: "是否已软删除"); + + migrationBuilder.AlterColumn( + name: "IsActive", + table: "users", + type: "boolean", + nullable: false, + defaultValue: true, + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: true, + oldComment: "是否启用,停用后禁止登录"); + + migrationBuilder.AlterColumn( + name: "Email", + table: "users", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "邮箱地址,唯一"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "users", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "创建人"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "users", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "创建时间"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "users", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "用户ID"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "user_roles", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "更新人"); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "user_roles", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "更新时间"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "user_roles", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "创建人"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "user_roles", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "创建时间"); + + migrationBuilder.AlterColumn( + name: "RoleId", + table: "user_roles", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "角色ID"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "user_roles", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "用户ID"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "roles", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "更新人"); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "roles", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "更新时间"); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "roles", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldComment: "操作者IP地址"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "roles", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldComment: "角色名称,唯一"); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "roles", + type: "boolean", + nullable: false, + defaultValue: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false, + oldComment: "是否已软删除"); + + migrationBuilder.AlterColumn( + name: "Description", + table: "roles", + type: "character varying(200)", + maxLength: 200, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldNullable: true, + oldComment: "角色描述"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "roles", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "创建人"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "roles", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "创建时间"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "roles", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "角色ID"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "role_permissions", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "更新人"); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "role_permissions", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "更新时间"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "role_permissions", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "创建人"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "role_permissions", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "创建时间"); + + migrationBuilder.AlterColumn( + name: "PermissionId", + table: "role_permissions", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "权限ID"); + + migrationBuilder.AlterColumn( + name: "RoleId", + table: "role_permissions", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "角色ID"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "refresh_tokens", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "关联用户ID"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "refresh_tokens", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "更新人"); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "refresh_tokens", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "更新时间"); + + migrationBuilder.AlterColumn( + name: "Token", + table: "refresh_tokens", + type: "character varying(200)", + maxLength: 200, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldComment: "刷新令牌值,唯一"); + + migrationBuilder.AlterColumn( + name: "IsRevoked", + table: "refresh_tokens", + type: "boolean", + nullable: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldComment: "是否已撤销"); + + migrationBuilder.AlterColumn( + name: "ExpiresAt", + table: "refresh_tokens", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "令牌过期时间"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "refresh_tokens", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "创建人"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "refresh_tokens", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "创建时间"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "refresh_tokens", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "刷新令牌ID"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "permissions", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "更新人"); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "permissions", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "更新时间"); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "permissions", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldComment: "操作者IP地址"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "permissions", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "权限名称"); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "permissions", + type: "boolean", + nullable: false, + defaultValue: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false, + oldComment: "是否已软删除"); + + migrationBuilder.AlterColumn( + name: "Group", + table: "permissions", + type: "character varying(50)", + maxLength: 50, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldNullable: true, + oldComment: "权限分组"); + + migrationBuilder.AlterColumn( + name: "Description", + table: "permissions", + type: "character varying(200)", + maxLength: 200, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldNullable: true, + oldComment: "权限描述"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "permissions", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "创建人"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "permissions", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "创建时间"); + + migrationBuilder.AlterColumn( + name: "Code", + table: "permissions", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldComment: "权限编码,如 user:create,唯一"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "permissions", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "权限ID"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "menus", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "更新人"); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "menus", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "更新时间"); + + migrationBuilder.AlterColumn( + name: "Title", + table: "menus", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "菜单显示标题"); + + migrationBuilder.AlterColumn( + name: "Redirect", + table: "menus", + type: "character varying(200)", + maxLength: 200, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldNullable: true, + oldComment: "重定向路径"); + + migrationBuilder.AlterColumn( + name: "Path", + table: "menus", + type: "character varying(200)", + maxLength: 200, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldComment: "路由路径"); + + migrationBuilder.AlterColumn( + name: "ParentId", + table: "menus", + type: "uuid", + nullable: true, + oldClrType: typeof(Guid), + oldType: "uuid", + oldNullable: true, + oldComment: "父菜单ID,null表示顶级菜单"); + + migrationBuilder.AlterColumn( + name: "Order", + table: "menus", + type: "integer", + nullable: false, + oldClrType: typeof(int), + oldType: "integer", + oldComment: "排序序号,值越小越靠前"); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "menus", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldComment: "操作者IP地址"); + + migrationBuilder.AlterColumn( + name: "NoBasicLayout", + table: "menus", + type: "boolean", + nullable: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldComment: "是否不使用基础布局"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "menus", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "菜单名称(路由name)"); + + migrationBuilder.AlterColumn( + name: "MenuVisibleWithForbidden", + table: "menus", + type: "boolean", + nullable: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldComment: "无权限时是否仍显示菜单"); + + migrationBuilder.AlterColumn( + name: "Link", + table: "menus", + type: "character varying(500)", + maxLength: 500, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(500)", + oldMaxLength: 500, + oldNullable: true, + oldComment: "外链地址"); + + migrationBuilder.AlterColumn( + name: "KeepAlive", + table: "menus", + type: "boolean", + nullable: true, + oldClrType: typeof(bool), + oldType: "boolean", + oldNullable: true, + oldComment: "是否缓存页面状态"); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "menus", + type: "boolean", + nullable: false, + defaultValue: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false, + oldComment: "是否已软删除"); + + migrationBuilder.AlterColumn( + name: "Icon", + table: "menus", + type: "character varying(100)", + maxLength: 100, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldNullable: true, + oldComment: "菜单图标"); + + migrationBuilder.AlterColumn( + name: "HideInMenu", + table: "menus", + type: "boolean", + nullable: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldComment: "是否在菜单中隐藏"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "menus", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "创建人"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "menus", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "创建时间"); + + migrationBuilder.AlterColumn( + name: "Component", + table: "menus", + type: "character varying(200)", + maxLength: 200, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldNullable: true, + oldComment: "前端组件路径"); + + migrationBuilder.AlterColumn( + name: "Authority", + table: "menus", + type: "character varying(200)", + maxLength: 200, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldNullable: true, + oldComment: "允许访问的角色名,逗号分隔,为空表示所有已认证用户可访问"); + + migrationBuilder.AlterColumn( + name: "AffixTab", + table: "menus", + type: "boolean", + nullable: true, + oldClrType: typeof(bool), + oldType: "boolean", + oldNullable: true, + oldComment: "是否固定标签页"); + + migrationBuilder.AlterColumn( + name: "ActiveIcon", + table: "menus", + type: "character varying(100)", + maxLength: 100, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldNullable: true, + oldComment: "菜单激活状态图标"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "menus", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "菜单ID"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "knowledge_bases", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "更新人"); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "knowledge_bases", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "更新时间"); + + migrationBuilder.AlterColumn( + name: "Status", + table: "knowledge_bases", + type: "integer", + nullable: false, + oldClrType: typeof(int), + oldType: "integer", + oldComment: "知识库状态:Active=0, Inactive=1"); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "knowledge_bases", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldComment: "操作者IP地址"); + + migrationBuilder.AlterColumn( + name: "Name", + table: "knowledge_bases", + type: "character varying(200)", + maxLength: 200, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldComment: "知识库名称"); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "knowledge_bases", + type: "boolean", + nullable: false, + defaultValue: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false, + oldComment: "是否已软删除"); + + migrationBuilder.AlterColumn( + name: "EmbeddingModel", + table: "knowledge_bases", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "嵌入模型名称"); + + migrationBuilder.AlterColumn( + name: "Description", + table: "knowledge_bases", + type: "character varying(1000)", + maxLength: 1000, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(1000)", + oldMaxLength: 1000, + oldNullable: true, + oldComment: "知识库描述"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "knowledge_bases", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "创建人"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "knowledge_bases", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "创建时间"); + + migrationBuilder.AlterColumn( + name: "ChunkSize", + table: "knowledge_bases", + type: "integer", + nullable: false, + oldClrType: typeof(int), + oldType: "integer", + oldComment: "分块大小(字符数)"); + + migrationBuilder.AlterColumn( + name: "ChunkOverlap", + table: "knowledge_bases", + type: "integer", + nullable: false, + oldClrType: typeof(int), + oldType: "integer", + oldComment: "分块重叠大小(字符数)"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "knowledge_bases", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "知识库ID"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "documents", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "更新人"); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "documents", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "更新时间"); + + migrationBuilder.AlterColumn( + name: "Title", + table: "documents", + type: "character varying(500)", + maxLength: 500, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(500)", + oldMaxLength: 500, + oldComment: "文档标题"); + + migrationBuilder.AlterColumn( + name: "Status", + table: "documents", + type: "integer", + nullable: false, + oldClrType: typeof(int), + oldType: "integer", + oldComment: "文档状态:Pending=0, Processing=1, Completed=2, Failed=3"); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "documents", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldComment: "操作者IP地址"); + + migrationBuilder.AlterColumn( + name: "KnowledgeBaseId", + table: "documents", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "所属知识库ID"); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "documents", + type: "boolean", + nullable: false, + defaultValue: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false, + oldComment: "是否已软删除"); + + migrationBuilder.AlterColumn( + name: "FileSize", + table: "documents", + type: "bigint", + nullable: false, + oldClrType: typeof(long), + oldType: "bigint", + oldComment: "文件大小(字节)"); + + migrationBuilder.AlterColumn( + name: "FilePath", + table: "documents", + type: "character varying(1000)", + maxLength: 1000, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(1000)", + oldMaxLength: 1000, + oldComment: "文件存储路径"); + + migrationBuilder.AlterColumn( + name: "FileName", + table: "documents", + type: "character varying(500)", + maxLength: 500, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(500)", + oldMaxLength: 500, + oldComment: "原始文件名"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "documents", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "创建人"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "documents", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "创建时间"); + + migrationBuilder.AlterColumn( + name: "ContentType", + table: "documents", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "文件MIME类型"); + + migrationBuilder.AlterColumn( + name: "ChunkCount", + table: "documents", + type: "integer", + nullable: false, + oldClrType: typeof(int), + oldType: "integer", + oldComment: "分块数量"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "documents", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "文档ID"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "document_chunks", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "更新人"); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "document_chunks", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "更新时间"); + + migrationBuilder.AlterColumn( + name: "TokenCount", + table: "document_chunks", + type: "integer", + nullable: false, + oldClrType: typeof(int), + oldType: "integer", + oldComment: "分块Token数量"); + + migrationBuilder.AlterColumn( + name: "DocumentId", + table: "document_chunks", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "所属文档ID"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "document_chunks", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "创建人"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "document_chunks", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "创建时间"); + + migrationBuilder.AlterColumn( + name: "Content", + table: "document_chunks", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "text", + oldComment: "分块文本内容"); + + migrationBuilder.AlterColumn( + name: "ChunkIndex", + table: "document_chunks", + type: "integer", + nullable: false, + oldClrType: typeof(int), + oldType: "integer", + oldComment: "分块序号,从0开始"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "document_chunks", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "文档分块ID"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "conversations", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "所属用户ID"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "conversations", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "更新人"); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "conversations", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "更新时间"); + + migrationBuilder.AlterColumn( + name: "Title", + table: "conversations", + type: "character varying(200)", + maxLength: 200, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(200)", + oldMaxLength: 200, + oldComment: "会话标题"); + + migrationBuilder.AlterColumn( + name: "OperatorIP", + table: "conversations", + type: "character varying(50)", + maxLength: 50, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldComment: "操作者IP地址"); + + migrationBuilder.AlterColumn( + name: "KnowledgeBaseId", + table: "conversations", + type: "uuid", + nullable: true, + oldClrType: typeof(Guid), + oldType: "uuid", + oldNullable: true, + oldComment: "关联知识库ID,null表示普通对话"); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "conversations", + type: "boolean", + nullable: false, + defaultValue: false, + oldClrType: typeof(bool), + oldType: "boolean", + oldDefaultValue: false, + oldComment: "是否已软删除"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "conversations", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "创建人"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "conversations", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "创建时间"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "conversations", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "会话ID"); + + migrationBuilder.AlterColumn( + name: "UpdatedBy", + table: "chat_messages", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "更新人"); + + migrationBuilder.AlterColumn( + name: "UpdatedAt", + table: "chat_messages", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "更新时间"); + + migrationBuilder.AlterColumn( + name: "TokenUsage", + table: "chat_messages", + type: "integer", + nullable: true, + oldClrType: typeof(int), + oldType: "integer", + oldNullable: true, + oldComment: "本次消息消耗的Token数"); + + migrationBuilder.AlterColumn( + name: "Role", + table: "chat_messages", + type: "integer", + nullable: false, + oldClrType: typeof(int), + oldType: "integer", + oldComment: "消息角色:System=0, User=1, Assistant=2"); + + migrationBuilder.AlterColumn( + name: "CreatedBy", + table: "chat_messages", + type: "character varying(100)", + maxLength: 100, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(100)", + oldMaxLength: 100, + oldComment: "创建人"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "chat_messages", + type: "timestamp with time zone", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "timestamp with time zone", + oldComment: "创建时间"); + + migrationBuilder.AlterColumn( + name: "ConversationId", + table: "chat_messages", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "所属会话ID"); + + migrationBuilder.AlterColumn( + name: "Content", + table: "chat_messages", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "text", + oldComment: "消息内容"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "chat_messages", + type: "uuid", + nullable: false, + oldClrType: typeof(Guid), + oldType: "uuid", + oldComment: "消息ID"); + } + } +} diff --git a/src/RAG.Infrastructure/Persistence/Migrations/RagDbContextModelSnapshot.cs b/src/RAG.Infrastructure/Persistence/Migrations/RagDbContextModelSnapshot.cs index e9b52fa..d1f0ed9 100644 --- a/src/RAG.Infrastructure/Persistence/Migrations/RagDbContextModelSnapshot.cs +++ b/src/RAG.Infrastructure/Persistence/Migrations/RagDbContextModelSnapshot.cs @@ -26,36 +26,45 @@ namespace RAG.Infrastructure.Persistence.Migrations modelBuilder.Entity("RAG.Domain.Entities.ChatMessage", b => { b.Property("Id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("消息ID"); b.Property("Content") .IsRequired() - .HasColumnType("text"); + .HasColumnType("text") + .HasComment("消息内容"); b.Property("ConversationId") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("所属会话ID"); b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); b.Property("CreatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("创建人"); b.Property("Role") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasComment("消息角色:System=0, User=1, Assistant=2"); b.Property("TokenUsage") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasComment("本次消息消耗的Token数"); b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); b.Property("UpdatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("更新人"); b.HasKey("Id"); @@ -67,44 +76,54 @@ namespace RAG.Infrastructure.Persistence.Migrations modelBuilder.Entity("RAG.Domain.Entities.Conversation", b => { b.Property("Id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("会话ID"); b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); b.Property("CreatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("创建人"); b.Property("IsDeleted") .ValueGeneratedOnAdd() .HasColumnType("boolean") - .HasDefaultValue(false); + .HasDefaultValue(false) + .HasComment("是否已软删除"); b.Property("KnowledgeBaseId") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("关联知识库ID,null表示普通对话"); b.Property("OperatorIP") .IsRequired() .HasMaxLength(50) - .HasColumnType("character varying(50)"); + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); b.Property("Title") .IsRequired() .HasMaxLength(200) - .HasColumnType("character varying(200)"); + .HasColumnType("character varying(200)") + .HasComment("会话标题"); b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); b.Property("UpdatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("更新人"); b.Property("UserId") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("所属用户ID"); b.HasKey("Id"); @@ -118,65 +137,80 @@ namespace RAG.Infrastructure.Persistence.Migrations modelBuilder.Entity("RAG.Domain.Entities.Document", b => { b.Property("Id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("文档ID"); b.Property("ChunkCount") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasComment("分块数量"); b.Property("ContentType") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("文件MIME类型"); b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); b.Property("CreatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("创建人"); b.Property("FileName") .IsRequired() .HasMaxLength(500) - .HasColumnType("character varying(500)"); + .HasColumnType("character varying(500)") + .HasComment("原始文件名"); b.Property("FilePath") .IsRequired() .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); + .HasColumnType("character varying(1000)") + .HasComment("文件存储路径"); b.Property("FileSize") - .HasColumnType("bigint"); + .HasColumnType("bigint") + .HasComment("文件大小(字节)"); b.Property("IsDeleted") .ValueGeneratedOnAdd() .HasColumnType("boolean") - .HasDefaultValue(false); + .HasDefaultValue(false) + .HasComment("是否已软删除"); b.Property("KnowledgeBaseId") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("所属知识库ID"); b.Property("OperatorIP") .IsRequired() .HasMaxLength(50) - .HasColumnType("character varying(50)"); + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); b.Property("Status") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasComment("文档状态:Pending=0, Processing=1, Completed=2, Failed=3"); b.Property("Title") .IsRequired() .HasMaxLength(500) - .HasColumnType("character varying(500)"); + .HasColumnType("character varying(500)") + .HasComment("文档标题"); b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); b.Property("UpdatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("更新人"); b.HasKey("Id"); @@ -188,36 +222,45 @@ namespace RAG.Infrastructure.Persistence.Migrations modelBuilder.Entity("RAG.Domain.Entities.DocumentChunk", b => { b.Property("Id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("文档分块ID"); b.Property("ChunkIndex") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasComment("分块序号,从0开始"); b.Property("Content") .IsRequired() - .HasColumnType("text"); + .HasColumnType("text") + .HasComment("分块文本内容"); b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); b.Property("CreatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("创建人"); b.Property("DocumentId") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("所属文档ID"); b.Property("TokenCount") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasComment("分块Token数量"); b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); b.Property("UpdatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("更新人"); b.HasKey("Id"); @@ -229,56 +272,69 @@ namespace RAG.Infrastructure.Persistence.Migrations modelBuilder.Entity("RAG.Domain.Entities.KnowledgeBase", b => { b.Property("Id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("知识库ID"); b.Property("ChunkOverlap") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasComment("分块重叠大小(字符数)"); b.Property("ChunkSize") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasComment("分块大小(字符数)"); b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); b.Property("CreatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("创建人"); b.Property("Description") .HasMaxLength(1000) - .HasColumnType("character varying(1000)"); + .HasColumnType("character varying(1000)") + .HasComment("知识库描述"); b.Property("EmbeddingModel") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("嵌入模型名称"); b.Property("IsDeleted") .ValueGeneratedOnAdd() .HasColumnType("boolean") - .HasDefaultValue(false); + .HasDefaultValue(false) + .HasComment("是否已软删除"); b.Property("Name") .IsRequired() .HasMaxLength(200) - .HasColumnType("character varying(200)"); + .HasColumnType("character varying(200)") + .HasComment("知识库名称"); b.Property("OperatorIP") .IsRequired() .HasMaxLength(50) - .HasColumnType("character varying(50)"); + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); b.Property("Status") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasComment("知识库状态:Active=0, Inactive=1"); b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); b.Property("UpdatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("更新人"); b.HasKey("Id"); @@ -288,93 +344,116 @@ namespace RAG.Infrastructure.Persistence.Migrations modelBuilder.Entity("RAG.Domain.Entities.Menu", b => { b.Property("Id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("菜单ID"); b.Property("ActiveIcon") .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("菜单激活状态图标"); b.Property("AffixTab") - .HasColumnType("boolean"); + .HasColumnType("boolean") + .HasComment("是否固定标签页"); b.Property("Authority") .HasMaxLength(200) - .HasColumnType("character varying(200)"); + .HasColumnType("character varying(200)") + .HasComment("允许访问的角色名,逗号分隔,为空表示所有已认证用户可访问"); b.Property("Component") .HasMaxLength(200) - .HasColumnType("character varying(200)"); + .HasColumnType("character varying(200)") + .HasComment("前端组件路径"); b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); b.Property("CreatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("创建人"); b.Property("HideInMenu") - .HasColumnType("boolean"); + .HasColumnType("boolean") + .HasComment("是否在菜单中隐藏"); b.Property("Icon") .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("菜单图标"); b.Property("IsDeleted") .ValueGeneratedOnAdd() .HasColumnType("boolean") - .HasDefaultValue(false); + .HasDefaultValue(false) + .HasComment("是否已软删除"); b.Property("KeepAlive") - .HasColumnType("boolean"); + .HasColumnType("boolean") + .HasComment("是否缓存页面状态"); b.Property("Link") .HasMaxLength(500) - .HasColumnType("character varying(500)"); + .HasColumnType("character varying(500)") + .HasComment("外链地址"); b.Property("MenuVisibleWithForbidden") - .HasColumnType("boolean"); + .HasColumnType("boolean") + .HasComment("无权限时是否仍显示菜单"); b.Property("Name") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("菜单名称(路由name)"); b.Property("NoBasicLayout") - .HasColumnType("boolean"); + .HasColumnType("boolean") + .HasComment("是否不使用基础布局"); b.Property("OperatorIP") .IsRequired() .HasMaxLength(50) - .HasColumnType("character varying(50)"); + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); b.Property("Order") - .HasColumnType("integer"); + .HasColumnType("integer") + .HasComment("排序序号,值越小越靠前"); b.Property("ParentId") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("父菜单ID,null表示顶级菜单"); b.Property("Path") .IsRequired() .HasMaxLength(200) - .HasColumnType("character varying(200)"); + .HasColumnType("character varying(200)") + .HasComment("路由路径"); b.Property("Redirect") .HasMaxLength(200) - .HasColumnType("character varying(200)"); + .HasColumnType("character varying(200)") + .HasComment("重定向路径"); b.Property("Title") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("菜单显示标题"); b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); b.Property("UpdatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("更新人"); b.HasKey("Id"); @@ -386,51 +465,62 @@ namespace RAG.Infrastructure.Persistence.Migrations modelBuilder.Entity("RAG.Domain.Entities.Permission", b => { b.Property("Id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("权限ID"); b.Property("Code") .IsRequired() .HasMaxLength(50) - .HasColumnType("character varying(50)"); + .HasColumnType("character varying(50)") + .HasComment("权限编码,如 user:create,唯一"); b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); b.Property("CreatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("创建人"); b.Property("Description") .HasMaxLength(200) - .HasColumnType("character varying(200)"); + .HasColumnType("character varying(200)") + .HasComment("权限描述"); b.Property("Group") .HasMaxLength(50) - .HasColumnType("character varying(50)"); + .HasColumnType("character varying(50)") + .HasComment("权限分组"); b.Property("IsDeleted") .ValueGeneratedOnAdd() .HasColumnType("boolean") - .HasDefaultValue(false); + .HasDefaultValue(false) + .HasComment("是否已软删除"); b.Property("Name") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("权限名称"); b.Property("OperatorIP") .IsRequired() .HasMaxLength(50) - .HasColumnType("character varying(50)"); + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); b.Property("UpdatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("更新人"); b.HasKey("Id"); @@ -443,37 +533,46 @@ namespace RAG.Infrastructure.Persistence.Migrations modelBuilder.Entity("RAG.Domain.Entities.RefreshToken", b => { b.Property("Id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("刷新令牌ID"); b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); b.Property("CreatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("创建人"); b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("令牌过期时间"); b.Property("IsRevoked") - .HasColumnType("boolean"); + .HasColumnType("boolean") + .HasComment("是否已撤销"); b.Property("Token") .IsRequired() .HasMaxLength(200) - .HasColumnType("character varying(200)"); + .HasColumnType("character varying(200)") + .HasComment("刷新令牌值,唯一"); b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); b.Property("UpdatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("更新人"); b.Property("UserId") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("关联用户ID"); b.HasKey("Id"); @@ -488,42 +587,51 @@ namespace RAG.Infrastructure.Persistence.Migrations modelBuilder.Entity("RAG.Domain.Entities.Role", b => { b.Property("Id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("角色ID"); b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); b.Property("CreatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("创建人"); b.Property("Description") .HasMaxLength(200) - .HasColumnType("character varying(200)"); + .HasColumnType("character varying(200)") + .HasComment("角色描述"); b.Property("IsDeleted") .ValueGeneratedOnAdd() .HasColumnType("boolean") - .HasDefaultValue(false); + .HasDefaultValue(false) + .HasComment("是否已软删除"); b.Property("Name") .IsRequired() .HasMaxLength(50) - .HasColumnType("character varying(50)"); + .HasColumnType("character varying(50)") + .HasComment("角色名称,唯一"); b.Property("OperatorIP") .IsRequired() .HasMaxLength(50) - .HasColumnType("character varying(50)"); + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); b.Property("UpdatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("更新人"); b.HasKey("Id"); @@ -536,26 +644,32 @@ namespace RAG.Infrastructure.Persistence.Migrations modelBuilder.Entity("RAG.Domain.Entities.RolePermission", b => { b.Property("RoleId") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("角色ID"); b.Property("PermissionId") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("权限ID"); b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); b.Property("CreatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("创建人"); b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); b.Property("UpdatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("更新人"); b.HasKey("RoleId", "PermissionId"); @@ -567,53 +681,64 @@ namespace RAG.Infrastructure.Persistence.Migrations modelBuilder.Entity("RAG.Domain.Entities.User", b => { b.Property("Id") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("用户ID"); b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); b.Property("CreatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("创建人"); b.Property("Email") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("邮箱地址,唯一"); b.Property("IsActive") .ValueGeneratedOnAdd() .HasColumnType("boolean") - .HasDefaultValue(true); + .HasDefaultValue(true) + .HasComment("是否启用,停用后禁止登录"); b.Property("IsDeleted") .ValueGeneratedOnAdd() .HasColumnType("boolean") - .HasDefaultValue(false); + .HasDefaultValue(false) + .HasComment("是否已软删除"); b.Property("OperatorIP") .IsRequired() .HasMaxLength(50) - .HasColumnType("character varying(50)"); + .HasColumnType("character varying(50)") + .HasComment("操作者IP地址"); b.Property("PasswordHash") .IsRequired() .HasMaxLength(200) - .HasColumnType("character varying(200)"); + .HasColumnType("character varying(200)") + .HasComment("密码哈希值"); b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); b.Property("UpdatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("更新人"); b.Property("Username") .IsRequired() .HasMaxLength(50) - .HasColumnType("character varying(50)"); + .HasColumnType("character varying(50)") + .HasComment("用户名,唯一"); b.HasKey("Id"); @@ -629,26 +754,32 @@ namespace RAG.Infrastructure.Persistence.Migrations modelBuilder.Entity("RAG.Domain.Entities.UserRole", b => { b.Property("UserId") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("用户ID"); b.Property("RoleId") - .HasColumnType("uuid"); + .HasColumnType("uuid") + .HasComment("角色ID"); b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("创建时间"); b.Property("CreatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("创建人"); b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); + .HasColumnType("timestamp with time zone") + .HasComment("更新时间"); b.Property("UpdatedBy") .IsRequired() .HasMaxLength(100) - .HasColumnType("character varying(100)"); + .HasColumnType("character varying(100)") + .HasComment("更新人"); b.HasKey("UserId", "RoleId");