From f02a3884a2d25927e69c711b96c6d786631fa274 Mon Sep 17 00:00:00 2001 From: SEAN Date: Mon, 19 Jan 2026 16:37:50 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=ED=81=B4=EB=A6=B0=20=EC=95=84?= =?UTF-8?q?=ED=82=A4=ED=85=8D=EC=B3=90=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8=20=EB=B6=84=EB=A6=AC=20(Re?= =?UTF-8?q?solves=20#5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 프로젝트 이름 변경 2. 계층 추가 3. 설정 파일 수정 --- Jenkinsfile | 2 - SPMS.API/Documents/ProjectRule.md | 54 +++++++++++++++++++ {SPMS_API => SPMS.API}/Program.cs | 9 +++- .../Properties/launchSettings.json | 0 .../SPMS.API.csproj | 5 ++ {SPMS_API => SPMS.API}/SPMS_API.http | 0 .../appsettings.Development.json | 0 {SPMS_API => SPMS.API}/appsettings.json | 0 SPMS.Application/SPMS.Application.csproj | 13 +++++ SPMS.Domain/SPMS.Domain.csproj | 9 ++++ SPMS.Infrastructure/AppDbContext.cs | 13 +++++ .../SPMS.Infrastructure.csproj | 18 +++++++ SPMS_API.sln | 20 ++++++- 13 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 SPMS.API/Documents/ProjectRule.md rename {SPMS_API => SPMS.API}/Program.cs (73%) rename {SPMS_API => SPMS.API}/Properties/launchSettings.json (100%) rename SPMS_API/SPMS_API.csproj => SPMS.API/SPMS.API.csproj (84%) rename {SPMS_API => SPMS.API}/SPMS_API.http (100%) rename {SPMS_API => SPMS.API}/appsettings.Development.json (100%) rename {SPMS_API => SPMS.API}/appsettings.json (100%) create mode 100644 SPMS.Application/SPMS.Application.csproj create mode 100644 SPMS.Domain/SPMS.Domain.csproj create mode 100644 SPMS.Infrastructure/AppDbContext.cs create mode 100644 SPMS.Infrastructure/SPMS.Infrastructure.csproj diff --git a/Jenkinsfile b/Jenkinsfile index d6afbc5..dd5c96c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -21,8 +21,6 @@ pipeline { TARGET_BUILD_CONTAINER = 'spms-back-build-release' TARGET_RUN_CONTAINER = 'spms-run-release' echo ">>> [PROD Mode] SET Release Container" - } else { - error "This branch(${branchName}) can't set container (USE develop or main branch)" } else if (branchName == 'staging') { TARGET_BUILD_CONTAINER = 'spms-back-build-staging' diff --git a/SPMS.API/Documents/ProjectRule.md b/SPMS.API/Documents/ProjectRule.md new file mode 100644 index 0000000..bb0a732 --- /dev/null +++ b/SPMS.API/Documents/ProjectRule.md @@ -0,0 +1,54 @@ +## 기술 스택 +| 기술 | 스택 | +|:------------------|:------------------------| +| Framework | .NET 9.0 / ASP.NET Core | +| Database | MariaDB | +| ORM | Entity Framework Core | +| API Documentation | Swagger | +| Logging | Serilog | + +## 프로젝트 구조 +프로젝트는 다음과 같은 구조로 구성되어 있다. + +### Clean Architecture +- 프로젝트는 클린 아키텍처(Clean Architecture)를 기반으로 설계한다. +- 의존성 방향은 **항상 `외부`에서 `내부`** 로 향한다. + - 외부 : DB, UI, API 등 + - 내부 : 비즈니스 로직, 도메인, 애플리케이션 서비스 등 +- + +### 폴더 구조 +```plaintext +SPMS.Server/ +├── 1.Domain/ # 순수 비즈니스 영역 : 외부 의존성 절대 금지! +│ ├── Entities/ # DB 테이블과 매핑될 핵심 객체 (Service, Device, Log...) +│ ├── Enums/ # OsType, SendStatus, TargetType 등 +│ ├── Constants/ # 시스템 전역 상수 (에러 메시지 등) +│ └── Exceptions/ # 비즈니스 로직 전용 예외 (BusinessException) +│ +├── 2.Application/ # [중재자] 흐름 제어 및 인터페이스 정의 +│ ├── Common/ # 공통 응답 포맷 (ResultWrapper, PagedResult) +│ ├── DTOs/ # Request/Response 모델 (서비스 간 데이터 전달용) +│ ├── Interfaces/ # 구현체가 없는 설계도 모음 +│ │ ├── Services/ # IServiceService, IPushService +│ │ ├── Repositories/ # IServiceRepository (DB 접근용 인터페이스) +│ │ └── Infra/ # ICryptoHelper, IFcmClient (외부 기술 인터페이스) +│ └── Services/ # 비즈니스 로직 구현체 (ServiceService, PushService) +│ # 주의: 여기서는 DB나 암호화 라이브러리를 직접 쓰지 않고 '인터페이스'만 주입받아 씀 +│ +├── 3.Infrastructure/ # 실제 기술 구현 (DB, 암호화, FCM) +│ ├── Persistence/ # DB 관련 +│ │ ├── Context/ # AppDbContext (EF Core 설정) +│ │ └── Repositories/ # ServiceRepository (실제 쿼리 수행) +│ ├── Security/ # 암호화/인증 구현 (AesHelper, RsaHelper, JwtGenerator) +│ └── External/ # 외부 시스템 연동 (FcmClient, ApnsClient) +│ +├── 4.Presentation/ # 외부와 연결 +│ ├── Controllers/ # API 엔드포인트 +│ ├── Middlewares/ # GlobalExceptionHandling, Logging +│ └── Filters/ # 권한 체크 등 (AuthFilter) +│ +├── appsettings.json +├── appsettings.Development.json +└── Program.cs +```아 \ No newline at end of file diff --git a/SPMS_API/Program.cs b/SPMS.API/Program.cs similarity index 73% rename from SPMS_API/Program.cs rename to SPMS.API/Program.cs index 7109b79..49e38cc 100644 --- a/SPMS_API/Program.cs +++ b/SPMS.API/Program.cs @@ -1,3 +1,5 @@ +using Microsoft.EntityFrameworkCore; +using SPMS.Infrastructure; var builder = WebApplication.CreateBuilder(new WebApplicationOptions @@ -6,10 +8,15 @@ var builder = WebApplication.CreateBuilder(new WebApplicationOptions ?? "wwwroot" }); - builder.Services.AddControllers(); builder.Services.AddOpenApi(); +var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); + +builder.Services.AddDbContext(options => + options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString))); + + var app = builder.Build(); // Configure the HTTP request pipeline. diff --git a/SPMS_API/Properties/launchSettings.json b/SPMS.API/Properties/launchSettings.json similarity index 100% rename from SPMS_API/Properties/launchSettings.json rename to SPMS.API/Properties/launchSettings.json diff --git a/SPMS_API/SPMS_API.csproj b/SPMS.API/SPMS.API.csproj similarity index 84% rename from SPMS_API/SPMS_API.csproj rename to SPMS.API/SPMS.API.csproj index 293a72a..a4d95a8 100644 --- a/SPMS_API/SPMS_API.csproj +++ b/SPMS.API/SPMS.API.csproj @@ -24,4 +24,9 @@ + + + + + diff --git a/SPMS_API/SPMS_API.http b/SPMS.API/SPMS_API.http similarity index 100% rename from SPMS_API/SPMS_API.http rename to SPMS.API/SPMS_API.http diff --git a/SPMS_API/appsettings.Development.json b/SPMS.API/appsettings.Development.json similarity index 100% rename from SPMS_API/appsettings.Development.json rename to SPMS.API/appsettings.Development.json diff --git a/SPMS_API/appsettings.json b/SPMS.API/appsettings.json similarity index 100% rename from SPMS_API/appsettings.json rename to SPMS.API/appsettings.json diff --git a/SPMS.Application/SPMS.Application.csproj b/SPMS.Application/SPMS.Application.csproj new file mode 100644 index 0000000..e228bb9 --- /dev/null +++ b/SPMS.Application/SPMS.Application.csproj @@ -0,0 +1,13 @@ + + + + net9.0 + enable + enable + + + + + + + diff --git a/SPMS.Domain/SPMS.Domain.csproj b/SPMS.Domain/SPMS.Domain.csproj new file mode 100644 index 0000000..17b910f --- /dev/null +++ b/SPMS.Domain/SPMS.Domain.csproj @@ -0,0 +1,9 @@ + + + + net9.0 + enable + enable + + + diff --git a/SPMS.Infrastructure/AppDbContext.cs b/SPMS.Infrastructure/AppDbContext.cs new file mode 100644 index 0000000..f2dd4da --- /dev/null +++ b/SPMS.Infrastructure/AppDbContext.cs @@ -0,0 +1,13 @@ +using Microsoft.EntityFrameworkCore; // 👈 이거 없으면 DbContext에서 빨간 줄 뜹니다! + +namespace SPMS.Infrastructure; + +public class AppDbContext : DbContext +{ + // 생성자: API 프로젝트에서 옵션(DB 연결 문자열 등)을 주입받기 위함 + public AppDbContext(DbContextOptions options) : base(options) + { + } + + // 나중에 여기에 DbSet Users { get; set; } 같은 테이블들이 추가될 겁니다. +} \ No newline at end of file diff --git a/SPMS.Infrastructure/SPMS.Infrastructure.csproj b/SPMS.Infrastructure/SPMS.Infrastructure.csproj new file mode 100644 index 0000000..c5564a8 --- /dev/null +++ b/SPMS.Infrastructure/SPMS.Infrastructure.csproj @@ -0,0 +1,18 @@ + + + + net9.0 + enable + enable + + + + + + + + + + + + diff --git a/SPMS_API.sln b/SPMS_API.sln index 1ae4d5e..1df68ef 100644 --- a/SPMS_API.sln +++ b/SPMS_API.sln @@ -1,6 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPMS_API", "SPMS_API\SPMS_API.csproj", "{B198CE2E-92BC-4197-9E91-B5D5708FC426}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPMS.API", "SPMS.API\SPMS.API.csproj", "{B198CE2E-92BC-4197-9E91-B5D5708FC426}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPMS.Domain", "SPMS.Domain\SPMS.Domain.csproj", "{C7295844-DE6A-4D2A-A113-ADE3D69CC8B1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPMS.Application", "SPMS.Application\SPMS.Application.csproj", "{695956AE-67AC-4682-A7E5-2580F3C58AEB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPMS.Infrastructure", "SPMS.Infrastructure\SPMS.Infrastructure.csproj", "{214116B2-1A1F-4B0F-9317-53DA0DFE8FFE}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -12,5 +18,17 @@ Global {B198CE2E-92BC-4197-9E91-B5D5708FC426}.Debug|Any CPU.Build.0 = Debug|Any CPU {B198CE2E-92BC-4197-9E91-B5D5708FC426}.Release|Any CPU.ActiveCfg = Release|Any CPU {B198CE2E-92BC-4197-9E91-B5D5708FC426}.Release|Any CPU.Build.0 = Release|Any CPU + {C7295844-DE6A-4D2A-A113-ADE3D69CC8B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C7295844-DE6A-4D2A-A113-ADE3D69CC8B1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C7295844-DE6A-4D2A-A113-ADE3D69CC8B1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C7295844-DE6A-4D2A-A113-ADE3D69CC8B1}.Release|Any CPU.Build.0 = Release|Any CPU + {695956AE-67AC-4682-A7E5-2580F3C58AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {695956AE-67AC-4682-A7E5-2580F3C58AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {695956AE-67AC-4682-A7E5-2580F3C58AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {695956AE-67AC-4682-A7E5-2580F3C58AEB}.Release|Any CPU.Build.0 = Release|Any CPU + {214116B2-1A1F-4B0F-9317-53DA0DFE8FFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {214116B2-1A1F-4B0F-9317-53DA0DFE8FFE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {214116B2-1A1F-4B0F-9317-53DA0DFE8FFE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {214116B2-1A1F-4B0F-9317-53DA0DFE8FFE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal