Files
sam-docs/guides/PROJECT_DEVELOPMENT_POLICY.md
권혁성 0ace50b006 docs: [종합정비] 구조 재편 — Phase 0+2+4 통합
- Phase 0: INDEX.md 전면 재작성, CLAUDE.md→INDEX.md 통합 삭제
- Phase 0: front/→guides/ 이관(5개 파일), changes/ D7 포맷 통일(3개)
- Phase 0: guides/ai-config-설정.md→ai-config-settings.md D3 통일
- Phase 2: architecture/+specs/→system/ 이관(6개 이동, 4개 폐기)
- Phase 2: 13개 파일 경로 참조 수정 (specs/→system/, architecture/→system/)
- Phase 4: 7개 파일 11개 교차참조 깨진 링크 수정

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 18:03:04 +09:00

16 KiB

SAM 프로젝트 개발 공통 정책

적용 대상: 견적, 수주, 생산, 출하, 품질 등 모든 MES 기능 개발 최종 업데이트: 2025-12-19


📋 개요

이 문서는 SAM 시스템의 모든 기능 개발에 공통으로 적용되는 정책을 정의합니다. 각 기능별 개발 문서(MASTER_PLAN.md)는 이 문서를 참조합니다.


🚨 필수 준수 규칙

1. 테이블 정책

❌ 절대 금지:
- 새로운 테이블 임의 생성 (price_new, order_items_v2 등)
- 기존 테이블 구조 임의 변경
- mng에서 마이그레이션 실행

✅ 필수:
- 기존 테이블 우선 활용
- 테이블 추가 필요 시 → 사용자 승인 필수
- DB 마이그레이션은 api 프로젝트에서만 실행

2. 기술 스택

프로젝트 기술 스택 주의사항
mng Laravel 12 + Plain Blade + Tailwind + Livewire + Filament Alpine.js 금지
api Laravel 12 REST API + Swagger Multi-tenant 필수
5130 PHP + jQuery + 레거시 JS 분석 대상 (참조용)
react Next.js 15 프론트엔드 담당자 별도

3. 코드 컨벤션 (추측 금지 원칙)

🔴 핵심: 모든 코드 요소는 실제 확인 후 사용

❌ 절대 금지 - 추측/할루시네이션:
- 컬럼명 추측 (tenant.name → 실제는 tenant.company_name)
- 관계명 추측 (user.roles → 실제는 user.userRoles)
- 경로 추측 (App\Models\User → 실제 경로 다를 수 있음)
- 메서드명 추측 (getName() → 실제는 getCompanyName())
- 설정값 추측 (config('app.name') → 실제 키 다를 수 있음)
- 라우트명 추측 (route('users.index') → 실제 라우트명 확인 필요)
- 테이블명 추측 (users → 실제는 sam_users 일 수 있음)
- Enum 값 추측 (Status::ACTIVE → 실제 Enum 확인 필요)
✅ 필수 - 실제 확인 후 사용:
- 모델 파일 열어서 컬럼명/관계명 확인
- 마이그레이션 파일에서 테이블 구조 확인
- 기존 코드에서 사용 패턴 확인
- config 파일에서 실제 키 확인
- routes 파일에서 라우트명 확인
- 불확실하면 → 반드시 질문

확인 우선순위:

