# 00. 신규 합류자 온보딩 가이드 > **대상**: 프로젝트에 새로 합류하는 개발자 (시니어 포함) > **버전**: 1.0.0 > **최종 수정**: 2026-03-20 > **읽는 시간**: 15분 --- ## 1. SAM ERP 한눈에 보기 SAM은 **멀티테넌트 폐쇄형 ERP** 시스템입니다. 인증된 사용자만 접근 가능하며, 테넌트(고객사)별로 필요한 모듈만 활성화됩니다. ``` ┌─────────────────────────────────────────────────────────┐ │ SAM ERP Platform │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ 공통 ERP (~165 페이지) │ │ │ │ 회계 | 영업 | 인사 | 결재 | 게시판 | 설정 │ │ │ │ 고객센터 | 기준정보 | 자재/재고 | 출고/배송 │ │ │ └─────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────┐ ┌──────────────────────────┐ │ │ │ 경동 MES (~27p) │ │ 주일 건설 (~48p) │ │ │ │ 생산관리 │ │ 시공/프로젝트 │ │ │ │ 품질관리 │ │ 입찰/계약 │ │ │ └──────────────────┘ │ 기성관리 │ │ │ └──────────────────────────┘ │ │ ┌──────────────────┐ │ │ │ 옵션 모듈 │ │ │ │ 차량관리 │ │ │ └──────────────────┘ │ └─────────────────────────────────────────────────────────┘ ``` --- ## 2. 테넌트 구조 현재 3개 테넌트가 운영됩니다. | 테넌트 | 업종 | 전용 모듈 | 특징 | |--------|------|-----------|------| | 경동 | 셔터 제조 (MES) | 생산, 품질 | 작업지시/실적, 설비관리, QMS | | 주일 | 건설 시공 | 건설/프로젝트 | 현장관리, 입찰, 기성 | | (신규) | 일반 | 공통만 | 공통 ERP 기능만 사용 | ### 테넌트별 접근 제어 ``` 로그인 → 백엔드가 해당 테넌트의 메뉴 목록 반환 → PermissionGate가 화이트리스트로 접근 제어 → 메뉴에 없는 페이지 = 접근 불가 (URL 직접 입력도 차단) 경동 유저: 회계, 영업, 생산, 품질 등 접근 가능 / 건설 차단 주일 유저: 회계, 영업, 건설 등 접근 가능 / 생산, 품질 차단 ``` 상세: [v1/12-permission-whitelist.md](12-permission-whitelist.md) --- ## 3. 기술 스택 | 영역 | 기술 | |------|------| | 프레임워크 | Next.js 15 (App Router) | | 런타임 | React 19 | | 언어 | TypeScript (strict) | | UI | shadcn/ui (Radix UI) + Tailwind CSS 4 | | 상태관리 | Zustand | | 폼 | react-hook-form + Zod | | 백엔드 | PHP Laravel 12 (별도 프로젝트) | | 모바일 | Capacitor (하이브리드 앱) | ### 핵심 제약 - **모든 페이지 Client Component**: `'use client'` 필수 (HttpOnly 쿠키 인증 때문) - **Server Component 사용 금지**: SEO 불필요 + 쿠키 수정 불가 - **API 호출은 반드시 프록시**: `/api/proxy/` 또는 Server Action 경유 --- ## 4. 프로젝트 구조 ``` sam_project/ ├── sam-next/sam-react-prod/ ← 프론트엔드 (현재 프로젝트) ├── sam-api/sam-api/ ← 백엔드 (PHP Laravel) ├── sam-design/sam-design/ ← 디자인 시스템 └── sam-docs/ ← 프로젝트 문서 ``` ### 프론트엔드 디렉토리 ``` src/ ├── app/[locale]/(protected)/ # 라우트 (도메인별 폴더) │ ├── accounting/ # 회계 │ ├── sales/ # 영업 │ ├── hr/ # 인사 │ ├── approval/ # 결재 │ ├── production/ # 생산 (경동 전용) │ ├── quality/ # 품질 (경동 전용) │ ├── construction/ # 건설 (주일 전용) │ ├── dashboard/ # CEO 대시보드 │ └── settings/ # 설정 │ ├── components/ # 컴포넌트 (계층 구조) │ ├── ui/ # atoms (shadcn/ui) │ ├── molecules/ # molecules (FormField, DateRangeSelector 등) │ ├── organisms/ # organisms (PageLayout, IntegratedListTemplateV2 등) │ ├── templates/ # templates (UniversalListPage 등) │ ├── {domain}/ # 도메인별 비즈니스 컴포넌트 │ └── document-system/ # 모듈 경계 넘는 공유 컴포넌트 │ ├── stores/ # Zustand 전역 상태 ├── hooks/ # 커스텀 훅 ├── lib/ # 유틸리티, API 래퍼 ├── modules/ # 모듈 시스템 (테넌트 분리) └── contexts/ # React Context (Permission 등) ``` --- ## 5. 전역 상태 (Zustand Stores) | 스토어 | 역할 | 지속성 | |--------|------|--------| | `authStore` | 로그인 유저, 테넌트, 역할 정보 | localStorage | | `menuStore` | 사이드바 메뉴 목록, 활성 메뉴, 접힘 상태 | localStorage | | `permissionStore` | 메뉴별 권한 매트릭스 (view/create/update/delete) | 메모리 | | `masterDataStore` | 기준정보 캐시 (품목, 공정 등) | 메모리 | | `themeStore` | 테마 설정 | localStorage | | `useUIStore` | UI 상태 (사이드바 너비 등) | 메모리 | | `useItemMasterStore` | 품목 마스터 폼 상태 | 메모리 | | `favoritesStore` | 즐겨찾기 메뉴 | localStorage | | `useCalendarScheduleStore` | 캘린더 일정 | 메모리 | | `useTableColumnStore` | 테이블 컬럼 설정 (표시/숨김) | localStorage | --- ## 6. 라우팅 패턴 ### 페이지 모드 (mode 쿼리파라미터) ``` /sales/order-management → 목록 (기본) /sales/order-management?mode=new → 등록 폼 /sales/order-management/123 → 상세 (view) /sales/order-management/123?mode=edit → 수정 폼 ``` - 별도 `/new`, `/edit` 경로 사용 금지 - 목록과 등록을 같은 page.tsx에서 mode로 분기 ### 페이지 유형 | 유형 | 컴포넌트 | 특징 | |------|----------|------| | 목록 | `UniversalListPage` | 검색, 페이지네이션, 컬럼 설정, 모바일 카드 | | 상세/폼 | `Card` + `FormField` | sticky 하단 액션 바, 모드별 분기 | | 대시보드 | 섹션 기반 | 모듈별 조건부 렌더링 | --- ## 7. 도메인 맵 ### 공통 ERP (모든 테넌트) ``` 회계 (accounting/) ├── 매출/매입 관리 ├── 입출금 관리 ├── 세금계산서 ├── 거래처 원장 ├── 경조사비/접대비 └── 일보/결산 영업 (sales/) ├── 견적/수주 관리 ├── 단가 관리 ├── 생산지시 (공유 API) └── 거래처 관리 인사 (hr/) ├── 직원 관리 ├── 근태/출결 ├── 급여/휴가 └── 인사 이력 결재 (approval/) ├── 기안/수신/참조 └── 결재 양식 관리 기준정보 (master-data/) ├── 품목 마스터 ├── 공정 관리 └── 단가 테이블 자재/재고 (material/, stocks/) ├── 입고 관리 ├── 재고 현황 └── 재고 생산 출고/배송 (outbound/) ├── 출하 관리 └── 차량 배차 ``` ### 경동 전용 (셔터 제조 MES) ``` 생산 (production/) ├── 작업지시 ├── 작업실적 ├── 작업자 화면 └── 생산 대시보드 품질 (quality/) ├── 설비 관리/점검/수리 ├── 검사 관리 ├── QMS (문서관리) └── 성적서/작업일지 ``` ### 주일 전용 (건설 시공) ``` 건설 (construction/) ├── 수주/현장 관리 ├── 프로젝트 관리 │ ├── 계약/실행예산 │ ├── 입찰 관리 │ ├── 시공 관리 │ └── 인력 현황 └── 기성 관리 ``` --- ## 8. 데이터 흐름 ``` [컴포넌트] → Server Action (또는 fetch /api/proxy/...) │ ↓ [authenticatedFetch] │ ├── 정상 → 데이터 반환 ├── 401 → 자동 토큰 갱신 → 재시도 └── 실패 → 로그인 페이지 이동 Server Action 위치: src/components/{domain}/actions.ts URL 빌더: buildApiUrl('/api/v1/path', { search, page }) ``` --- ## 9. 모듈 분리 현황 코드 아키텍처 레벨에서 공통 ERP와 테넌트 전용 코드의 경계를 관리합니다. | 단계 | 상태 | 내용 | |------|------|------| | Phase 0 | 완료 | 공통 -> 테넌트 import 의존성 해소 | | Phase 1 | 완료 | 모듈 레지스트리 + useModules() 훅 | | Phase 2 | 완료 | CEO 대시보드 모듈화 (섹션/API 최적화) | | Phase 3 | 완료 | 검증 스크립트 + 경계 문서 (MODULE.md) | | 화이트리스트 | 완료 | PermissionGate 화이트리스트 전환 | ### 모듈 경계 규칙 ``` 허용: 테넌트 → 공통 import (production → ui/) 금지: 공통 → 테넌트 import (approval → production/) 금지: 테넌트 간 import (production → construction/) 공유 필요 시: document-system/ 또는 lib/api/ 래퍼 경유 ``` 검증: `scripts/verify-module-separation.sh` --- ## 10. 향후 로드맵 ``` v1 (현재) ──── 모듈 분리 완료, 권한 화이트리스트 │ v2 (진행) ──── 백엔드에서 모듈/페이지 정보 JSON API 제공 │ useModules() 내부를 API 호출로 교체 │ v3 (목표) ──── JSON 스키마 기반 동적 페이지 조립 테넌트 추가 = 어드민 설정만 → 코드 변경 0줄 ``` 상세: [v2/01-dynamic-multi-tenant-page-system.md](../v2/01-dynamic-multi-tenant-page-system.md) --- ## 11. 문서 읽기 순서 ### 첫째 날: 전체 구조 파악 | 순서 | 문서 | 핵심 | |------|------|------| | 1 | 이 문서 (00-onboarding) | 시스템 전체 그림 | | 2 | [01-architecture](01-architecture.md) | 기술 스택, 디렉토리 구조 | | 3 | [07-auth-flow](07-auth-flow.md) | 인증/토큰 흐름 | | 4 | [12-permission-whitelist](12-permission-whitelist.md) | 접근 제어 | ### 둘째 날: 개발 패턴 익히기 | 순서 | 문서 | 핵심 | |------|------|------| | 5 | [02-api-pattern](02-api-pattern.md) | API 호출 방법 | | 6 | [03-component-design](03-component-design.md) | 컴포넌트 계층 | | 7 | [04-common-components](04-common-components.md) | UniversalListPage 등 사용법 | | 8 | [05-form-pattern](05-form-pattern.md) | 폼 패턴 (Zod, FormField) | ### 셋째 날: 세부 규칙 | 순서 | 문서 | 핵심 | |------|------|------| | 9 | [06-styling-guide](06-styling-guide.md) | Tailwind, 색상 | | 10 | [08-dashboard-system](08-dashboard-system.md) | 대시보드 아키텍처 | | 11 | [09-conventions](09-conventions.md) | 네이밍, Git 규칙 | --- ## 12. Git 브랜치 전략 ``` main ────── 배포용 (검증된 것만, 기능별 squash merge) │ develop ─── 평소 작업 (자유롭게 커밋) │ feature/* ─ 큰 기능/실험적 작업 시 사용 ``` - develop에서 자유롭게 작업 - main에는 기능별 squash merge (cherry-pick + 정리) - main 직접 push 금지 --- ## 13. 개발 환경 셋업 ```bash # 1. 의존성 설치 npm install # 2. 환경변수 (.env.local) # 팀원에게 받거나 sam-docs 참고 # 3. 개발 서버 npm run dev # 4. 접속 http://localhost:3000 ``` ### 주요 명령어 | 명령어 | 용도 | |--------|------| | `npm run dev` | 개발 서버 | | `npm run build` | 프로덕션 빌드 | | `npx tsc --noEmit` | 타입 체크 | --- ## 14. 자주 하는 실수 | 실수 | 올바른 방법 | |------|-------------| | Server Component 사용 | `'use client'` 필수 | | localStorage 직접 접근 | `typeof window` 가드 필요 | | API 직접 fetch | Server Action 또는 `/api/proxy/` 사용 | | `/new`, `/edit` 라우트 생성 | `?mode=new`, `?mode=edit` 쿼리 사용 | | `DatePicker` 2개 직접 조합 | `DateRangeSelector` 사용 | | `Label + Input` 수동 조합 | `FormField` molecule 사용 | | 공통에서 테넌트 코드 import | `document-system/` 래퍼 경유 |