Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d879255d9 | |||
| 67274cbdb6 | |||
| 9e4346efa9 | |||
| 07b6fc6bb3 | |||
| 366978ce0f | |||
| c0b49959d4 | |||
| 1c685e2285 | |||
| aee4a4d624 |
@@ -22,6 +22,33 @@ jobs:
|
||||
with:
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: pnpm
|
||||
cache-dependency-path: frontend/pnpm-lock.yaml
|
||||
|
||||
- name: Build frontend into Host static assets
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
VERSION_DATE="$(TZ=Asia/Seoul date +%Y.%m.%d)"
|
||||
RELEASE_COUNT="$(git ls-remote --tags origin "refs/tags/v${VERSION_DATE}.*" | wc -l | tr -d ' ')"
|
||||
VERSION_SEQUENCE="$((RELEASE_COUNT + 1))"
|
||||
APP_VERSION="${VERSION_DATE}.${VERSION_SEQUENCE}.${GITHUB_SHA::10}"
|
||||
echo "VITE_APP_VERSION=${APP_VERSION}" >> "$GITHUB_ENV"
|
||||
echo "release_version=${APP_VERSION}"
|
||||
VITE_APP_VERSION="${APP_VERSION}" pnpm build
|
||||
grep -R -q 'app-version' dist
|
||||
grep -R -q 'UI contract 4.0' dist
|
||||
grep -R -q "${APP_VERSION}" dist
|
||||
find ../src/KArtSell.Host/wwwroot -mindepth 1 -delete
|
||||
cp -R dist/. ../src/KArtSell.Host/wwwroot/
|
||||
working-directory: frontend
|
||||
|
||||
- run: dotnet restore KArtSell.sln
|
||||
|
||||
- run: dotnet build KArtSell.sln --no-restore -c Release
|
||||
@@ -58,6 +85,11 @@ jobs:
|
||||
echo ""
|
||||
ssh -i /tmp/deploy_key.pem -o StrictHostKeyChecking=no kjh2064@178.104.200.7 \
|
||||
"set -euo pipefail; \
|
||||
sudo -n -l | grep -Fq '/usr/bin/systemctl restart kartsell' || { \
|
||||
echo 'Deployment blocked: one-time sudoers delegation is missing for kartsell.' >&2; \
|
||||
echo 'Expected: kjh2064 ALL=(root) NOPASSWD: /usr/bin/systemctl restart kartsell' >&2; \
|
||||
exit 77; \
|
||||
}; \
|
||||
export KARTSELL_POSTGRES='${{ secrets.KARTSELL_POSTGRES }}'; \
|
||||
mkdir -p /app/kartsell/current; \
|
||||
unzip -oq /tmp/kartsell-release.zip -d /app/kartsell/current; \
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# AEG-X-009 Decision Package — 결정 필수 항목 통합
|
||||
|
||||
**목표:** DEC-037, DEC-038, DEC-079 3개 미결정 항목을 사람(법무/데이터거버넌스)이 빠르게 승인/반려할 수 있도록 통합 체크리스트 제공
|
||||
|
||||
**Status:** PROPOSED (코드 아님, 문서만)
|
||||
**Date:** 2026-08-07
|
||||
|
||||
---
|
||||
|
||||
## 필수 승인 항목
|
||||
|
||||
### DEC-037: 총수익·상폐·컨센서스 Source/License/SLA
|
||||
|
||||
| 항목 | 현재 상태 | 필수 값 | 담당자 |
|
||||
|------|---------|--------|--------|
|
||||
| **Source** | KRX, OpenDart, Consensus API 후보 | 최종 승인된 소스 목록 | 데이터거버넌스 |
|
||||
| **License** | 라이선스 조건 미확정 | MIT/GPL/Commercial/Custom | 법무 |
|
||||
| **Retention SLA** | 보유 기간 미결정 | 1년/3년/영구 | 콤플라이언스 |
|
||||
| **Update Freshness SLA** | 갱신 빈도 미결정 | Daily/Weekly/Monthly | 데이터 Ops |
|
||||
|
||||
**승인 절차:**
|
||||
- [ ] 법무: 라이선스 검토 및 승인
|
||||
- [ ] 데이터거버넌스: 소스 & 보유기간 확정
|
||||
- [ ] 콤플라이언스: GDPR/PCI-DSS 준수 확인
|
||||
|
||||
---
|
||||
|
||||
### DEC-038: Market Calendar Source & Operator Assignment
|
||||
|
||||
| 항목 | 현재 상태 | 필수 값 | 담당자 |
|
||||
|------|---------|--------|--------|
|
||||
| **Source** | KRX 휴장일/공휴일 API 미통합 | 승인된 데이터 소스 URI | 데이터거버넌스 |
|
||||
| **Owner** | 미배정 | 담당자 이름 (Ops/Data) | Ops Lead |
|
||||
| **Secondary** | 미배정 | 백업 담당자 이름 | Ops Lead |
|
||||
| **Timezone** | 미정 | Asia/Seoul / UTC | 데이터 Arch |
|
||||
|
||||
---
|
||||
|
||||
### DEC-079: 생산 시장 Calendar/Timezone & 휴장정정 SLA
|
||||
|
||||
| 항목 | 현재 상태 | 필수 값 | 담당자 |
|
||||
|------|---------|--------|--------|
|
||||
| **Timezone Standard** | Asia/Seoul 기본 | 공식 표준 선정 | 데이터 Arch |
|
||||
| **Holiday Corrections** | 임시 공휴일 정정 절차 미정 | 정정 요청 → 승인 → 반영 SLA | Ops/Legal |
|
||||
| **Effectiveness** | 정정 유효시점 미정 | T+0 / T+1 / EOM | Ops |
|
||||
|
||||
---
|
||||
|
||||
## AGENTS.md 준수
|
||||
|
||||
- ✅ **Necessity-driven**: 이미 식별된 미결정 항목 통합만
|
||||
- ✅ **Maturity**: 코드 앞에 승인 결정 — 문서만 준비
|
||||
- ✅ **Traceability**: DEC ID 명시, DECISION_LOG.csv 연계
|
||||
|
||||
**상태:** PROPOSED (사용자/법무팀의 승인 대기)
|
||||
@@ -0,0 +1,22 @@
|
||||
# 배포 frontend artifact 계약
|
||||
|
||||
## Source
|
||||
|
||||
- 운영 배포 Run 3357 로그: `dotnet publish` 전 frontend build 단계 없음
|
||||
- 운영 bundle에 `app-version` 및 `UI contract 4.0` marker 없음
|
||||
- `frontend`의 재현 가능한 `pnpm-lock.yaml` 및 기존 CI frontend job
|
||||
|
||||
## Decision
|
||||
|
||||
배포 workflow는 Host publish 전에 다음 규칙으로 버전을 계산하고 frontend를 재생성한다.
|
||||
|
||||
```text
|
||||
YYYY.MM.DD.<당일 release 순번>.<commit SHA 10자리>
|
||||
```
|
||||
|
||||
당일 순번은 `vYYYY.MM.DD.*` release tag 개수에 1을 더해 계산한다. 예: `2026.08.06.1.acaa731b3f`. 생성된 `frontend/dist`를 Host `wwwroot`에 복사하고, `app-version`, `UI contract 4.0`, 계산된 전체 버전 marker가 없으면 배포를 중단한다.
|
||||
|
||||
## Evidence / Unknown
|
||||
|
||||
- Source 변경과 운영 artifact를 분리하지 않고, 매 배포 시 동일 commit에서 재생성한다.
|
||||
- 실제 운영 반영 증거는 이 Slice의 CI 및 deploy run 완료 후 보존한다.
|
||||
@@ -0,0 +1,32 @@
|
||||
# KArtSell 배포 재기동 권한 계약
|
||||
|
||||
## Source
|
||||
|
||||
- 운영 호스트 `hz-prod-01`의 실제 sudo 정책 조회 결과
|
||||
- 기존 `quantengine` 및 `taxbaik` 서비스의 특정 `systemctl restart` `NOPASSWD` 위임 패턴
|
||||
- `.gitea/workflows/deploy.yml`
|
||||
|
||||
## Assumption
|
||||
|
||||
- 배포 SSH 계정은 `kjh2064`로 유지한다.
|
||||
- 운영 서비스는 `/etc/systemd/system/kartsell.service`로 유지한다.
|
||||
- DbMigrator와 artifact 복사는 현재처럼 `kjh2064` 권한으로 수행한다.
|
||||
|
||||
## Decision
|
||||
|
||||
`kjh2064`에 전체 sudo 권한을 부여하지 않고, 운영자가 한 번만 다음 단일 명령을 `/etc/sudoers.d/kartsell-deploy`에 등록한다.
|
||||
|
||||
```sudoers
|
||||
kjh2064 ALL=(root) NOPASSWD: /usr/bin/systemctl restart kartsell
|
||||
```
|
||||
|
||||
파일 권한은 `0440`이어야 하며 `visudo -cf /etc/sudoers.d/kartsell-deploy` 검증 후 적용한다. 이후 CI는 비대화형 `sudo -n systemctl restart kartsell`만 사용하므로 배포마다 비밀번호 입력이나 sudo 등록이 필요 없다.
|
||||
|
||||
## Deployment guard
|
||||
|
||||
워크플로우는 artifact 복사와 DbMigrator 실행 전에 `sudo -n -l`로 위임 존재 여부를 검사한다. 위임이 없으면 운영 DB를 변경하지 않고 exit 77로 종료한다.
|
||||
|
||||
## Unknown / Decision Required
|
||||
|
||||
- 이 파일을 운영 호스트에 설치할 권한은 root 운영자에게만 있다.
|
||||
- 설치 후 필요한 증거: `visudo -cf` 결과, `sudo -n -l` 결과, 다음 deploy run의 성공 로그, 서비스 active 상태.
|
||||
Reference in New Issue
Block a user