Files
sam-api/CURRENT_WORKS.md

25 KiB

SAM API 작업 현황

2025-12-02 (월) - 메뉴 통합관리 시스템 구현 (Phase 1-2)

작업 목표

  • 글로벌 메뉴-테넌트 메뉴 연결 시스템 구현
  • Phase 1: DB 스키마 변경 및 모델 수정
  • Phase 2: 서비스 및 API 엔드포인트 개발

Phase 1 완료 (DB 스키마 및 모델)

추가된 파일:

  • database/migrations/2025_12_02_100000_add_global_menu_link_columns_to_menus_table.php
    • global_menu_id 컬럼: 원본 글로벌 메뉴 ID
    • is_customized 컬럼: 테넌트 커스터마이징 여부
    • 인덱스 추가

수정된 파일:

  • app/Models/Commons/Menu.php

    • fillable: global_menu_id, is_customized 추가
    • casts: is_customized => boolean 등 추가
    • 관계 메서드: globalMenu(), tenantMenus()
    • 헬퍼 메서드: isGlobal(), isClonedFromGlobal(), isCustomized()
    • 스코프: scopeGlobal(), scopeActive(), scopeVisible(), scopeRoots()
    • getSyncFields(): 동기화 비교 대상 필드 목록
  • app/Services/MenuBootstrapService.php

    • cloneGlobalMenusForTenant(): global_menu_id 저장 추가
    • 활성 메뉴만 복제 (is_active=true)

Phase 2 완료 (서비스 및 API)

추가된 파일:

  • app/Services/GlobalMenuService.php (신규)

    • 글로벌 메뉴 CRUD (tenant_id = NULL)
    • syncToAllTenants(): 특정 메뉴를 모든 테넌트에 동기화
    • stats(): 글로벌 메뉴 통계
  • app/Services/MenuSyncService.php (신규)

    • 동기화 상태 상수: NEW, UP_TO_DATE, UPDATABLE, CUSTOMIZED, DELETED
    • getSyncStatus(): 동기화 상태 목록 조회
    • syncMenus(): 선택 동기화 (신규/업데이트)
    • importNewMenus(): 신규 글로벌 메뉴 일괄 가져오기
    • syncUpdates(): 변경된 메뉴 일괄 업데이트 (커스텀 제외)
    • getAvailableGlobalMenus(): 복제 가능한 글로벌 메뉴 목록
  • app/Http/Controllers/Api/Admin/GlobalMenuController.php (신규)

    • 시스템 관리자용 글로벌 메뉴 관리
    • index, tree, show, store, update, destroy, reorder
    • syncToTenants, stats