1. 모델 파일 (app/Models/*.php)
2. 마이그레이션 (database/migrations/*.php)
3. 기존 컨트롤러/서비스 사용 패턴
4. 라우트 파일 (routes/*.php)
5. 설정 파일 (config/*.php)

4. 정책 충돌 해결

문서 간 정책 충돌 발견 시:
1. 최신 날짜 문서 우선
2. 날짜 동일 → 상위 문서(CLAUDE.md) 우선
3. 모호한 경우 → 반드시 사용자에게 질문
4. 해결된 정책 → PROGRESS.md에 기록

🗄️ DB 테이블 정책

테이블 매핑 원칙

┌─────────────────────────────────────────────────────────────────┐
│ 5130 (레거시)                                                    │
│ ├── 모든 테이블 존재 (이미 개발 완료)                              │
│ └── 분석 대상 (구조/데이터 참조용)                                 │
└─────────────────────────────────────────────────────────────────┘
                              ↓ 매핑
┌─────────────────────────────────────────────────────────────────┐
│ SAM (api/mng)                                                   │
│ ├── 있는 테이블: 매핑하여 활용                                     │
│ ├── 이름 다른 테이블: 매핑 테이블 문서화 후 활용                     │
│ └── 없는 테이블: 신규 생성 (SAM 설계 정책 적용)                     │
└─────────────────────────────────────────────────────────────────┘

SAM 테이블 설계 정책 (Hybrid EAV)

┌─────────────────────────────────────────────────────────────────┐
│ 컬럼 분류 기준                                                   │
├─────────────────────────────────────────────────────────────────┤
│ 🔴 필수 컬럼 (일반 컬럼으로 생성)                                  │
│    - 조인에 사용되는 필드 (FK: tenant_id, product_id 등)          │
│    - 인덱싱이 필요한 필드 (검색/정렬: status, created_at 등)       │
│    - 고빈도 쿼리 필드 (WHERE 조건 자주 사용)                       │
│    - 유니크 제약 필드 (code, slug 등)                             │
├─────────────────────────────────────────────────────────────────┤
│ 🟢 가변 컬럼 (options JSON으로 통합)                              │
│    - 비즈니스 로직용 데이터                                       │
│    - 설정/옵션 값                                                │
│    - 확장 가능성 있는 필드                                        │
│    - 조인/검색에 사용되지 않는 필드                                │
└─────────────────────────────────────────────────────────────────┘

컬럼 타입 정책

┌─────────────────────────────────────────────────────────────────┐
│ ⚠️ Enum 지양 정책                                                │
├─────────────────────────────────────────────────────────────────┤
│ 요구사항은 언제든 변경될 수 있음 → 유연한 타입 사용                   │
│                                                                 │
│ ❌ 지양:                                                         │
│    - DB enum 타입 (ALTER TABLE 필요, 마이그레이션 복잡)             │
│    - PHP Enum 하드코딩 (변경 시 코드 수정 필요)                     │
│                                                                 │
│ ✅ 권장:                                                         │
│    - string/varchar 타입 + common_codes 테이블 관리               │
│    - is_* 필드: boolean 허용 (true/false 명확한 경우만)            │
│    - status 필드: string + common_codes 연동                      │
│    - type 필드: string + common_codes 연동                        │
│                                                                 │
│ 💡 예외 (Enum 허용):                                              │
│    - 절대 변경되지 않는 값 (예: 성별 M/F)                           │
│    - is_* boolean 필드 (2가지 상태만 존재 확실할 때)                │
└─────────────────────────────────────────────────────────────────┘

예시:

// ❌ 지양: DB Enum
$table->enum('status', ['pending', 'approved', 'rejected']);

// ❌ 지양: 나중에 상태 추가되면 코드 수정 필요
enum OrderStatus: string {
    case PENDING = 'pending';
    case APPROVED = 'approved';
}

// ✅ 권장: string + 코드 테이블
$table->string('status', 20)->default('pending');
// 상태값은 common_codes 테이블에서 관리

// ✅ 허용: is_* boolean (명확한 2가지 상태)
$table->boolean('is_active')->default(true);
$table->boolean('is_deleted')->default(false);

테이블 생성 예시

// ✅ SAM 테이블 설계 정책 적용 예시
Schema::create('example_table', function (Blueprint $table) {
    $table->id();

    // 🔴 필수 컬럼 (조인/인덱싱)
    $table->foreignId('tenant_id')->constrained()->cascadeOnDelete();
    $table->foreignId('related_id')->constrained()->cascadeOnDelete();
    $table->string('code')->unique();
    $table->string('status')->index();
    $table->decimal('amount', 15, 2)->index();

    // 🟢 가변 컬럼 (JSON)
    $table->json('options')->nullable();
    // options 예시: {
    //   "custom_field_1": "value",
    //   "settings": {...},
    //   "metadata": {...}
    // }

    $table->timestamps();
    $table->softDeletes();
});

테이블 매핑 문서 템플릿

## 테이블 매핑: [기능명]

### 매핑 현황
| 5130 테이블 | SAM 테이블 | 상태 | 비고 |
|------------|-----------|------|------|
| legacy_table | sam_table | 🆕 신규 생성 | SAM 정책 적용 |
| legacy_items | sam_items | ✅ 존재 | 동일 |

### 컬럼 매핑 상세
| 5130 컬럼 | SAM 컬럼 | 타입 | 분류 | 비고 |
|----------|---------|------|------|------|
| id | id | bigint | 필수 | PK |
| company_id | tenant_id | bigint | 필수 | FK, 조인 |
| code | code | string | 필수 | 유니크 |
| memo | options->notes | json | 가변 | JSON 내부 |

테이블 작업 프로세스

Step 1: 5130 테이블 분석
└── 컬럼 목록, 관계, 인덱스 파악
        ↓
Step 2: SAM 테이블 확인
├── 존재 여부 확인 (api/database/migrations/)
├── 이름 다른 경우 매핑 관계 문서화
└── 없는 경우 신규 생성 대상으로 표시
        ↓
Step 3: 컬럼 분류
├── 🔴 필수 컬럼 식별 (조인/인덱싱/검색)
└── 🟢 가변 컬럼 → options JSON 통합
        ↓
Step 4: 매핑 문서 작성
└── docs/projects/[기능명]/phase-X/table-mapping.md
        ↓
Step 5: 사용자 승인
├── 신규 테이블 생성 승인
├── 컬럼 분류(필수/가변) 승인
└── 매핑 관계 승인
        ↓
Step 6: 마이그레이션 생성 (api 프로젝트에서만!)
└── api/database/migrations/

기존 테이블 처리 정책

┌─────────────────────────────────────────────────────────────────┐
│ 기존 SAM 테이블 (options JSON 미적용)                             │
├─────────────────────────────────────────────────────────────────┤
│ ⏳ 추후 변환 작업 예정                                            │
│                                                                 │
│ 현재 작업 시:                                                    │
│ ├── 기존 테이블 구조 그대로 사용                                   │
│ ├── 기존 컬럼 활용 (임의 변경 금지)                                │
│ └── 신규 테이블만 SAM 정책(options JSON) 적용                     │
│                                                                 │
│ 변환 작업 시 (추후):                                              │
│ ├── 가변 컬럼 → options JSON 마이그레이션                         │
│ └── 별도 마이그레이션 계획 수립                                    │
└─────────────────────────────────────────────────────────────────┘

Model options 처리 패턴

// app/Models/ExampleModel.php
class ExampleModel extends Model
{
    use BelongsToTenant, SoftDeletes;

    protected $casts = [
        'options' => 'array',  // JSON 자동 변환
    ];

    // options 헬퍼 메서드
    public function getOption(string $key, mixed $default = null): mixed
    {
        return data_get($this->options, $key, $default);
    }

    public function setOption(string $key, mixed $value): void
    {
        $options = $this->options ?? [];
        data_set($options, $key, $value);
        $this->options = $options;
    }
}

DB 작업 체크리스트

신규 테이블 생성 시:
- [ ] 5130 원본 테이블 구조 분석 완료
- [ ] SAM 기존 테이블 존재 여부 확인
- [ ] 컬럼 분류 (필수 🔴 / 가변 🟢) 완료
- [ ] 테이블 매핑 문서 작성
- [ ] 사용자 승인 획득
- [ ] api 프로젝트에서 마이그레이션 생성
- [ ] 모델 생성 및 options 캐스팅 설정

기존 테이블 활용 시:
- [ ] 현재 테이블 구조 확인
- [ ] 필요 컬럼 존재 여부 확인
- [ ] 없는 컬럼 → 추가 마이그레이션 (승인 필요)
- [ ] 이름 다른 컬럼 → 매핑 문서화

🔄 Phase 진행 방식

Phase 시작 시

1. PROGRESS.md 확인 → 현재 상태 파악
2. 해당 Phase README.md 확인 → 체크리스트 로드
3. 관련 문서 링크 확인 → 참조 문서 읽기
4. MCP Sequential Thinking으로 작업 계획 수립
5. 사용자 승인 후 진행

Phase 진행 중

1. SuperClaude 페르소나 적용
   - 분석: root-cause-analyst
   - 설계: backend-architect
   - 구현: backend-architect, quality-engineer
2. 단계별 문서 업데이트 (승인 불필요)
3. 코드 변경 시 code-workflow 스킬 적용
4. 체크리스트 진행 상황 실시간 반영

Phase 완료 시

1. 해당 Phase 문서 최종 정리
2. PROGRESS.md 업데이트
3. Git 태그 생성: [기능명]/phase-X-complete
4. 커밋 (정책에 따라 한글 메시지)
5. 다음 Phase 준비 사항 명시

⚠️ 세션 및 커밋 정책

롤백 포인트 설정

각 Phase 완료 시 Git 태그 생성:
- [기능명]/phase-1-complete
- [기능명]/phase-2-complete
- ...

세션 중단 대응

세션 중단 시 복구 절차:
1. PROGRESS.md 확인 → 마지막 완료 상태
2. 해당 Phase README.md → 체크리스트 상태
3. 미완료 항목부터 이어서 진행
4. 이전 문서 내용 참조하여 컨텍스트 복구

커밋 정책

- 한글 커밋 메시지
- 단계별/스텝별 커밋
- 푸시는 사용자 수동 진행
- 커밋 후 푸시 여부 묻지 않음

🔗 참조 문서 목록

SAM 전체 문서

docs/system/                                         # 시스템 현황
docs/reference/                                      # 레퍼런스
docs/guides/                                         # 가이드 (이 문서 포함)

개별 프로젝트 문서

api/docs/                                            # API 프로젝트 문서
mng/docs/                                            # mng 프로젝트 문서

테이블 참조

api/database/migrations/                             # 마이그레이션 파일
api/app/Models/                                      # 모델 정의

📝 변경 이력

날짜 변경 내용 작성자
2025-12-19 초기 공통 정책 문서 작성 (견적에서 분리) Claude

Note: 각 기능별 개발 문서(MASTER_PLAN.md)는 이 문서를 참조합니다. 기능별 특화 내용만 각 MASTER_PLAN.md에 작성하세요.