improvement: Tag 테이블 신설 및 도메인 모델 확정 (#243)
All checks were successful
SPMS_API/pipeline/head This commit looks good
All checks were successful
SPMS_API/pipeline/head This commit looks good
Reviewed-on: https://git.ipstein.myds.me/SPMS/SPMS_API/pulls/244
This commit is contained in:
commit
6b4f502bb8
|
|
@ -59,4 +59,10 @@ public static class ErrorCodes
|
|||
public const string FileNotFound = "181";
|
||||
public const string FileTypeNotAllowed = "182";
|
||||
public const string FileSizeExceeded = "183";
|
||||
|
||||
// === Tag (9) ===
|
||||
public const string TagNotFound = "191";
|
||||
public const string TagNameDuplicate = "192";
|
||||
public const string TagNameImmutable = "193";
|
||||
public const string TagLimitExceeded = "194";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,4 +35,5 @@ public class Service : BaseEntity
|
|||
public ICollection<ServiceIp> ServiceIps { get; set; } = new List<ServiceIp>();
|
||||
public ICollection<Device> Devices { get; set; } = new List<Device>();
|
||||
public ICollection<Message> Messages { get; set; } = new List<Message>();
|
||||
public ICollection<Tag> TagList { get; set; } = new List<Tag>();
|
||||
}
|
||||
|
|
|
|||
15
SPMS.Domain/Entities/Tag.cs
Normal file
15
SPMS.Domain/Entities/Tag.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
namespace SPMS.Domain.Entities;
|
||||
|
||||
public class Tag : BaseEntity
|
||||
{
|
||||
public long ServiceId { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public long CreatedBy { get; set; }
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
|
||||
// Navigation
|
||||
public Service Service { get; set; } = null!;
|
||||
public Admin CreatedByAdmin { get; set; } = null!;
|
||||
}
|
||||
9
SPMS.Domain/Interfaces/ITagRepository.cs
Normal file
9
SPMS.Domain/Interfaces/ITagRepository.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
using SPMS.Domain.Entities;
|
||||
|
||||
namespace SPMS.Domain.Interfaces;
|
||||
|
||||
public interface ITagRepository : IRepository<Tag>
|
||||
{
|
||||
Task<Tag?> GetByIdWithServiceAsync(long id);
|
||||
Task<bool> ExistsInServiceAsync(long serviceId, string name);
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ public class AppDbContext : DbContext
|
|||
public DbSet<Banner> Banners => Set<Banner>();
|
||||
public DbSet<Faq> Faqs => Set<Faq>();
|
||||
public DbSet<AppConfig> AppConfigs => Set<AppConfig>();
|
||||
public DbSet<Tag> Tags => Set<Tag>();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ public static class DependencyInjection
|
|||
services.AddScoped<IPushSendLogRepository, PushSendLogRepository>();
|
||||
services.AddScoped<IDailyStatRepository, DailyStatRepository>();
|
||||
services.AddScoped<IWebhookLogRepository, WebhookLogRepository>();
|
||||
services.AddScoped<ITagRepository, TagRepository>();
|
||||
|
||||
// External Services
|
||||
services.AddScoped<IJwtService, JwtService>();
|
||||
|
|
|
|||
1190
SPMS.Infrastructure/Migrations/20260225083135_AddTagTable.Designer.cs
generated
Normal file
1190
SPMS.Infrastructure/Migrations/20260225083135_AddTagTable.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
67
SPMS.Infrastructure/Migrations/20260225083135_AddTagTable.cs
Normal file
67
SPMS.Infrastructure/Migrations/20260225083135_AddTagTable.cs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace SPMS.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddTagTable : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Tag",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<long>(type: "bigint", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
ServiceId = table.Column<long>(type: "bigint", nullable: false),
|
||||
Name = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Description = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
CreatedBy = table.Column<long>(type: "bigint", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Tag", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Tag_Admin_CreatedBy",
|
||||
column: x => x.CreatedBy,
|
||||
principalTable: "Admin",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_Tag_Service_ServiceId",
|
||||
column: x => x.ServiceId,
|
||||
principalTable: "Service",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Tag_CreatedBy",
|
||||
table: "Tag",
|
||||
column: "CreatedBy");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Tag_ServiceId_Name",
|
||||
table: "Tag",
|
||||
columns: new[] { "ServiceId", "Name" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Tag");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -836,6 +836,45 @@ namespace SPMS.Infrastructure.Migrations
|
|||
b.ToTable("SystemLog", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SPMS.Domain.Entities.Tag", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("bigint");
|
||||
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<long>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<long>("CreatedBy")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("varchar(200)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)");
|
||||
|
||||
b.Property<long>("ServiceId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<DateTime?>("UpdatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreatedBy");
|
||||
|
||||
b.HasIndex("ServiceId", "Name")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Tag", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SPMS.Domain.Entities.WebhookLog", b =>
|
||||
{
|
||||
b.Property<long>("Id")
|
||||
|
|
@ -1102,6 +1141,25 @@ namespace SPMS.Infrastructure.Migrations
|
|||
b.Navigation("Service");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SPMS.Domain.Entities.Tag", b =>
|
||||
{
|
||||
b.HasOne("SPMS.Domain.Entities.Admin", "CreatedByAdmin")
|
||||
.WithMany()
|
||||
.HasForeignKey("CreatedBy")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("SPMS.Domain.Entities.Service", "Service")
|
||||
.WithMany("TagList")
|
||||
.HasForeignKey("ServiceId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CreatedByAdmin");
|
||||
|
||||
b.Navigation("Service");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("SPMS.Domain.Entities.WebhookLog", b =>
|
||||
{
|
||||
b.HasOne("SPMS.Domain.Entities.Service", "Service")
|
||||
|
|
@ -1120,6 +1178,8 @@ namespace SPMS.Infrastructure.Migrations
|
|||
b.Navigation("Messages");
|
||||
|
||||
b.Navigation("ServiceIps");
|
||||
|
||||
b.Navigation("TagList");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using SPMS.Domain.Entities;
|
||||
|
||||
namespace SPMS.Infrastructure.Persistence.Configurations;
|
||||
|
||||
public class TagConfiguration : IEntityTypeConfiguration<Tag>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Tag> builder)
|
||||
{
|
||||
builder.ToTable("Tag");
|
||||
|
||||
builder.HasKey(e => e.Id);
|
||||
builder.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
|
||||
builder.Property(e => e.Name).HasMaxLength(50).IsRequired();
|
||||
builder.Property(e => e.Description).HasMaxLength(200);
|
||||
builder.Property(e => e.CreatedAt).IsRequired();
|
||||
builder.Property(e => e.CreatedBy).IsRequired();
|
||||
builder.Property(e => e.UpdatedAt);
|
||||
|
||||
builder.HasOne(e => e.Service)
|
||||
.WithMany(s => s.TagList)
|
||||
.HasForeignKey(e => e.ServiceId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
builder.HasOne(e => e.CreatedByAdmin)
|
||||
.WithMany()
|
||||
.HasForeignKey(e => e.CreatedBy)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
builder.HasIndex(e => new { e.ServiceId, e.Name }).IsUnique();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using SPMS.Domain.Entities;
|
||||
using SPMS.Domain.Interfaces;
|
||||
|
||||
namespace SPMS.Infrastructure.Persistence.Repositories;
|
||||
|
||||
public class TagRepository : Repository<Tag>, ITagRepository
|
||||
{
|
||||
public TagRepository(AppDbContext context) : base(context) { }
|
||||
|
||||
public async Task<Tag?> GetByIdWithServiceAsync(long id)
|
||||
=> await _dbSet
|
||||
.Include(t => t.Service)
|
||||
.FirstOrDefaultAsync(t => t.Id == id);
|
||||
|
||||
public async Task<bool> ExistsInServiceAsync(long serviceId, string name)
|
||||
=> await _dbSet.AnyAsync(t => t.ServiceId == serviceId && t.Name == name);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user