수정된 파일:

  • app/Services/MenuService.php

    • update(): 글로벌 복제 메뉴 수정 시 is_customized=true 자동 설정
    • restore(): 삭제된 메뉴 복원 추가
    • trashedList(): 삭제된 메뉴 목록 조회 추가
  • app/Http/Controllers/Api/V1/MenuController.php

    • MenuSyncService DI 추가
    • restore, trashed, availableGlobal, syncStatus, sync, syncNew, syncUpdates 메서드 추가
  • routes/api.php

    • GlobalMenuController use 문 추가
    • 테넌트 메뉴 동기화 라우트 6개 추가 (trashed, available-global, sync-status, sync, sync-new, sync-updates, restore)
    • 글로벌 메뉴 관리 라우트 9개 추가 (admin/global-menus/*)

API 엔드포인트

테넌트 메뉴 동기화 (V1):

Method Path 설명
GET /v1/menus/trashed 삭제된 메뉴 목록
GET /v1/menus/available-global 복제 가능한 글로벌 메뉴
GET /v1/menus/sync-status 동기화 상태 조회
POST /v1/menus/sync 선택 동기화
POST /v1/menus/sync-new 신규 메뉴 일괄 가져오기
POST /v1/menus/sync-updates 변경된 메뉴 일괄 업데이트
POST /v1/menus/{id}/restore 삭제된 메뉴 복원

글로벌 메뉴 관리 (Admin):

Method Path 설명
GET /v1/admin/global-menus 글로벌 메뉴 목록
POST /v1/admin/global-menus 글로벌 메뉴 생성
GET /v1/admin/global-menus/tree 글로벌 메뉴 트리
GET /v1/admin/global-menus/stats 통계 조회
POST /v1/admin/global-menus/reorder 순서 변경
GET /v1/admin/global-menus/{id} 단건 조회
PUT /v1/admin/global-menus/{id} 수정
DELETE /v1/admin/global-menus/{id} 삭제
POST /v1/admin/global-menus/{id}/sync-to-tenants 모든 테넌트에 동기화

검증 결과

  • PHP 문법 검사: 모든 파일 통과
  • 라우트 등록: 9개 글로벌 메뉴 + 7개 테넌트 동기화 라우트 확인

다음 작업 (Phase 3-4)

  • Phase 3: MNG 글로벌 메뉴 관리 화면
  • Phase 3: MNG 동기화 센터 화면
  • Phase 4: 마이그레이션 실행 및 테스트

2025-12-01 (일) - 메뉴 통합관리 시스템 설계

작업 목표

  • PDF 기획서(SAM_ERP_인사관리전자결재_Storyboard)에서 메뉴 추출
  • 글로벌 메뉴와 테넌트 메뉴 간의 연결(링크) 시스템 설계
  • 메뉴 추가 SQL 쿼리 생성

추가된 파일

  • claudedocs/MENU_INTEGRATION_SYSTEM_DESIGN.md (신규)

    • 글로벌-테넌트 메뉴 연결 시스템 설계서
    • global_menu_id, is_customized 컬럼 추가 계획
    • API 엔드포인트 설계 (글로벌/테넌트 메뉴 관리)
    • MNG 화면 설계 (복제, 동기화 기능)
    • 구현 Phase 1~4 계획
  • claudedocs/MENU_INSERT_QUERIES.sql (신규)

    • PDF 기획서 기반 신규 메뉴 23개 INSERT 쿼리
    • 인사관리 (근태/휴가/급여)
    • 전자결재 (기안함/결재함/참조함)
    • 게시판, 보고서, 계정정보, 회사정보, 구독관리, 결제내역, 고객센터
    • 기준정보 관리 하위 8개 메뉴

정책 결정 사항

항목 결정 내용
글로벌 메뉴 삭제 시 테넌트 메뉴 유지 (global_menu_id = NULL)
활성 메뉴 (is_active=1) 새 테넌트 생성 시 자동 복사
비활성 메뉴 (is_active=0) 테넌트가 수동으로 복제 가능
숨김 메뉴 (hidden=1) 복사되지만 테넌트에서 안 보임
기존 데이터 신규 테넌트부터 적용

다음 작업 (Phase별)

  • Phase 1: 마이그레이션 (global_menu_id, is_customized)
  • Phase 1: Menu 모델 수정
  • Phase 1: MenuBootstrapService 수정
  • Phase 2: GlobalMenuService 생성
  • Phase 2: MenuService 메서드 추가
  • Phase 2: API 엔드포인트 추가
  • Phase 3: MNG 글로벌 메뉴 관리 화면
  • Phase 3: MNG 테넌트 메뉴 관리 화면 개선
  • Phase 4: 테스트

Git 커밋

commit d7fdfa8
docs: 메뉴 통합관리 시스템 설계서 및 SQL 쿼리 추가

참고 문서

  • PDF: SAM_ERP_인사관리전자결재_Storyboard_D0.6_251201.pdf
  • 설계서: claudedocs/MENU_INTEGRATION_SYSTEM_DESIGN.md

2025-11-27 (수) - 시스템 게시판 기능 확장

작업 목표

  • 기존 boards 테이블에 시스템 게시판 지원 추가
  • mng에서 시스템 게시판 생성, sam에서 테넌트 게시판 + 시스템 게시판 조회

수정된 파일

Migration:

  • database/migrations/2025_11_27_205429_add_system_fields_to_boards_table.php (NEW)
    • tenant_id nullable 변경
    • is_system boolean 컬럼 추가
    • board_type VARCHAR(50) 컬럼 추가
    • deleted_at, deleted_by SoftDeletes 추가
    • 인덱스 추가

Model:

  • app/Models/Boards/Board.php

    • SoftDeletes 추가
    • fillable, casts 업데이트
    • scopeAccessible(tenantId), scopeSystemOnly(), scopeTenantOnly(tenantId) 스코프 추가
    • 권한 헬퍼 메서드 (canRead, canWrite, canManage)
  • app/Models/Boards/BoardSetting.php

    • casts, fillable 업데이트
    • getMeta() 헬퍼 추가

Service:

  • app/Services/Boards/BoardService.php (NEW)
    • 시스템/테넌트 게시판 CRUD
    • 필드 관리 (add, update, delete, reorder)
    • 유틸리티 메서드

DB 스키마 변경

-- boards 테이블 추가 컬럼
is_system TINYINT(1) DEFAULT 0 COMMENT '시스템 게시판 여부'
board_type VARCHAR(50) NULL COMMENT '게시판 유형'
deleted_at TIMESTAMP NULL
deleted_by BIGINT UNSIGNED NULL

다음 작업

  • mng 게시판 관리 화면 개발
  • sam API 개발 (Swagger 포함)
  • 검증 및 테스트

2025-11-27 (수) - sam API 게시판/게시글 API 개발

작업 목표

  • 테넌트용 게시판/게시글 V1 API 개발
  • Swagger 문서 작성

추가된 파일

Service:

  • app/Services/Boards/PostService.php (NEW)
    • 게시글 CRUD (boardCode 기반)
    • 댓글 CRUD
    • 커스텀 필드 관리
    • 조회수 증가

Controller:

  • app/Http/Controllers/Api/V1/BoardController.php (NEW)

    • index: 접근 가능한 게시판 목록 (시스템 + 테넌트)
    • tenantBoards: 테넌트 게시판만
    • show: 게시판 상세 (코드 기반)
    • store/update/destroy: 테넌트 게시판 CRUD
    • fields: 게시판 필드 목록
  • app/Http/Controllers/Api/V1/PostController.php (NEW)

    • index/show/store/update/destroy: 게시글 CRUD
    • comments/storeComment/updateComment/destroyComment: 댓글 CRUD

FormRequest:

  • app/Http/Requests/Boards/BoardStoreRequest.php (NEW)
  • app/Http/Requests/Boards/BoardUpdateRequest.php (NEW)
  • app/Http/Requests/Boards/PostStoreRequest.php (NEW)
  • app/Http/Requests/Boards/PostUpdateRequest.php (NEW)
  • app/Http/Requests/Boards/CommentStoreRequest.php (NEW)

Swagger:

  • app/Swagger/v1/BoardApi.php (NEW)

    • Board, BoardField 스키마
    • BoardCreateRequest, BoardUpdateRequest 스키마
    • 7개 엔드포인트 문서화
  • app/Swagger/v1/PostApi.php (NEW)

    • Post, PostPagination, Comment 스키마
    • PostCreateRequest, PostUpdateRequest, CommentCreateRequest 스키마
    • 9개 엔드포인트 문서화

수정된 파일

  • routes/api.php
    • BoardController, PostController import 추가
    • /v1/boards 프리픽스로 16개 라우트 등록

API 엔드포인트 (16개)

게시판 관리:

Method Path 설명
GET /v1/boards 접근 가능한 게시판 목록
GET /v1/boards/tenant 테넌트 게시판만
POST /v1/boards 테넌트 게시판 생성
GET /v1/boards/{code} 게시판 상세 (코드 기반)
PUT /v1/boards/{id} 테넌트 게시판 수정
DELETE /v1/boards/{id} 테넌트 게시판 삭제
GET /v1/boards/{code}/fields 게시판 필드 목록

게시글 관리:

Method Path 설명
GET /v1/boards/{code}/posts 게시글 목록
POST /v1/boards/{code}/posts 게시글 작성
GET /v1/boards/{code}/posts/{id} 게시글 상세
PUT /v1/boards/{code}/posts/{id} 게시글 수정
DELETE /v1/boards/{code}/posts/{id} 게시글 삭제

댓글 관리:

Method Path 설명
GET /v1/boards/{code}/posts/{postId}/comments 댓글 목록
POST /v1/boards/{code}/posts/{postId}/comments 댓글 작성
PUT /v1/boards/{code}/posts/{postId}/comments/{commentId} 댓글 수정
DELETE /v1/boards/{code}/posts/{postId}/comments/{commentId} 댓글 삭제

검증 결과

  • PHP 문법 검사: 통과
  • Pint 코드 포맷팅: 완료
  • Swagger 문서 생성: 완료
  • 라우트 등록: 16개 라우트 확인

2025-11-27 (수) - ItemMaster API group_id(계층번호) 추가 및 Swagger 보완

작업 목표

  • FormRequest에 누락된 group_id 필드 추가
  • Swagger 스키마에 group_id description="계층번호" 추가
  • API 문서 정확도 개선

배경

  • POST /api/v1/item-master/pages/{pageId}/sections Swagger 문서 점검 중 group_id 누락 발견
  • Service에서 $data['group_id'] ?? 1로 사용하지만 FormRequest와 Swagger에 미정의
  • group_id는 "계층번호"로 통일하여 주석 및 description 작성

수정된 파일 (4개)

FormRequest (group_id 필드 추가):

  • app/Http/Requests/ItemMaster/ItemSectionStoreRequest.php
  • app/Http/Requests/ItemMaster/ItemFieldStoreRequest.php
  • app/Http/Requests/ItemMaster/ItemBomItemStoreRequest.php

Swagger:

  • app/Swagger/v1/ItemMasterApi.php

Swagger 스키마 업데이트 상세

모델 스키마 (3개) - description="계층번호" 추가:

  • ItemSection
  • ItemField
  • ItemBomItem

Request 스키마 (6개) - group_id 추가 또는 description 추가:

  • ItemSectionStoreRequest - group_id 신규 추가
  • ItemFieldStoreRequest - group_id 신규 추가
  • ItemBomItemStoreRequest - group_id 신규 추가
  • IndependentSectionStoreRequest - description 추가
  • IndependentFieldStoreRequest - description 추가
  • IndependentBomItemStoreRequest - description 추가

12개 EntityRelationship 엔드포인트

EntityRelationshipApi.php에 이미 문서화 완료 확인:

  • POST/DELETE /pages/{pageId}/link-section, /unlink-section/{sectionId}
  • POST/DELETE /pages/{pageId}/link-field, /unlink-field/{fieldId}
  • GET /pages/{pageId}/relationships, /structure
  • POST/DELETE /sections/{sectionId}/link-field, /unlink-field/{fieldId}
  • POST/DELETE /sections/{sectionId}/link-bom, /unlink-bom/{bomId}
  • GET /sections/{sectionId}/relationships
  • POST /relationships/reorder

검증 결과

  • Pint 코드 포맷팅: 통과
  • Swagger 문서 생성: 완료

Git 커밋

commit 4f78eed
feat: ItemMaster API group_id(계층번호) 추가 및 Swagger 보완

2025-11-26 (화) - AccessService permission_overrides 테이블 사용으로 수정

주요 작업

  • API AccessService가 존재하지 않는 테이블(user_permission_overrides, department_permissions)을 참조하던 문제 수정
  • 실제 DB의 permission_overrides 테이블을 사용하도록 수정

수정된 파일:

  • app/Services/Authz/AccessService.php
    • hasUserOverride(): user_permission_overridespermission_overrides (model_type='App\Models\Members\User')
    • departmentAllows(): department_permissionspermission_overrides (model_type='App\Models\Tenants\Department')
    • 필드명 변경: is_allowedeffect, user_idmodel_id

기술 상세:

permission_overrides 테이블 구조:

  • model_type: 폴리모픽 타입 (User, Department)
  • model_id: 대상 ID
  • permission_id: 권한 ID
  • effect: 0=DENY, 1=ALLOW
  • effective_from, effective_to: 유효 기간

코드 품질:

  • PHP 문법 검사 통과
  • Pint 포맷팅 통과

2025-11-26 (화) - Item Master 독립 엔티티 API 추가 완료

작업 목표

  • 독립 엔티티(섹션, 필드, BOM) CRUD API 10개 추가
  • SectionTemplate 모델 삭제 → ItemSection.is_template 플래그로 통합
  • Swagger 문서 업데이트

변경 내용

1. SectionTemplate → ItemSection 통합

  • section_templates 테이블 삭제
  • item_sections 테이블에 is_template 컬럼 추가
  • 기존 /section-templates API는 유지 (내부적으로 is_template=true 사용)

2. 10개 독립 API 추가

API 메서드 설명
/sections GET 섹션 목록 (is_template 필터)
/sections POST 독립 섹션 생성
/sections/{id}/clone POST 섹션 복제
/sections/{id}/usage GET 섹션 사용처 조회
/fields GET 필드 목록
/fields POST 독립 필드 생성
/fields/{id}/clone POST 필드 복제
/fields/{id}/usage GET 필드 사용처 조회
/bom-items GET BOM 항목 목록
/bom-items POST 독립 BOM 생성

추가된 파일

  • app/Http/Requests/ItemMaster/IndependentSectionStoreRequest.php
  • app/Http/Requests/ItemMaster/IndependentFieldStoreRequest.php
  • app/Http/Requests/ItemMaster/IndependentBomItemStoreRequest.php

삭제된 파일

  • app/Models/ItemMaster/SectionTemplate.php

수정된 파일

  • app/Http/Controllers/Api/V1/ItemMaster/ItemSectionController.php
  • app/Http/Controllers/Api/V1/ItemMaster/ItemFieldController.php
  • app/Http/Controllers/Api/V1/ItemMaster/ItemBomItemController.php
  • app/Services/ItemMaster/ItemSectionService.php
  • app/Services/ItemMaster/ItemFieldService.php
  • app/Services/ItemMaster/ItemBomItemService.php
  • app/Models/ItemMaster/ItemSection.php (is_template, scopeTemplates 추가)
  • routes/api.php
  • app/Swagger/v1/ItemMasterApi.php

마이그레이션

# 실행된 마이그레이션
2025_11_26_120000_add_is_template_to_item_sections_and_drop_section_templates.php

검증 결과

  • PHP 문법 검사: 통과
  • Pint 코드 포맷팅: 통과
  • Swagger 문서 생성: 완료

2025-11-26 (화) - Item Master 하이브리드 구조 전환 (독립 엔티티 + 링크 테이블) 완료

작업 목표

기존 CASCADE FK 기반 계층 구조를 독립 엔티티 + 링크 테이블 구조로 전환

배경

  • 문제점: 현재 구조에서 섹션 삭제 시 항목(필드)도 함께 삭제됨 (CASCADE)
  • 요구사항:
    • 페이지, 섹션, 항목은 독립적으로 존재
    • 관계는 링크 테이블로 관리 (Many-to-Many)
    • 페이지에서 섹션/항목 모두 직접 연결 가능
    • 섹션에서 항목 연결 가능
    • 엔티티 삭제 시 링크만 제거, 다른 엔티티는 유지
    • group_id로 카테고리 격리 (품목관리=1, 향후 확장)

변경 구조

Before (CASCADE FK):

item_pages
  ↓ page_id FK (CASCADE)
item_sections
  ↓ section_id FK (CASCADE)
item_fields / item_bom_items

After (독립 + 링크):

item_pages (독립)
item_sections (독립)
item_fields (독립)
item_bom_items (독립)
  ⇄ entity_relationships (링크 테이블)

Phase 계획

Phase 작업 내용 상태
1 마이그레이션: FK 제거 + group_id 추가 완료
2 마이그레이션: entity_relationships 테이블 생성 완료
3 마이그레이션: 기존 데이터 이관 완료
4 모델 및 Service 수정 완료
5 새로운 API 엔드포인트 추가 완료
6 Swagger 문서 업데이트 완료
7 테스트 및 검증 완료

추가된 파일

마이그레이션 (Batch 26으로 실행):

  • database/migrations/2025_11_26_100001_convert_item_tables_to_independent_entities.php
  • database/migrations/2025_11_26_100002_create_entity_relationships_table.php
  • database/migrations/2025_11_26_100003_migrate_existing_relationships_to_entity_relationships.php

모델:

  • app/Models/ItemMaster/EntityRelationship.php (신규)

서비스:

  • app/Services/ItemMaster/EntityRelationshipService.php (신규)

컨트롤러:

  • app/Http/Controllers/Api/V1/ItemMaster/EntityRelationshipController.php (신규)

Request:

  • app/Http/Requests/ItemMaster/LinkEntityRequest.php (신규)
  • app/Http/Requests/ItemMaster/ReorderRelationshipsRequest.php (신규)

Swagger:

  • app/Swagger/v1/EntityRelationshipApi.php (신규)

수정된 파일

모델 (group_id 추가 + relationship 메서드):

  • app/Models/ItemMaster/ItemPage.php
  • app/Models/ItemMaster/ItemSection.php
  • app/Models/ItemMaster/ItemField.php
  • app/Models/ItemMaster/ItemBomItem.php
  • app/Models/ItemMaster/SectionTemplate.php
  • app/Models/ItemMaster/ItemMasterField.php

라우트:

  • routes/api.php (새로운 엔드포인트 추가)

언어 파일:

  • lang/ko/message.php (linked, unlinked 추가)
  • lang/ko/error.php (page_not_found, section_not_found, field_not_found, bom_not_found 추가)

새로운 API 엔드포인트 (14개)

페이지-섹션 연결:

  • POST /api/v1/item-master/pages/{pageId}/link-section
  • DELETE /api/v1/item-master/pages/{pageId}/unlink-section/{sectionId}

페이지-필드 직접 연결:

  • POST /api/v1/item-master/pages/{pageId}/link-field
  • DELETE /api/v1/item-master/pages/{pageId}/unlink-field/{fieldId}

페이지 관계 조회:

  • GET /api/v1/item-master/pages/{pageId}/relationships
  • GET /api/v1/item-master/pages/{pageId}/structure

섹션-필드 연결:

  • POST /api/v1/item-master/sections/{sectionId}/link-field
  • DELETE /api/v1/item-master/sections/{sectionId}/unlink-field/{fieldId}

섹션-BOM 연결:

  • POST /api/v1/item-master/sections/{sectionId}/link-bom
  • DELETE /api/v1/item-master/sections/{sectionId}/unlink-bom/{bomId}

섹션 관계 조회:

  • GET /api/v1/item-master/sections/{sectionId}/relationships

관계 순서 변경:

  • POST /api/v1/item-master/relationships/reorder

검증 결과

  • PHP 문법 검사: 통과
  • Pint 코드 포맷팅: 통과 (9개 신규 파일)
  • Swagger 문서 생성: 완료
  • 라우트 등록: 44개 item-master 라우트 확인

롤백 방법

php artisan migrate:rollback --step=3

다음 작업 (옵션)

  • 기존 API (POST /pages/{pageId}/sections 등) 내부적으로 entity_relationships 사용하도록 수정
  • 독립 엔티티 CRUD API 추가 (POST /sections, POST /fields 등)

2025-11-25 (월) - API 인증 에러 처리 개선 및 요청 로그 강화

문제 상황

  • GET /item-master/init 요청 시 Route [login] not defined 에러 발생
  • user_id null (인증 실패 상태)
  • API Request 로그에 헤더 정보 누락

근본 원인

  1. Handler.php: expectsJson() 체크만 있어서, Accept 헤더 없는 API 요청이 기본 동작(로그인 리다이렉트)으로 처리됨
  2. ApiKeyMiddleware: 요청 로그에 헤더 정보 (X-API-KEY, Authorization) 미포함

해결 방안

Handler.php (app/Exceptions/Handler.php)

  • Line 60: API 라우트 체크 추가 (str_starts_with($request->path(), 'api/'))
  • Line 62: $request->expectsJson() || $isApiRoute 조건으로 변경
  • 효과: Accept 헤더 없어도 API 라우트는 무조건 JSON 응답 반환

ApiKeyMiddleware (app/Http/Middleware/ApiKeyMiddleware.php)

  • Line 52-57: headers 필드 추가
    • X-API-KEY: 마스킹 ('***')
    • Authorization: Bearer 토큰 마스킹 ('Bearer ***')
    • Accept, Content-Type: 원본 그대로
  • 효과: 인증 문제 디버깅 용이

수정된 파일

  • app/Exceptions/Handler.php
  • app/Http/Middleware/ApiKeyMiddleware.php

검증 결과

  • PHP 문법 체크: 통과
  • Pint 코드 포맷팅: 통과

기대 효과

  1. API 요청 시 Accept 헤더 없어도 정상 JSON 응답
  2. 인증 실패 시 로그인 리다이렉트 대신 401 JSON 응답
  3. 요청 로그에서 헤더 정보 확인 가능 (디버깅 개선)

2025-11-24 (일) - 소프트삭제 및 타임스탬프 감사 컬럼 추가

작업 목표

  • deleted_at이 있는 테이블에 deleted_by 컬럼 추가
  • created_at, updated_at이 있는 테이블에 created_by, updated_by 컬럼 추가

작업 내용

1. DB 스키마 분석 (INFORMATION_SCHEMA 쿼리)

  • deleted_at은 있지만 deleted_by가 없는 테이블: 30개
  • created_at은 있지만 created_by, updated_by가 없는 테이블: 45개

2. 마이그레이션 생성

  • 2025_11_24_192518_add_deleted_by_to_soft_delete_tables.php

    • 30개 테이블에 deleted_by 추가
    • nullable, COMMENT('삭제자 사용자 ID')
    • after('deleted_at') 배치
  • 2025_11_24_192518_add_audit_columns_to_tables.php

    • 38개 비즈니스 테이블에 created_by, updated_by 추가
    • 시스템 테이블 제외 (jobs, job_batches, password_reset_tokens, personal_access_tokens, taggables, tags)
    • nullable, COMMENT
    • after('updated_at'), after('created_by') 배치

3. 마이그레이션 실행 및 검증

  • 실행 시간: deleted_by (429.53ms), audit_columns (1초)
  • 샘플 테이블 검증: users, products, models, bom_templates, department_user 모두 정상

추가된 파일

  • database/migrations/2025_11_24_192518_add_deleted_by_to_soft_delete_tables.php
  • database/migrations/2025_11_24_192518_add_audit_columns_to_tables.php

마이그레이션 상태

  • Batch 25로 실행 완료
  • 롤백 가능 (down 메서드 구현)

2025-11-24 (일) - CORS Preflight 문제 해결

문제 상황

  • React 프론트엔드(http://192.0.0.2:3001)에서 API 호출 시 CORS 에러
  • 에러: Request header field x-api-key is not allowed by Access-Control-Allow-Headers in preflight response
  • 서버 로그: OPTIONS 요청만 있고 Response 로그 없음 (401 차단)

근본 원인 (root-cause-analyst 스킬 활용)

  1. CorsMiddleware에서 Access-Control-Allow-HeadersX-API-KEY 누락
  2. OPTIONS 요청(Preflight)이 ApiKeyMiddleware에서 401로 차단
  3. 브라우저는 커스텀 헤더 사용 시 Preflight 요청을 자동 전송

해결 방안

CorsMiddleware 수정:

  • OPTIONS 요청을 미들웨어 체인 진입 전에 즉시 200 OK 처리
  • Access-Control-Allow-HeadersX-API-KEY 추가
  • PATCH 메서드 추가, Max-Age 86400초 설정

ApiKeyMiddleware 정리:

  • 불필요한 OPTIONS 체크 제거

CORS 설정 업데이트:

  • config/cors.php: exposed_headers, max_age 설정

수정된 파일

  • app/Http/Middleware/CorsMiddleware.php
  • app/Http/Middleware/ApiKeyMiddleware.php
  • config/cors.php

Git 커밋

  • 2e96660 - CORS preflight 요청 처리 개선 및 X-API-KEY 헤더 허용
  • 8e8ab65 - CORS preflight 응답에 x-api-key 헤더 허용 추가

다음 작업

  • React에서 API 호출 테스트
  • 개발 서버 로그 확인 (Request/Response 쌍 기록 여부)

2025-11-20 (수) - ItemMaster API 테스트 및 버그 수정

주요 작업

  • ItemMaster API 통합 테스트 작성 (12개 테스트, 82개 assertion)
  • 누락된 마이그레이션 실행 (section_templates, tab_columns)
  • API Key 미들웨어 수정 (로그인 엔드포인트 API Key 필수화)
  • ReorderRequest validation 수정 (범용성 확보)
  • 네임스페이스 오류 수정 (5개 Controller)
  • Route 순서 수정 (specific route 우선)

테스트 결과

12/12 테스트 통과 (100%)


2025-11-19 (화) - ItemMaster API Swagger 문서 작성

주요 작업

  • ItemMaster 전체 API (32개 엔드포인트) Swagger 문서화 완료
  • OpenAPI 3.0 표준 준수
  • Model Schemas 8개, Request Schemas 12개 작성

2025-11-18 (월) - Category API 테스트 및 개선

주요 작업

  • Category CRUD 테스트 작성 (9개 테스트, 98개 assertion)
  • 계층 구조 및 필드 관리 테스트
  • Validation 로직 개선