10 KiB
Claude Code 프로젝트 설정
Git 커밋 규칙 (최우선 필수 규칙)
경고: 이 규칙은 절대 누락되어서는 안 됩니다!
적용 범위
/home/aweso/sam/ 하위의 모든 폴더에 적용:
/home/aweso/sam/mng- 관리자 웹 (Laravel)/home/aweso/sam/api- API 서버 (Laravel)- 기타 sam 하위 폴더
각 폴더는 독립적인 Git 저장소입니다. 해당 폴더에서 git 명령을 실행해야 합니다.
필수 수행 절차
모든 코드 작업 완료 후 반드시 다음을 수행:
- 변경된 파일이 있는 폴더로 이동
git status로 변경사항 확인git add <파일들>로 스테이징git commit -m "type:메시지"로 커밋
커밋 메시지 형식 (필수)
| Prefix | 사용 시점 | 예시 |
|---|---|---|
feat: |
새로운 파일/기능 생성 | feat:재무 대시보드 추가 |
fix: |
버그 수정, 코드 수정 | fix:HTMX 리다이렉트 오류 수정 |
refactor: |
코드 리팩토링 | refactor:서비스 클래스 구조 개선 |
docs: |
문서 수정 | docs:README 업데이트 |
chore: |
설정, 빌드 관련 | chore:CLAUDE.md 설정 추가 |
커밋 예시
# mng 폴더 작업 후
cd /home/aweso/sam/mng
git add app/Http/Controllers/SomeController.php
git add resources/views/some-view.blade.php
git commit -m "feat:새로운 기능 추가"
# api 폴더 작업 후
cd /home/aweso/sam/api
git add app/Http/Controllers/Api/SomeApiController.php
git commit -m "fix:API 응답 오류 수정"
Claude Code 설정 파일도 커밋 대상
다음 파일들이 변경되면 반드시 커밋:
| 파일/폴더 | 설명 | 커밋 예시 |
|---|---|---|
CLAUDE.md |
프로젝트 설정 | docs:CLAUDE.md 규칙 업데이트 |
claudedocs/ |
Claude 관련 문서 | docs:기능 분석 문서 추가 |
.claude/settings.json |
Claude 설정 | chore:Claude 설정 변경 |
agents/, skills/ |
커스텀 에이전트/스킬 | feat:새 스킬 추가 |
# CLAUDE.md 변경 시
git add CLAUDE.md
git commit -m "docs:CLAUDE.md 규칙 업데이트"
# claudedocs 문서 추가 시
git add claudedocs/new-feature.md
git commit -m "docs:새 기능 분석 문서 추가"
체크리스트 (작업 완료 시 확인)
- mng 폴더 변경사항 확인 → git add → git commit
- api 폴더 변경사항 확인 → git add → git commit
- CLAUDE.md, claudedocs/, agents/, skills/ 변경 확인 → git commit
- 커밋 메시지에 적절한 prefix 사용 (feat:/fix:/refactor:/docs:/chore:)
- 한글로 명확한 커밋 메시지 작성
프로젝트 기술 스택
- Backend: Laravel 11 (PHP 8.3)
- Frontend: Blade + HTMX + Tailwind CSS
- React 페이지: React 18 + Babel (브라우저 트랜스파일링)
- Database: MySQL 8
Tailwind CSS 레이아웃 규칙 (필수)
경고: 이 프로젝트는 Tailwind CSS 빌드 시점에 포함되지 않은 유틸리티 클래스가 런타임에 적용되지 않습니다.
반응형 클래스 대신 inline style 사용
Tailwind 반응형 클래스(sm:, md:, lg:)가 빌드에 누락될 수 있으므로, 레이아웃 관련 속성은 inline style을 사용한다.
❌ class="w-full sm:w-1/3 sm:flex-nowrap"
✅ style="flex: 1 1 250px; max-width: 400px;"
flex 레이아웃 패턴
| 항목 유형 | 사용 방법 | 예시 |
|---|---|---|
| 가변 너비 | inline style flex | style="flex: 1 1 250px; max-width: 400px;" |
| 고정 너비 | shrink-0 + inline width |
class="shrink-0" style="width: 140px;" |
| 줄바꿈 방지 | whitespace-nowrap |
class="whitespace-nowrap" |
flex 컨테이너 직계 자식에서 w-full 금지
flex-wrap 컨테이너에서 w-full은 항목이 한 줄 전체를 차지하여 줄바꿈을 유발한다. flex 자식 요소의 너비는 flex 속성이나 inline style로 제어한다.
❌ <div class="w-full sm:w-1/3"> ← w-full이 줄바꿈 유발
✅ <div style="flex: 1 1 250px; max-width: 400px;"> ← inline flex로 제어
Tailwind 기본 클래스는 그대로 사용
색상, 패딩, 마진, 보더, 라운드 등 비-반응형 클래스는 Tailwind 사용:
class="px-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-800"
Blade + React(JSX) 혼용 규칙 (필수)
경고: Blade 파일에서 React/JSX 코드 수정 시 반드시 확인하세요! 정책 문서:
/home/aweso/sam/docs/dev/standards/blade-react-policy.md
핵심 원칙
Blade 엔진은 @verbatim 외부의 모든 이중 중괄호를 PHP echo로 변환한다. JSX의 style= 이중중괄호 패턴은 Blade와 충돌하여 **500 에러(ParseError)**를 유발한다.
필수 준수 사항
❌ @verbatim 없는 파일에서 style={{ key: 'value' }} 사용 금지
❌ JS 주석에 이중 중괄호 텍스트 포함 금지
✅ 스타일 객체를 JS 변수로 선언 후 단일 중괄호로 참조
✅ React/JSX 코드 수정 전 @verbatim 사용 여부 확인
허용 패턴
// 변수로 분리 (Blade 충돌 없음)
const tableStyle = { tableLayout: 'fixed' };
const colWidths = [{ width: '10%' }, { width: '22%' }];
// 단일 중괄호로 참조
<table style={tableStyle}>
<col style={colWidths[0]} />
</table>
현재 파일 현황
| 파일 | @verbatim | 주의 |
|---|---|---|
finance/journal-entries.blade.php |
✅ | 안전 |
barobill/ecard/index.blade.php |
❌ | 주의 필요 |
데이터베이스 아키텍처 (필수 규칙)
codebridge 서버 분리 이후, MNG는 자체 DB 마이그레이션을 관리합니다.
핵심 원칙
| 작업 | MNG 전용 테이블 | 공용 테이블 |
|---|---|---|
| 마이그레이션 생성 | ✅ mng/database/migrations/ |
⚠️ api/database/migrations/ |
| 마이그레이션 실행 | docker exec sam-mng-1 php artisan migrate |
docker exec sam-api-1 php artisan migrate |
| 모델 생성 | ✅ mng/app/Models/ |
✅ mng/app/Models/ |
MNG database 폴더 상태
/home/aweso/sam/mng/database/
├── migrations/ ← MNG 전용 테이블 마이그레이션 (예: pmis_*)
├── seeders/ ← MNG 전용 시더 (예: MngMenuSeeder)
└── factories/ ← 필요 시 사용
MNG에서 허용되는 것
- ✅ 컨트롤러, 뷰, 라우트 작성
- ✅ 모델 작성
- ✅ MNG 전용 테이블 마이그레이션 생성/실행
- ✅ MNG 전용 시더 (MngMenuSeeder 등)
공용 테이블이 필요할 때
공용 테이블(API와 MNG 모두 사용)은 API에서 관리:
- API 프로젝트에서 마이그레이션 생성
docker exec sam-api-1 php artisan migrate실행- MNG에서 해당 테이블의 모델 작성
HTMX 네비게이션 규칙
HX-Redirect가 필요한 페이지
복잡한 JavaScript가 @push('scripts')에 있는 페이지는 HTMX 부분 로드 시 스크립트가 실행되지 않으므로 전체 페이지 리로드 필요:
public function index(Request $request): View|Response
{
if ($request->header('HX-Request')) {
return response('', 200)->header('HX-Redirect', route('...'));
}
// ...
}
적용 대상:
- React 컴포넌트 사용 페이지 (VAT, 미수금, 미지급금 등)
- API Explorer, Flow Tester
- Daily Logs (toggleAttentionItem 등 함수 사용)
HX-Redirect가 불필요한 페이지
단순 Blade 템플릿 (JavaScript 없음):
- 재무 대시보드
- 계좌관리 (accounts/*)
- FCM 관리
- API Logs
Docker 환경 명령어
기본 Docker 컨테이너
sam-mng-1 # Laravel MNG 앱
sam-api-1 # Laravel API 앱
sam-mysql-1 # MySQL 데이터베이스
sam-nginx-1 # Nginx 웹서버
sam-phpmyadmin-1 # phpMyAdmin
Artisan 명령어 실행
# MNG 앱에서 artisan 명령 실행
docker exec sam-mng-1 php artisan <명령어>
# API 앱에서 artisan 명령 실행
docker exec sam-api-1 php artisan <명령어>
메뉴 관리 (DB 기반) - 수동 관리 필수!
경고: 메뉴 시더(Seeder)를 절대 실행하지 마세요!
배경
사이드바 메뉴는 DB의 menus 테이블에 저장됩니다.
메뉴 시더 실행 시 부서별 권한 설정(permission_overrides)이 초기화되므로 시더 사용을 금지합니다.
금지 사항
❌ php artisan db:seed --class=MngMenuSeeder 실행 금지
❌ php artisan db:seed --class=*MenuSeeder 실행 금지
❌ 메뉴 시더 파일 생성 금지
❌ 메뉴 데이터를 일괄 삭제 후 재생성하는 방식 금지
메뉴 변경 시 올바른 절차
로컬에서 메뉴를 추가/수정한 후, 개발서버·운영서버에는 MNG의 메뉴 동기화 기능으로 반영한다.
- 로컬: Claude가 Docker tinker로 직접 메뉴 추가/수정 가능
- 개발서버·운영서버: 코드 푸시와 별도로, MNG 내장 메뉴 동기화 기능에서 처리
- 절대 시더를 만들어 실행하지 않음
✅ 로컬: docker exec sam-mng-1 php artisan tinker 로 직접 메뉴 추가
✅ 개발/운영: MNG 메뉴 동기화 기능에서 사용자가 직접 동기화
❌ 메뉴를 위해 별도로 서버에 SSH 접속하여 tinker 실행 불필요
❌ 메뉴 변경을 git push로 반영하지 않음 (메뉴는 DB 데이터)
로컬 메뉴 추가 예시
# 부모 메뉴 ID 조회
docker exec sam-mng-1 php artisan tinker --execute="
\App\Models\Commons\Menu::withoutGlobalScopes()
->where('name', 'LIKE', '%검색어%')
->get(['id', 'parent_id', 'name', 'url'])
->each(fn(\$m) => print(\$m->id . ' | parent:' . \$m->parent_id . ' | ' . \$m->name . PHP_EOL));
"
# 메뉴 추가
docker exec sam-mng-1 php artisan tinker --execute="
\App\Models\Commons\Menu::create([
'tenant_id' => 1,
'parent_id' => <부모ID>,
'name' => '새 메뉴',
'url' => '/new-menu',
'icon' => 'icon-name',
'sort_order' => 1,
'is_active' => true,
]);
"
# 메뉴 이름 변경
docker exec sam-mng-1 php artisan tinker --execute="
\App\Models\Commons\Menu::withoutGlobalScopes()->find(<ID>)->update(['name' => '새이름']);
"
# 메뉴 비활성화 (삭제 대신)
docker exec sam-mng-1 php artisan tinker --execute="
\App\Models\Commons\Menu::withoutGlobalScopes()->find(<ID>)->update(['is_active' => false]);
"
주의사항
- 메뉴 변경 시 라우트(
routes/web.php)와 컨트롤러도 함께 추가해야 함 - 새 메뉴 추가 후 부서별 권한 설정이 필요하면 사용자에게 안내