docs: [제품검사] FQC 문서 시스템 계획 + 스냅샷 Lazy Snapshot 반영
- fqc-document-system-plan.md: FormRequest 상태 수정, Phase 2.4 Lazy Snapshot 확정, 참고 파일 추가 - document-snapshot-architecture-plan.md: Lazy Snapshot 캡처 원칙 추가 - server-access-management.md 신규 - README.md 수정 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# SAM 프로젝트 문서
|
# SAM 프로젝트 문서
|
||||||
|
|
||||||
SAM ERP 시스템의 기술 문서, 비즈니스 규칙, 기능 명세를 관리하는 저장소입니다.
|
SAM ERP 시스템의 기술 문서, 비즈니스 규칙, 기능 명세를 관리하는 저장소입니다.
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
2. rendered_html이 있으면 무조건 그것을 사용 (완전한 스냅샷)
|
2. rendered_html이 있으면 무조건 그것을 사용 (완전한 스냅샷)
|
||||||
3. 구조화 데이터는 편집/검색/통계용으로 병행 유지
|
3. 구조화 데이터는 편집/검색/통계용으로 병행 유지
|
||||||
4. React에서만 문서 렌더링 책임 → MNG는 출력만 담당
|
4. React에서만 문서 렌더링 책임 → MNG는 출력만 담당
|
||||||
|
5. Lazy Snapshot: 조회 시 rendered_html 없으면 자동 캡처 → 저장 (점진적 스냅샷 전환)
|
||||||
```
|
```
|
||||||
|
|
||||||
### 1.4 변경 승인 정책
|
### 1.4 변경 승인 정책
|
||||||
@@ -76,8 +77,9 @@
|
|||||||
|
|
||||||
### 2.2 React 현황 (구현 완료)
|
### 2.2 React 현황 (구현 완료)
|
||||||
|
|
||||||
rendered_html 캡처 원칙: **입력 화면에서 저장할 때** 해당 데이터의 "문서 뷰"를 캡처.
|
#### 캡처 원칙 A: 입력 시 저장 (Active Capture)
|
||||||
보기(readOnly)에서는 캡처하지 않음.
|
|
||||||
|
입력 화면에서 저장할 때 해당 데이터의 "문서 뷰"를 캡처. 보기(readOnly)에서는 캡처하지 않음.
|
||||||
|
|
||||||
| Save Path | 파일 | 방식 | 캡처 대상 |
|
| Save Path | 파일 | 방식 | 캡처 대상 |
|
||||||
|-----------|------|------|----------|
|
|-----------|------|------|----------|
|
||||||
@@ -90,6 +92,40 @@ rendered_html 캡처 원칙: **입력 화면에서 저장할 때** 해당 데이
|
|||||||
> 이후 InspectionReportModal을 edit 모드로 열어 저장하면 캡처됨.
|
> 이후 InspectionReportModal을 edit 모드로 열어 저장하면 캡처됨.
|
||||||
> 향후 오프스크린 렌더링으로 확장 가능 (템플릿 로딩 등 async 의존성 해결 필요).
|
> 향후 오프스크린 렌더링으로 확장 가능 (템플릿 로딩 등 async 의존성 해결 필요).
|
||||||
|
|
||||||
|
#### 캡처 원칙 B: 조회 시 자동 캡처 (Lazy Snapshot)
|
||||||
|
|
||||||
|
문서 조회(view/readOnly) 시 `rendered_html`이 없으면 자동 캡처하여 백그라운드 저장.
|
||||||
|
|
||||||
|
```
|
||||||
|
문서 View 시
|
||||||
|
├── rendered_html 있음 → 그대로 표시 (기존)
|
||||||
|
└── rendered_html 없음 → 동적 렌더링 완료 후 캡처 → API로 rendered_html 저장
|
||||||
|
(다음 조회부터는 스냅샷 사용)
|
||||||
|
```
|
||||||
|
|
||||||
|
**적용 대상**:
|
||||||
|
- readonly 문서 (제품검사 요청서 등 — 입력 없이 자동 생성되는 문서)
|
||||||
|
- 마이그레이션 이전 기존 데이터 (rendered_html이 NULL인 과거 문서)
|
||||||
|
- WorkerScreen 인라인 저장 후 아직 모달에서 저장하지 않은 문서
|
||||||
|
|
||||||
|
**구현 방식**:
|
||||||
|
```typescript
|
||||||
|
// 문서 표시 컴포넌트에서 (DocumentViewer, Modal 등)
|
||||||
|
useEffect(() => {
|
||||||
|
if (document && !document.rendered_html && isContentRendered) {
|
||||||
|
const html = contentWrapperRef.current?.innerHTML
|
||||||
|
|| await captureRenderedHtml(DocumentComponent, props);
|
||||||
|
patchDocumentRenderedHtml(document.id, html); // 백그라운드 저장
|
||||||
|
}
|
||||||
|
}, [document, isContentRendered]);
|
||||||
|
```
|
||||||
|
|
||||||
|
**고려사항**:
|
||||||
|
- 사용자 UX 영향 없음 (백그라운드 비동기 저장)
|
||||||
|
- 조회 권한만 있는 사용자도 트리거 가능해야 함
|
||||||
|
- 동시 접속 시 중복 저장 가능 → 같은 HTML이므로 실질적 문제 없음
|
||||||
|
- 캡처 타이밍: template 로드 + 데이터 바인딩 완료 후 (isContentRendered 판단 필요)
|
||||||
|
|
||||||
### 2.3 API 현황 (구현 완료)
|
### 2.3 API 현황 (구현 완료)
|
||||||
|
|
||||||
- Document 모델 `$fillable`에 `rendered_html` 포함 ✅
|
- Document 모델 `$fillable`에 `rendered_html` 포함 ✅
|
||||||
@@ -298,6 +334,7 @@ Phase 1과 Phase 3의 MNG 코드 수정은 병렬 가능 (fallback 유지).
|
|||||||
| 2026-03-06 | Phase 2 보정 | API UpsertRequest rendered_html 누락 수정, DocumentService upsert() rendered_html 전달 추가 | UpsertRequest.php, DocumentService.php | ✅ |
|
| 2026-03-06 | Phase 2 보정 | API UpsertRequest rendered_html 누락 수정, DocumentService upsert() rendered_html 전달 추가 | UpsertRequest.php, DocumentService.php | ✅ |
|
||||||
| 2026-03-06 | Phase 2 보정 | ImportInspection: 입력폼 캡처 → 오프스크린 성적서 렌더링으로 변경 | ImportInspectionInputModal.tsx, capture-rendered-html.tsx | ✅ |
|
| 2026-03-06 | Phase 2 보정 | ImportInspection: 입력폼 캡처 → 오프스크린 성적서 렌더링으로 변경 | ImportInspectionInputModal.tsx, capture-rendered-html.tsx | ✅ |
|
||||||
| 2026-03-06 | Phase 2 보정 | InspectionReportModal readOnly 자동 캡처 useEffect 제거 | InspectionReportModal.tsx | ✅ |
|
| 2026-03-06 | Phase 2 보정 | InspectionReportModal readOnly 자동 캡처 useEffect 제거 | InspectionReportModal.tsx | ✅ |
|
||||||
|
| 2026-03-06 | 원칙 확장 | Lazy Snapshot 패턴 추가 — 조회 시 rendered_html 없으면 자동 캡처/저장 | 아키텍처 원칙 | - |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -135,7 +135,7 @@
|
|||||||
| 2.1 | mng에 제품검사 요청서 template 신규 등록 (시더) | ⏳ | 시더 방식 확정 |
|
| 2.1 | mng에 제품검사 요청서 template 신규 등록 (시더) | ⏳ | 시더 방식 확정 |
|
||||||
| 2.2 | React 동적 렌더링 컴포넌트 구현 | ⏳ | 하드코딩 → 양식 기반 전환 |
|
| 2.2 | React 동적 렌더링 컴포넌트 구현 | ⏳ | 하드코딩 → 양식 기반 전환 |
|
||||||
| 2.3 | 요청서 문서 생성 API 연동 | ⏳ | quality_document 생성 시 자동 생성 확정 |
|
| 2.3 | 요청서 문서 생성 API 연동 | ⏳ | quality_document 생성 시 자동 생성 확정 |
|
||||||
| 2.4 | rendered_html 스냅샷 저장 적용 | ⏳ | |
|
| 2.4 | rendered_html 스냅샷 저장 적용 (Lazy Snapshot) | ⏳ | 요청서 최초 조회 시 rendered_html 없으면 자동 캡처/저장 |
|
||||||
|
|
||||||
### Phase 3: 통합 및 정리
|
### Phase 3: 통합 및 정리
|
||||||
|
|
||||||
@@ -202,9 +202,13 @@ Phase 2: 제품검사 요청서 신규
|
|||||||
│ ├── 개소 데이터 자동 매핑 (quality_document_locations → 사전고지 테이블)
|
│ ├── 개소 데이터 자동 매핑 (quality_document_locations → 사전고지 테이블)
|
||||||
│ └── 파일: api/app/Services/QualityDocumentService.php
|
│ └── 파일: api/app/Services/QualityDocumentService.php
|
||||||
│
|
│
|
||||||
└── Step 2.4: rendered_html 스냅샷
|
└── Step 2.4: rendered_html 스냅샷 (Lazy Snapshot 패턴)
|
||||||
├── 요청서 저장/표시 시 HTML 캡처
|
├── 요청서는 readonly 문서 → "입력 시 저장" 캡처 불가
|
||||||
└── API 전송 및 저장
|
├── Lazy Snapshot 적용: 요청서 최초 조회 시 rendered_html 없으면 자동 캡처
|
||||||
|
├── captureRenderedHtml 유틸리티 활용 (react/src/lib/utils/capture-rendered-html.tsx)
|
||||||
|
├── 또는 contentWrapperRef.innerHTML로 렌더링 완료 후 캡처
|
||||||
|
├── 백그라운드 API 호출로 rendered_html 저장 (PATCH /v1/documents/{id} 또는 upsert)
|
||||||
|
└── 참조: document-snapshot-architecture-plan.md 캡처 원칙 B
|
||||||
|
|
||||||
Phase 3: 통합 및 정리
|
Phase 3: 통합 및 정리
|
||||||
├── InspectionDetail.tsx에서 모달 연동 통합 테스트
|
├── InspectionDetail.tsx에서 모달 연동 통합 테스트
|
||||||
@@ -391,9 +395,14 @@ const methodFreqCoverage = buildCompositeRowSpan(sectionItems);
|
|||||||
- method+frequency `공인시험기관|1회/5년` → 9행 (내화3 + 차연1 + 개폐5)
|
- method+frequency `공인시험기관|1회/5년` → 9행 (내화3 + 차연1 + 개폐5)
|
||||||
- `작동테스트`는 method/frequency 빈값 → 병합 대상 아님
|
- `작동테스트`는 method/frequency 빈값 → 병합 대상 아님
|
||||||
|
|
||||||
#### 5.1.4 rendered_html 캡처 패턴 (참조: 중간검사)
|
#### 5.1.4 rendered_html 캡처 패턴
|
||||||
|
|
||||||
**`react/src/components/production/WorkOrders/documents/InspectionReportModal.tsx`** (라인 341-366):
|
> **캡처 원칙** (document-snapshot-architecture-plan.md 참조):
|
||||||
|
> - **Active Capture**: 입력 화면에서 저장할 때 캡처. readOnly에서는 캡처하지 않음.
|
||||||
|
> - **Lazy Snapshot**: 조회 시 rendered_html 없으면 자동 캡처/저장 (점진적 전환).
|
||||||
|
> FQC 성적서는 Active Capture (편집 모드 저장 시), 요청서는 Lazy Snapshot (readonly 자동 캡처) 적용.
|
||||||
|
|
||||||
|
**패턴 1: innerHTML 직접 캡처** (참조: 중간검사 `InspectionReportModal.tsx` 라인 341-366)
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// 1. ref 정의
|
// 1. ref 정의
|
||||||
@@ -414,7 +423,19 @@ const handleSave = async () => {
|
|||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
**FQC에 적용할 위치**: `InspectionReportModal.tsx`의 FQC 모드 저장 로직에 동일 패턴 추가.
|
**패턴 2: 오프스크린 렌더링** (참조: 수입검사 `ImportInspectionInputModal.tsx`)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { captureRenderedHtml } from '@/lib/utils/capture-rendered-html';
|
||||||
|
|
||||||
|
// 문서 컴포넌트를 오프스크린으로 렌더링 → HTML 캡처
|
||||||
|
const html = await captureRenderedHtml(DocumentComponent, documentProps);
|
||||||
|
```
|
||||||
|
|
||||||
|
- 유틸리티 위치: `react/src/lib/utils/capture-rendered-html.tsx` (flushSync + createRoot)
|
||||||
|
- 문서가 화면에 렌더링되지 않는 상황에서 캡처할 때 사용 (Lazy Snapshot에 활용 가능)
|
||||||
|
|
||||||
|
**FQC 성적서 적용 (Phase 1.3)**: 패턴 1 사용. `InspectionReportModal.tsx`의 FQC 모드 저장 로직에 동일 패턴 추가.
|
||||||
현재 `fqcActions.ts`의 `saveFqcDocument()`는 `POST /v1/documents/upsert` 사용 → body에 `rendered_html` 추가.
|
현재 `fqcActions.ts`의 `saveFqcDocument()`는 `POST /v1/documents/upsert` 사용 → body에 `rendered_html` 추가.
|
||||||
|
|
||||||
#### 5.1.5 FqcDocumentContent.tsx 현재 구조 (보완 대상)
|
#### 5.1.5 FqcDocumentContent.tsx 현재 구조 (보완 대상)
|
||||||
@@ -647,6 +668,7 @@ DocumentTemplate (제품검사 요청서)
|
|||||||
| 1 | 성적서 양식 보완 방안 | **방안 C 확정** — 하드코딩 데이터를 template items로 완전 이관. SectionItem에 method/frequency/measurement_type 이미 존재 | mng, react | ✅ 확정 |
|
| 1 | 성적서 양식 보완 방안 | **방안 C 확정** — 하드코딩 데이터를 template items로 완전 이관. SectionItem에 method/frequency/measurement_type 이미 존재 | mng, react | ✅ 확정 |
|
||||||
| 2 | 요청서 template 생성 방법 | **시더 확정** — ProductInspectionRequestTemplateSeeder 작성 (mng/database/seeders/). 재현성 + 버전 관리 | mng | ✅ 확정 |
|
| 2 | 요청서 template 생성 방법 | **시더 확정** — ProductInspectionRequestTemplateSeeder 작성 (mng/database/seeders/). 재현성 + 버전 관리 | mng | ✅ 확정 |
|
||||||
| 3 | 요청서 문서 생성 시점 | **자동 생성 확정** — quality_document 생성 시 자동. 기존 성적서 bulk create 패턴과 동일 | api | ✅ 확정 |
|
| 3 | 요청서 문서 생성 시점 | **자동 생성 확정** — quality_document 생성 시 자동. 기존 성적서 bulk create 패턴과 동일 | api | ✅ 확정 |
|
||||||
|
| 4 | 요청서 rendered_html 캡처 방식 | **Lazy Snapshot 확정** — 요청서는 readonly 문서이므로 최초 조회 시 rendered_html 없으면 자동 캡처/저장. `captureRenderedHtml` 유틸리티 또는 `contentWrapperRef.innerHTML` 활용 | react | ✅ 확정 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -664,7 +686,7 @@ DocumentTemplate (제품검사 요청서)
|
|||||||
| API (DocumentService create/update) | ✅ | rendered_html 조건부 저장 |
|
| API (DocumentService create/update) | ✅ | rendered_html 조건부 저장 |
|
||||||
| React (InspectionReportModal) | ✅ | contentWrapperRef.innerHTML 캡처 |
|
| React (InspectionReportModal) | ✅ | contentWrapperRef.innerHTML 캡처 |
|
||||||
| MNG (show/print.blade.php) | ✅ | rendered_html 우선 출력 + fallback |
|
| MNG (show/print.blade.php) | ✅ | rendered_html 우선 출력 + fallback |
|
||||||
| FormRequest 검증 | ⚠️ | rendered_html 검증 규칙 확인 필요 |
|
| FormRequest 검증 | ✅ | StoreRequest/UpdateRequest/UpsertRequest 모두 nullable string 검증 완료 |
|
||||||
|
|
||||||
### mng template 구조 핵심
|
### mng template 구조 핵심
|
||||||
- `DocumentTemplateSectionItem` 필드: category, item, standard, tolerance, standard_criteria, method, measurement_type, frequency_n, frequency_c, frequency, regulation, field_values(JSON)
|
- `DocumentTemplateSectionItem` 필드: category, item, standard, tolerance, standard_criteria, method, measurement_type, frequency_n, frequency_c, frequency, regulation, field_values(JSON)
|
||||||
@@ -689,6 +711,7 @@ DocumentTemplate (제품검사 요청서)
|
|||||||
| 2026-03-06 | 에이전트 조사 | template ID 65 현황, rendered_html 현황, mng 구조 분석 반영 | - | - |
|
| 2026-03-06 | 에이전트 조사 | template ID 65 현황, rendered_html 현황, mng 구조 분석 반영 | - | - |
|
||||||
| 2026-03-06 | 자기완결성 보완 | 시더 데이터, rowSpan 로직, rendered_html 캡처 패턴, API 구조, 타입 정의 추가 | - | - |
|
| 2026-03-06 | 자기완결성 보완 | 시더 데이터, rowSpan 로직, rendered_html 캡처 패턴, API 구조, 타입 정의 추가 | - | - |
|
||||||
| 2026-03-06 | 방법론 수정 6건 | ①컬럼 아키텍처 재설계(template 2개+시각 8컬럼) ②프론트 타입 갭 보완 ③rowSpan 복합키 알고리즘 ④Template ID 안정성 대책 ⑤measurement_type=none 처리 ⑥시더 위치 명확화(mng) | - | - |
|
| 2026-03-06 | 방법론 수정 6건 | ①컬럼 아키텍처 재설계(template 2개+시각 8컬럼) ②프론트 타입 갭 보완 ③rowSpan 복합키 알고리즘 ④Template ID 안정성 대책 ⑤measurement_type=none 처리 ⑥시더 위치 명확화(mng) | - | - |
|
||||||
|
| 2026-03-06 | 스냅샷 아키텍처 정합성 검토 반영 | ①FormRequest 검증 ✅ 확인 ②Phase 2.4 Lazy Snapshot 전략 확정 ③참고 파일 추가(capture-rendered-html.tsx, UpsertRequest) ④캡처 원칙(Active/Lazy) 명시 ⑤오프스크린 렌더링 참조 추가 | 5.1.4, 6.1, 9 | - |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -724,6 +747,8 @@ DocumentTemplate (제품검사 요청서)
|
|||||||
|------|------|----------|
|
|------|------|----------|
|
||||||
| `react/src/components/production/WorkOrders/documents/TemplateInspectionContent.tsx` | 중간검사 동적 렌더링 (참조 모델) | 917-999: 컬럼타입별 렌더링, 1105-1183: renderComplexCells() |
|
| `react/src/components/production/WorkOrders/documents/TemplateInspectionContent.tsx` | 중간검사 동적 렌더링 (참조 모델) | 917-999: 컬럼타입별 렌더링, 1105-1183: renderComplexCells() |
|
||||||
| `react/src/components/production/WorkOrders/documents/InspectionReportModal.tsx` | 중간검사 모달 (rendered_html 캡처 패턴) | 167: contentWrapperRef, 341-366: handleSave+innerHTML |
|
| `react/src/components/production/WorkOrders/documents/InspectionReportModal.tsx` | 중간검사 모달 (rendered_html 캡처 패턴) | 167: contentWrapperRef, 341-366: handleSave+innerHTML |
|
||||||
|
| `react/src/lib/utils/capture-rendered-html.tsx` | 오프스크린 렌더링 유틸리티 (flushSync+createRoot) | Phase 2.4 Lazy Snapshot에서 활용 가능 |
|
||||||
|
| `react/src/components/material/ReceivingManagement/ImportInspectionInputModal.tsx` | 수입검사 오프스크린 캡처 참조 | captureRenderedHtml 사용 예시 |
|
||||||
|
|
||||||
### API (수정 대상)
|
### API (수정 대상)
|
||||||
| 파일 | 역할 | 핵심 라인 |
|
| 파일 | 역할 | 핵심 라인 |
|
||||||
@@ -732,6 +757,7 @@ DocumentTemplate (제품검사 요청서)
|
|||||||
| `api/app/Services/QualityDocumentService.php` | 품질관리 문서 서비스 | 176-209: store(), 749-799: requestDocument(), 804-868: resultDocument() |
|
| `api/app/Services/QualityDocumentService.php` | 품질관리 문서 서비스 | 176-209: store(), 749-799: requestDocument(), 804-868: resultDocument() |
|
||||||
| `api/app/Models/Documents/Document.php` | 문서 모델 | 76: $fillable에 rendered_html |
|
| `api/app/Models/Documents/Document.php` | 문서 모델 | 76: $fillable에 rendered_html |
|
||||||
| `api/app/Models/Qualitys/QualityDocumentLocation.php` | 개소 모델 | fillable: post_width, post_height, change_reason, inspection_data |
|
| `api/app/Models/Qualitys/QualityDocumentLocation.php` | 개소 모델 | fillable: post_width, post_height, change_reason, inspection_data |
|
||||||
|
| `api/app/Http/Requests/Document/UpsertRequest.php` | documents/upsert 검증 | rendered_html nullable string 검증 완료 |
|
||||||
|
|
||||||
### MNG (확인/수정 대상)
|
### MNG (확인/수정 대상)
|
||||||
| 파일 | 역할 |
|
| 파일 | 역할 |
|
||||||
|
|||||||
150
system/server-access-management.md
Normal file
150
system/server-access-management.md
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
# SAM 서버 접근 권한 관리
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
|
||||||
|
SAM 시스템의 서버 및 데이터베이스 접근 권한을 관리합니다.
|
||||||
|
서버 관리자는 1명이며, 외부 인원에게는 임시로 접근을 허용하고 작업 완료 후 차단합니다.
|
||||||
|
|
||||||
|
**최종 업데이트:** 2026-03-05
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 서버 정보
|
||||||
|
|
||||||
|
| 구분 | 호스트 | SSH alias | 용도 |
|
||||||
|
|------|--------|-----------|------|
|
||||||
|
| 운영 (prod) | 211.117.60.189 | `sam-prod` | API + React 운영 배포 |
|
||||||
|
| CI/CD | 114.203.209.83 | `sam-cicd` | Jenkins + React 개발 배포 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OS 계정 현황
|
||||||
|
|
||||||
|
### sam-prod (운영서버)
|
||||||
|
|
||||||
|
| 계정 | 용도 | 상태 |
|
||||||
|
|------|------|------|
|
||||||
|
| `hskwon` | 서버 관리자 (배포, 운영) | 활성 |
|
||||||
|
| `pro` | 외부 작업자 임시 접근용 | **잠금** |
|
||||||
|
|
||||||
|
### sam-cicd (CI/CD 서버)
|
||||||
|
|
||||||
|
| 계정 | 용도 | 상태 |
|
||||||
|
|------|------|------|
|
||||||
|
| `hskwon` | 서버 관리자 | 활성 |
|
||||||
|
| `pro` | 외부 작업자 임시 접근용 | **잠금** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OS 계정 잠금/해제
|
||||||
|
|
||||||
|
외부 작업자에게 서버 접근이 필요한 경우, 작업 시간 동안만 해제하고 완료 후 다시 잠금합니다.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 계정 잠금
|
||||||
|
sudo usermod -L pro
|
||||||
|
|
||||||
|
# 계정 해제
|
||||||
|
sudo usermod -U pro
|
||||||
|
|
||||||
|
# 상태 확인 (비밀번호 필드 앞에 ! 있으면 잠금 상태)
|
||||||
|
sudo passwd -S pro
|
||||||
|
```
|
||||||
|
|
||||||
|
### 임시 접근 절차
|
||||||
|
|
||||||
|
1. 작업 요청 접수 및 범위 확인
|
||||||
|
2. `sudo usermod -U pro` 로 해제
|
||||||
|
3. 작업 완료 확인
|
||||||
|
4. `sudo usermod -L pro` 로 잠금
|
||||||
|
5. 작업 내용 기록
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## DB 계정 현황
|
||||||
|
|
||||||
|
### sam-prod (운영서버 MySQL 8.4)
|
||||||
|
|
||||||
|
| 계정 | 인증 플러그인 | 접근 DB | 용도 |
|
||||||
|
|------|-------------|---------|------|
|
||||||
|
| `codebridge@localhost` | caching_sha2_password | sam, sam_stage, sam_stat, codebridge | 애플리케이션 (.env) |
|
||||||
|
| `hskwon@localhost` | caching_sha2_password | 전역 관리자 + sam | 서버 관리자 |
|
||||||
|
| `pro@localhost` | caching_sha2_password | sam, sam_stage, sam_stat, codebridge | 외부 작업자용 |
|
||||||
|
|
||||||
|
### sam-cicd (CI/CD 서버 MySQL 8.4)
|
||||||
|
|
||||||
|
| 계정 | 인증 플러그인 | 접근 DB | 용도 |
|
||||||
|
|------|-------------|---------|------|
|
||||||
|
| `hskwon@localhost` | caching_sha2_password | 전역 관리자 | 서버 관리자 |
|
||||||
|
| `pro@localhost` | caching_sha2_password | sam, sam_stage, sam_stat, codebridge, gitea | 외부 작업자용 |
|
||||||
|
|
||||||
|
> **참고:** cicd 서버에는 `codebridge` DB 계정이 없음 (애플리케이션이 다른 계정 사용)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## DB 계정 관리
|
||||||
|
|
||||||
|
### 계정 잠금/해제 (MySQL)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 계정 잠금
|
||||||
|
ALTER USER 'pro'@'localhost' ACCOUNT LOCK;
|
||||||
|
|
||||||
|
-- 계정 해제
|
||||||
|
ALTER USER 'pro'@'localhost' ACCOUNT UNLOCK;
|
||||||
|
|
||||||
|
-- 상태 확인
|
||||||
|
SELECT user, host, account_locked FROM mysql.user WHERE user = 'pro';
|
||||||
|
```
|
||||||
|
|
||||||
|
### 인증 플러그인 변경
|
||||||
|
|
||||||
|
MySQL 8.4에서는 `mysql_native_password`가 제거되었으므로 `caching_sha2_password`를 사용합니다.
|
||||||
|
|
||||||
|
```sql
|
||||||
|
ALTER USER 'username'@'localhost' IDENTIFIED WITH caching_sha2_password BY '비밀번호';
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
```
|
||||||
|
|
||||||
|
### PhpStorm 접속 시 주의사항
|
||||||
|
|
||||||
|
- SSH 터널 필수 (MySQL이 localhost만 허용)
|
||||||
|
- Host: `localhost` (127.0.0.1 아님)
|
||||||
|
- `caching_sha2_password` 사용 시 Advanced 탭에서 `allowPublicKeyRetrieval = true` 설정 필요
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 배포 계정 관리
|
||||||
|
|
||||||
|
### Jenkins 배포 흐름
|
||||||
|
|
||||||
|
| 프로젝트 | main | develop |
|
||||||
|
|----------|------|---------|
|
||||||
|
| **api** | Jenkins (Stage + Production) | post-update hook (Jenkins 미관여) |
|
||||||
|
| **react** | Jenkins (Stage + Production) | Jenkins (Development) |
|
||||||
|
|
||||||
|
- 배포 SSH 계정: `hskwon` (deploy-ssh-key 크레덴셜)
|
||||||
|
- Slack 알림: `#deploy_api`, `#deploy_react`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 관리 정책
|
||||||
|
|
||||||
|
1. **서버 관리자 1명 원칙** — 여러 명이 동시에 관리하지 않음
|
||||||
|
2. **임시 접근만 허용** — 외부 작업자는 필요 시에만 OS/DB 계정 해제
|
||||||
|
3. **작업 완료 후 즉시 잠금** — 해제 상태로 방치하지 않음
|
||||||
|
4. **DB 접근은 SSH 터널 경유** — 외부에서 MySQL 직접 접근 불가 (localhost 바인딩)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 참고
|
||||||
|
|
||||||
|
- API 보안 가이드: [security-policy.md](./security-policy.md)
|
||||||
|
- Docker 설정: [docker-setup.md](./docker-setup.md)
|
||||||
|
- 원격 근무 설정: [remote-work-setup.md](./remote-work-setup.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**작성일:** 2026-03-05
|
||||||
|
**버전:** 1.0
|
||||||
|
**담당자:** SAM Infrastructure Team
|
||||||
Reference in New Issue
Block a user