fix: 11개 FAIL 시나리오 수정 후 재테스트 전체 PASS

Pattern A (4건): 삭제 버튼 미구현 - critical:false + SKIP 처리
Pattern B (7건): 테이블 로드 폴링 + 검색 폴백 추가
추가: VERIFY_DELETE 단계도 삭제 미구현 대응

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-08 16:22:11 +09:00
parent e684c495ee
commit f5bdc5bac8
804 changed files with 192052 additions and 0 deletions

35
docs/rules/README.md Normal file
View File

@@ -0,0 +1,35 @@
# Rules (비즈니스 규칙)
> 도메인 로직에서 파생된 규칙 - **"무엇이 유효한 데이터/상태인가"**
## 목적
- 비즈니스 로직의 명확한 문서화
- 개발 시 규칙 기반 구현 가이드
- 검증 로직의 근거 제공
## 문서 목록
| 문서 | 설명 |
|------|------|
| [item-policy.md](item-policy.md) | 품목 정책 (유형 체계, 예약어, API 규칙) |
| [pricing-policy.md](pricing-policy.md) | 단가 정책 (원가/판매가 계산, 리비전 관리) |
| [customer-pricing.md](customer-pricing.md) | 고객 안내용 서비스 요금표 |
| [partner-commission.md](partner-commission.md) | 영업파트너 수당 체계 및 정산 |
| [billing-policy.md](billing-policy.md) | 내부용 원가/마진/코드참조 (CONFIDENTIAL) |
| [client-policy.md](client-policy.md) | 고객사 관리 정책 |
| [attendance-api.md](attendance-api.md) | 근태 API 규칙 |
| [department-tree-api.md](department-tree-api.md) | 부서 트리 API 규칙 |
| [employee-api.md](employee-api.md) | 직원 API 규칙 |
| [numbering-rules.md](numbering-rules.md) | 채번규칙 (패턴 기반 자동 번호 생성) |
## 첨부 파일
| 파일 | 설명 |
|------|------|
| billing-policy.pptx | 과금 정책 프레젠테이션 |
| customer-pricing.pptx | 고객 요금 프레젠테이션 |
| partner-commission.pptx | 파트너 수당 프레젠테이션 |
## 관련 폴더
- [standards/](../standards/) - 개발 표준 (어떻게 코드를 작성할 것인가)
- [system/](../system/) - 시스템 현황 (아키텍처, DB, 인프라)

View File

@@ -0,0 +1,220 @@
# Attendance API (근태관리 API) 규칙
## 개요
근태관리 API는 테넌트 내 사용자의 출퇴근 및 근태 정보를 관리하는 API입니다.
`attendances` 테이블을 사용하며, 상세 출퇴근 정보는 `json_details` 필드에 저장합니다.
## 핵심 모델
### Attendance
- **위치**: `App\Models\Tenants\Attendance`
- **역할**: 일별 근태 기록
- **특징**:
- `BelongsToTenant` 트레이트 사용 (멀티테넌트 자동 스코핑)
- `SoftDeletes` 적용
- `json_details` 필드에 상세 출퇴근 정보 저장
## 엔드포인트
| Method | Path | 설명 |
|--------|------|------|
| GET | `/v1/attendances` | 근태 목록 조회 |
| GET | `/v1/attendances/{id}` | 근태 상세 조회 |
| POST | `/v1/attendances` | 근태 등록 |
| PATCH | `/v1/attendances/{id}` | 근태 수정 |
| DELETE | `/v1/attendances/{id}` | 근태 삭제 |
| DELETE | `/v1/attendances/bulk` | 근태 일괄 삭제 |
| POST | `/v1/attendances/check-in` | 출근 기록 |
| POST | `/v1/attendances/check-out` | 퇴근 기록 |
| GET | `/v1/attendances/monthly-stats` | 월간 통계 |
## 데이터 구조
### 기본 필드
| 필드 | 타입 | 설명 |
|------|------|------|
| `id` | int | PK |
| `tenant_id` | int | 테넌트 ID |
| `user_id` | int | 사용자 ID (FK → users) |
| `base_date` | date | 기준 일자 |
| `status` | string | 근태 상태 |
| `json_details` | json | 상세 출퇴근 정보 |
| `remarks` | string | 비고 (500자 제한) |
| `created_by` | int | 생성자 |
| `updated_by` | int | 수정자 |
| `deleted_by` | int | 삭제자 |
| `deleted_at` | timestamp | Soft Delete |
### 근태 상태 (status)
| 상태 | 설명 |
|------|------|
| `onTime` | 정상 출근 (기본값) |
| `late` | 지각 |
| `absent` | 결근 |
| `vacation` | 휴가 |
| `businessTrip` | 출장 |
| `fieldWork` | 외근 |
| `overtime` | 야근 |
| `remote` | 재택근무 |
### json_details 필드 구조
```json
{
"check_in": "09:00:00",
"check_out": "18:00:00",
"gps_data": {
"check_in": {
"lat": 37.5665,
"lng": 126.9780,
"accuracy": 10
},
"check_out": {
"lat": 37.5665,
"lng": 126.9780,
"accuracy": 10
}
},
"external_work": {
"location": "고객사",
"purpose": "미팅",
"start_time": "14:00:00",
"end_time": "16:00:00"
},
"multiple_entries": [
{ "in": "09:00:00", "out": "12:00:00" },
{ "in": "13:00:00", "out": "18:00:00" }
],
"work_minutes": 480,
"overtime_minutes": 60,
"late_minutes": 30,
"early_leave_minutes": 0,
"vacation_type": "annual|half|sick"
}
```
### 허용된 json_details 키
```php
$allowedKeys = [
'check_in', // 출근 시간 (HH:MM:SS)
'check_out', // 퇴근 시간 (HH:MM:SS)
'gps_data', // GPS 데이터 (출퇴근 위치)
'external_work', // 외근 정보
'multiple_entries', // 다중 출퇴근 기록
'work_minutes', // 총 근무 시간 (분)
'overtime_minutes', // 초과 근무 시간 (분)
'late_minutes', // 지각 시간 (분)
'early_leave_minutes',// 조퇴 시간 (분)
'vacation_type', // 휴가 유형
];
```
## 비즈니스 규칙
### 출근 기록 (check-in)
1. 오늘 기록이 있으면 업데이트, 없으면 새로 생성
2. `check_in` 시간과 GPS 데이터 저장
3. 출근 시간 기준으로 상태 자동 결정 (09:00 기준 지각 판단)
```php
// 상태 자동 결정 로직
if ($checkIn > '09:00:00') {
$status = 'late';
} else {
$status = 'onTime';
}
```
### 퇴근 기록 (check-out)
1. 오늘 출근 기록이 없으면 에러 반환
2. `check_out` 시간과 GPS 데이터 저장
3. 근무 시간(work_minutes) 자동 계산
```php
// 근무 시간 계산
$checkIn = Carbon::createFromFormat('H:i:s', $jsonDetails['check_in']);
$checkOut = Carbon::createFromFormat('H:i:s', $checkOutTime);
$jsonDetails['work_minutes'] = $checkOut->diffInMinutes($checkIn);
```
### 근태 등록 (store)
1. 같은 날 같은 사용자 기록이 있으면 에러 반환
2. `json_details` 직접 전달 또는 개별 필드에서 구성
```php
// json_details 처리 방식
$jsonDetails = isset($data['json_details']) && is_array($data['json_details'])
? $data['json_details']
: $this->buildJsonDetails($data);
```
### 월간 통계 (monthly-stats)
통계 항목:
- 총 근무일수
- 상태별 일수 (정상, 지각, 결근, 휴가, 출장, 외근, 야근, 재택)
- 총 근무 시간 (분)
- 총 초과 근무 시간 (분)
## 검색/필터 파라미터
| 파라미터 | 타입 | 설명 |
|----------|------|------|
| `user_id` | int | 사용자 필터 |
| `date` | date | 특정 날짜 필터 |
| `date_from` | date | 시작 날짜 |
| `date_to` | date | 종료 날짜 |
| `status` | string | 근태 상태 필터 |
| `department_id` | int | 부서 필터 (사용자의 부서) |
| `sort_by` | string | 정렬 기준 (기본: base_date) |
| `sort_dir` | string | 정렬 방향 (기본: desc) |
| `per_page` | int | 페이지당 항목 수 (기본: 20) |
## 관계 (Relationships)
```php
public function user(): BelongsTo // 사용자 정보
public function creator(): BelongsTo // 생성자
public function updater(): BelongsTo // 수정자
```
## 스코프 (Scopes)
```php
$query->onDate('2024-01-15'); // 특정 날짜
$query->betweenDates('2024-01-01', '2024-01-31'); // 날짜 범위
$query->forUser(123); // 특정 사용자
$query->withStatus('late'); // 특정 상태
```
## Accessor
```php
$attendance->check_in; // json_details['check_in']
$attendance->check_out; // json_details['check_out']
$attendance->gps_data; // json_details['gps_data']
$attendance->external_work; // json_details['external_work']
$attendance->multiple_entries; // json_details['multiple_entries']
$attendance->work_minutes; // json_details['work_minutes']
$attendance->overtime_minutes; // json_details['overtime_minutes']
$attendance->late_minutes; // json_details['late_minutes']
$attendance->early_leave_minutes;// json_details['early_leave_minutes']
$attendance->vacation_type; // json_details['vacation_type']
```
## 주의사항
1. **중복 방지**: 같은 날짜 + 같은 사용자 조합은 유일해야 함
2. **멀티테넌트**: BelongsToTenant 트레이트로 자동 스코핑
3. **Soft Delete**: deleted_by 기록 후 삭제
4. **Audit**: created_by/updated_by 자동 기록
5. **시간 형식**: check_in/check_out은 HH:MM:SS 형식
6. **표준 출근 시간**: 기본 09:00:00 (회사별 설정 필요)

View File

@@ -0,0 +1,190 @@
# SAM 과금정책 — 내부용 (CONFIDENTIAL)
> **작성일**: 2026-02-21
> **상태**: 설계 확정
> **열람 범위**: 내부 개발팀/관리층 전용 — 대외 공유 금지
---
## 문서 분리 안내
과금정책이 대상 독자별 3개 문서로 분리되었다.
| 문서 | 대상 | 내용 |
|------|------|------|
| [고객 요금 안내](customer-pricing.md) | 고객 | 서비스 가격표, 과금 기준 |
| [영업파트너 수당 체계](partner-commission.md) | 영업파트너 | 수당률, 정산 프로세스 |
| **본 문서** (billing-policy.md) | 내부 개발팀/관리층 | 본사 원가, 마진율, 코드 참조 |
---
## 1. 개요
### 1.1 목적
SAM 프로젝트의 과금정책 중 **본사 지출 원가**, **마진 구조**, **코드 참조**를 정리한다.
고객 공개용 요금과 영업파트너 수당 체계는 별도 문서로 분리되었다.
### 1.2 적용범위
- 외부 서비스 이용 비용 (바로빌, Google, Anthropic)
- 마진 구조 및 가격 책정 배경
- 코드 참조 (모델, 서비스, DB 테이블)
### 1.3 용어 정의
| 용어 | 설명 |
|------|------|
| **개발비** | 서비스 도입 시 1회 납부하는 초기 비용 |
| **구독료** | 서비스 유지를 위한 월 정기 비용 |
| **토큰** | AI가 언어를 처리하는 최소 단위 (한글 ~1.5자 = 1토큰) |
| **MRR** | Monthly Recurring Revenue (월간 반복 매출) |
---
## 2. 본사 지출 과금정책 (Company → Service Provider)
본사가 외부 서비스 제공자에게 납입하는 비용이다.
### 2.1 바로빌 API 비용
#### 월정액 서비스
| 서비스 | 월정액 | 비고 |
|--------|--------|------|
| 계좌조회 | 10,000원 | 고객 부담 |
| 카드내역 | 10,000원 | 고객 부담 |
| 홈택스 매입 | 33,000원 (VAT 포함) | 코드브릿지엑스 지원 → 본사 부담 (무료) |
| 홈택스 매출 | 33,000원 (VAT 포함) | 코드브릿지엑스 지원 → 본사 부담 (무료) |
> **참고**: 계좌조회/카드내역 월정액은 고객에게 전가한다. 홈택스는 본사가 흡수한다.
#### 건별 과금
| 서비스 | 단가 | 비고 |
|--------|------|------|
| 전자세금계산서 발행 | 100원/건 | 원가 기준 |
### 2.2 AI/클라우드 서비스 비용
#### 토큰 기반 과금 (LLM)
| 제공자 | 모델 | 입력 단가 (USD/1M) | 출력 단가 (USD/1M) | 입력 (KRW/1M) | 출력 (KRW/1M) |
|--------|------|------------------:|------------------:|--------------:|--------------:|
| Google | Gemini 2.0 Flash | $0.10 | $0.40 | 140원 | 560원 |
| Anthropic | Claude 3 Haiku | $0.25 | $1.25 | 350원 | 1,750원 |
#### 시간/작업 기반 과금
| 서비스 | 단가 (USD) | 단위 | KRW 환산 |
|--------|----------:|------|----------:|
| Google STT | $0.009 | 15초당 | 12.6원/15초 (약 50원/분) |
| Google GCS | $0.005 | 1,000건당 | 7원/1,000건 |
| Google FCM | 무료 | - | - |
#### 환율 기준
- 기본 환율: **1,400원/USD**
- `ai_pricing_configs` 테이블에서 동적 관리
- 캐시 TTL: 1시간
### 2.3 본사 지출 월간 예상 (테넌트 1개 기준)
| 항목 | 최소 | 최대 | 비고 |
|------|-----:|-----:|------|
| 바로빌 홈택스 | 0원 | 0원 | 코드브릿지엑스 지원 |
| 세금계산서 원가 | ~5,000원 | ~10,000원 | 50~100건 기준 |
| AI 토큰 (Gemini) | ~100원 | ~5,000원 | 사용량 비례 |
| GCS/STT | ~50원 | ~2,000원 | 사용량 비례 |
---
## 3. 고객 안내용 과금정책
> 고객 요금 상세는 **[고객 요금 안내](customer-pricing.md)** 문서를 참조한다.
---
## 4. 내부 정산 정책
### 4.1 영업 수당 체계
> 수당률 및 정산 프로세스는 **[영업파트너 수당 체계](partner-commission.md)** 문서를 참조한다.
### 4.2 마진 구조
- **회사 마진**: 개발비의 약 **67~75%** (가입 유형에 따라 변동)
- 개인 가입: 개발비의 약 72~75% (수당 25~28% 차감 후)
- 단체 가입: 개발비의 약 67% (수당 33% 차감 후)
### 4.3 가격 책정 배경
- 내부 총 개발비 산정: **약 7,600만원**
- 구성: 개발비 2,000만원 + 장기 구독(약 7년) 및 금융 비용(4.6%)
- 중소기업 초기 투자 부담 분산 구조
---
## 5. 코드 참조 (개발자용)
### 5.1 바로빌 과금
| 파일 | 내용 |
|------|------|
| `mng/app/Models/Barobill/BarobillSubscription.php` | `DEFAULT_MONTHLY_FEES` 월정액 상수 |
| `mng/app/Models/Barobill/BarobillBillingRecord.php` | `USAGE_UNIT_PRICES` 건별 단가 상수 |
| `mng/app/Models/Barobill/BarobillPricingPolicy.php` | 과금 정책 모델 + `calculateBilling()` |
| `mng/app/Services/Barobill/BarobillBillingService.php` | 월정액/건별 과금 처리 서비스 |
| `mng/app/Services/Barobill/BarobillUsageService.php` | 사용량 집계 및 과금 계산 |
| `mng/database/seeders/BarobillPricingPolicySeeder.php` | 과금 정책 시더 (5개 정책) |
### 5.2 AI 가격/토큰
| 파일 | 내용 |
|------|------|
| `api/app/Models/Tenants/AiPricingConfig.php` | AI 단가 모델 + `getActivePricing()` |
| `api/app/Models/Tenants/AiTokenUsage.php` | 토큰 사용량 기록 모델 |
| `api/app/Services/AiReportService.php` | 토큰 비용 계산 로직 (`saveTokenUsage()`) |
| `api/database/migrations/2026_02_09_*_ai_pricing_configs.php` | AI 단가 테이블 + 시드 데이터 |
| `api/database/migrations/2026_02_07_*_ai_token_usages.php` | 토큰 사용량 테이블 |
### 5.3 정산 관련
| 파일 | 내용 |
|------|------|
| `mng` 또는 `api` 정산 컨트롤러/서비스 | 영업수수료, 구독료, 컨설팅비 정산 |
### 5.4 DB 테이블 참조
| 테이블 | 설명 |
|--------|------|
| `barobill_subscriptions` | 바로빌 월정액 구독 현황 |
| `barobill_billing_records` | 바로빌 월별 과금 내역 |
| `barobill_pricing_policies` | 바로빌 과금 정책 (무료 제공량, 추가 단가) |
| `ai_pricing_configs` | AI 제공자별 단가 설정 |
| `ai_token_usages` | AI 토큰 사용량 기록 |
| `ai_voice_recordings` | AI 음성 녹음 (STT 비용 발생) |
| `sales_commissions` | 영업수수료 정산 |
---
## 6. 관련 문서
- [고객 요금 안내](customer-pricing.md) - 서비스 가격표 (고객 공개용)
- [영업파트너 수당 체계](partner-commission.md) - 수당률 및 정산 (파트너용)
- [단가 정책 (품목)](pricing-policy.md) - 품목 단가/원가 계산
- [영업수수료정산](../features/settlement/sales-commissions.md)
- [구독료정산](../features/settlement/subscriptions.md)
- [컨설팅비용정산](../features/settlement/consulting-fees.md)
- [고객사정산](../features/settlement/customer-settlements.md)
- `sales/price/수당지급체계.md` - 수당 지급 체계 상세
- `sales/policy/SAM_영업정책문서.md` - 영업 정책 상세
- `sales/price/ref/토큰정책.md` - AI 토큰 고객 안내 가이드
---
> **공통 안내**: 본 문서에 명시된 모든 개발비 및 구독료는 **부가가치세(VAT) 별도** 금액이다.
---
**최종 업데이트**: 2026-02-21

Binary file not shown.

498
docs/rules/client-policy.md Normal file
View File

@@ -0,0 +1,498 @@
# 거래처 관리 정책 (Client Management Policy)
> **작성일**: 2025-12-08
> **상태**: 설계 확정
> **관련 요청**: `docs/front/[API-2025-12-04] client-api-analysis.md`
---
## 1. 개요
### 1.1 목적
- **거래처 마스터** 통합 관리 (매입처/매출처/매입매출)
- **고객그룹** 기반 단가 정책 연계
- 세금계산서 합의 및 **불량 채권** 관리
- 주문/발주 연동을 위한 거래처 기반 시스템
### 1.2 핵심 원칙
| 원칙 | 설명 |
|------|------|
| **거래처 유형 분류** | 매입, 매출, 매입매출로 구분 관리 |
| **코드 유일성** | tenant 내 client_code 중복 불가 |
| **그룹 기반 단가** | 고객그룹별 차등 판매가 적용 |
| **연관 데이터 보호** | 주문 존재 시 삭제 불가 |
---
## 2. 테이블 구조
### 2.1 ERD 개요
```
┌─────────────────┐ ┌─────────────────────┐
│ client_groups │──────<│ clients │
│ (고객 그룹) │ │ (거래처) │
└────────┬────────┘ └─────────┬───────────┘
│ │
│ price_rate │ client_id
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────────┐
│ prices │ │ orders │
│ (차등 단가) │ │ (주문) │
└─────────────────┘ └─────────────────────┘
```
### 2.2 clients 테이블 (거래처 마스터)
```sql
CREATE TABLE clients (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '테넌트 ID',
client_group_id BIGINT UNSIGNED NULL COMMENT '고객그룹 ID',
-- 기본 정보 --
client_code VARCHAR(50) NOT NULL COMMENT '거래처 코드',
name VARCHAR(100) NOT NULL COMMENT '거래처명',
client_type VARCHAR(20) NULL COMMENT '거래처 유형 (매입/매출/매입매출)',
is_active TINYINT(1) DEFAULT 1 COMMENT '활성여부(1=활성,0=비활성)',
-- 사업자 정보 --
business_no VARCHAR(20) NULL COMMENT '사업자등록번호',
business_type VARCHAR(50) NULL COMMENT '업태',
business_item VARCHAR(100) NULL COMMENT '업종',
-- 연락처 정보 --
contact_person VARCHAR(50) NULL COMMENT '담당자명',
phone VARCHAR(30) NULL COMMENT '전화번호',
mobile VARCHAR(20) NULL COMMENT '휴대폰',
fax VARCHAR(20) NULL COMMENT '팩스',
email VARCHAR(80) NULL COMMENT '이메일',
address VARCHAR(255) NULL COMMENT '주소',
-- 담당자 정보 --
manager_name VARCHAR(50) NULL COMMENT '당사 담당자명',
manager_tel VARCHAR(20) NULL COMMENT '당사 담당자 연락처',
system_manager VARCHAR(50) NULL COMMENT '시스템 담당자',
-- 계정 정보 --
account_id VARCHAR(50) NULL COMMENT '계정 ID',
account_password VARCHAR(255) NULL COMMENT '계정 비밀번호 (hidden)',
-- 발주/결제 설정 --
purchase_payment_day VARCHAR(20) NULL COMMENT '매입 결제일',
sales_payment_day VARCHAR(20) NULL COMMENT '매출 결제일',
-- 세금계산서 합의 --
tax_agreement BOOLEAN DEFAULT FALSE COMMENT '세금계산서 합의 여부',
tax_amount DECIMAL(15,2) NULL COMMENT '합의 금액',
tax_start_date DATE NULL COMMENT '합의 시작일',
tax_end_date DATE NULL COMMENT '합의 종료일',
-- 불량 채권 관리 --
bad_debt BOOLEAN DEFAULT FALSE COMMENT '불량 채권 여부',
bad_debt_amount DECIMAL(15,2) NULL COMMENT '불량 채권 금액',
bad_debt_receive_date DATE NULL COMMENT '채권 발생일',
bad_debt_end_date DATE NULL COMMENT '채권 종료일',
bad_debt_progress VARCHAR(20) NULL COMMENT '진행 상태',
-- 기타 --
memo TEXT NULL COMMENT '메모',
-- 감사 컬럼 --
created_by BIGINT UNSIGNED NULL COMMENT '생성자 ID',
updated_by BIGINT UNSIGNED NULL COMMENT '수정자 ID',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
-- 인덱스 --
INDEX idx_clients_tenant (tenant_id),
INDEX idx_clients_code (tenant_id, client_code),
INDEX idx_clients_group (tenant_id, client_group_id),
INDEX idx_clients_type (tenant_id, client_type),
INDEX idx_clients_active (tenant_id, is_active),
UNIQUE idx_clients_unique (tenant_id, client_code),
FOREIGN KEY (client_group_id) REFERENCES client_groups(id) ON DELETE SET NULL
) COMMENT='거래처 마스터';
```
### 2.3 client_groups 테이블 (고객 그룹)
```sql
CREATE TABLE client_groups (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '테넌트 ID',
-- 그룹 정보 --
group_code VARCHAR(50) NOT NULL COMMENT '그룹 코드',
group_name VARCHAR(100) NOT NULL COMMENT '그룹명',
price_rate DECIMAL(5,4) DEFAULT 1.0000 COMMENT '단가 비율 (1.0 = 100%)',
is_active BOOLEAN DEFAULT TRUE COMMENT '활성 상태',
-- 감사 컬럼 --
created_by BIGINT UNSIGNED NULL COMMENT '생성자 ID',
updated_by BIGINT UNSIGNED NULL COMMENT '수정자 ID',
deleted_by BIGINT UNSIGNED NULL COMMENT '삭제자 ID',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL COMMENT 'Soft Delete',
-- 인덱스 --
INDEX idx_groups_tenant (tenant_id),
INDEX idx_groups_code (tenant_id, group_code),
INDEX idx_groups_active (tenant_id, is_active),
UNIQUE idx_groups_unique (tenant_id, group_code, deleted_at)
) COMMENT='고객 그룹';
```
---
## 3. 거래처 유형 정책
### 3.1 거래처 유형 (client_type)
| 유형 | 설명 | 용도 |
|------|------|------|
| **매입** | 자재/상품 구매처 | 발주, 입고, 매입 관리 |
| **매출** | 제품/상품 판매처 | 주문, 출고, 매출 관리 |
| **매입매출** | 양방향 거래처 | 매입+매출 모두 가능 |
### 3.2 유형별 업무 흐름
```
┌───────────────────────────────────────────────────────────────┐
│ 매입 거래처 │
├───────────────────────────────────────────────────────────────┤
│ 발주요청 → 발주서 → 입고 → 수입검사 → 매입확정 → 대금지급 │
└───────────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────┐
│ 매출 거래처 │
├───────────────────────────────────────────────────────────────┤
│ 견적 → 수주 → 생산 → 출고 → 매출확정 → 대금수금 │
└───────────────────────────────────────────────────────────────┘
```
---
## 4. 고객그룹과 단가 연계
### 4.1 단가 적용 우선순위
```
┌─────────────────────────────────────────────────────────┐
│ 판매가 조회 로직 │
├─────────────────────────────────────────────────────────┤
│ 1순위: 고객그룹별 특별 단가 │
│ prices WHERE client_group_id = [거래처.그룹ID] │
│ │
│ 2순위: 기본 판매가 │
│ prices WHERE client_group_id IS NULL │
└─────────────────────────────────────────────────────────┘
```
### 4.2 단가 비율 적용 (price_rate)
```
최종 판매가 = 기본 판매가 × price_rate
예시:
- 기본 판매가: 10,000원
- VIP 그룹 price_rate: 0.90 (10% 할인)
- 최종 판매가: 10,000 × 0.90 = 9,000원
```
### 4.3 그룹 활용 예시
| 그룹 코드 | 그룹명 | price_rate | 설명 |
|----------|--------|------------|------|
| `DEFAULT` | 일반 고객 | 1.0000 | 정가 적용 |
| `VIP` | VIP 고객 | 0.9000 | 10% 할인 |
| `WHOLESALE` | 도매 거래처 | 0.8000 | 20% 할인 |
| `PARTNER` | 협력 업체 | 0.8500 | 15% 할인 |
---
## 5. 세금계산서 합의 관리
### 5.1 합의 정보 구조
| 필드 | 설명 | 용도 |
|------|------|------|
| `tax_agreement` | 합의 여부 | 세금계산서 발행 방식 결정 |
| `tax_amount` | 합의 금액 | 월정액 또는 고정 금액 |
| `tax_start_date` | 시작일 | 합의 유효 기간 시작 |
| `tax_end_date` | 종료일 | 합의 유효 기간 종료 |
### 5.2 합의 유형
```
┌─────────────────────────────────────────────────────────┐
│ tax_agreement = FALSE │
│ → 실제 거래 금액으로 세금계산서 발행 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ tax_agreement = TRUE │
│ → 합의 금액(tax_amount)으로 세금계산서 발행 │
│ → 유효 기간: tax_start_date ~ tax_end_date │
└─────────────────────────────────────────────────────────┘
```
---
## 6. 불량 채권 관리
### 6.1 불량 채권 정보 구조
| 필드 | 설명 |
|------|------|
| `bad_debt` | 불량 채권 여부 |
| `bad_debt_amount` | 불량 채권 금액 |
| `bad_debt_receive_date` | 채권 발생일 |
| `bad_debt_end_date` | 채권 종료(해결)일 |
| `bad_debt_progress` | 진행 상태 |
### 6.2 진행 상태 (bad_debt_progress)
```
┌──────────┐ 협의 ┌──────────┐ 법적조치 ┌──────────┐
│ 협의중 │ ──────────> │ 소송중 │ ─────────── │ 회수완료 │
└──────────┘ └────┬─────┘ └──────────┘
│ 회수 불가
┌──────────┐
│ 대손처리 │
└──────────┘
```
### 6.3 불량 채권 상태값
| 상태 | 설명 | 후속 조치 |
|------|------|----------|
| `협의중` | 채권 회수 협의 진행 | 정기 연락, 분할 상환 협의 |
| `소송중` | 법적 절차 진행 | 법무팀 연계, 소송 진행 |
| `회수완료` | 채권 전액 회수 | bad_debt_end_date 기록 |
| `대손처리` | 회수 불가 판정 | 회계 처리, 거래 중단 검토 |
---
## 7. 상태 관리
### 7.1 활성 상태 (is_active)
```
┌──────────────┐ 비활성화 ┌──────────────┐
│ true (활성) │ ───────────── │ false (비활성)│
│ 거래가능 │ <───────── │ 거래중단 │
└──────────────┘ 재활성화 └──────────────┘
```
### 7.2 상태별 제약
| 상태 | 주문 생성 | 발주 생성 | 조회 | 수정 |
|------|----------|----------|------|------|
| `true` (활성) | ✅ | ✅ | ✅ | ✅ |
| `false` (비활성) | ❌ | ❌ | ✅ | ✅ |
### 7.3 비활성화 고려 사항
- **불량 채권 거래처**: bad_debt = true 시 비활성화 검토
- **장기 미거래**: 12개월 이상 거래 없을 시 비활성화 검토
- **사업자 폐업**: 사업자등록 말소 확인 시 비활성화
---
## 8. API 엔드포인트
### 8.1 엔드포인트 목록
| Method | Endpoint | 설명 | 우선순위 |
|--------|----------|------|---------|
| GET | `/api/v1/clients` | 거래처 목록 조회 | 🔴 필수 |
| GET | `/api/v1/clients/{id}` | 거래처 상세 조회 | 🔴 필수 |
| POST | `/api/v1/clients` | 거래처 등록 | 🔴 필수 |
| PUT | `/api/v1/clients/{id}` | 거래처 수정 | 🔴 필수 |
| DELETE | `/api/v1/clients/{id}` | 거래처 삭제 | 🔴 필수 |
| POST | `/api/v1/clients/{id}/toggle` | 활성/비활성 토글 | 🟡 중요 |
| GET | `/api/v1/client-groups` | 고객그룹 목록 | 🟡 중요 |
| POST | `/api/v1/client-groups` | 고객그룹 등록 | 🟢 권장 |
### 8.2 목록 조회 API
```
GET /api/v1/clients?page=1&size=20&q=검색어&only_active=true
```
**Query Parameters:**
| 파라미터 | 타입 | 설명 |
|---------|------|------|
| `page` | int | 페이지 번호 (기본: 1) |
| `size` | int | 페이지당 개수 (기본: 20) |
| `q` | string | 검색어 (거래처명, 코드, 담당자) |
| `only_active` | bool | 활성 거래처만 조회 |
**Response:**
```json
{
"success": true,
"message": "message.fetched",
"data": {
"current_page": 1,
"data": [
{
"id": 1,
"client_code": "C001",
"name": "ABC 상사",
"client_type": "매입매출",
"business_no": "123-45-67890",
"contact_person": "홍길동",
"is_active": true,
"client_group": {
"id": 1,
"group_name": "VIP"
}
}
],
"total": 100
}
}
```
---
## 9. 비즈니스 규칙
### 9.1 검증 규칙
| 규칙 | 설명 |
|------|------|
| **R1** | client_code는 tenant 내 유일해야 함 |
| **R2** | client_code, name은 필수 값 |
| **R3** | client_type은 '매입', '매출', '매입매출' 중 하나 |
| **R4** | 주문이 존재하는 거래처는 삭제 불가 |
| **R5** | email 형식 검증 |
| **R6** | bad_debt_progress는 지정된 값만 허용 |
| **R7** | tax_start_date ≤ tax_end_date |
### 9.2 코드 중복 처리
```
신규 등록 시:
└─ tenant_id + client_code 조합 중복 검사
└─ 중복 시 error.duplicate_code 반환
수정 시:
└─ client_code 변경 시에만 중복 검사 수행
└─ 자기 자신 제외하고 검사
```
### 9.3 삭제 정책
| 테이블 | 삭제 방식 | 설명 |
|--------|----------|------|
| `clients` | **Hard Delete** | 연관 주문이 없는 경우만 삭제 가능 |
| `client_groups` | **Soft Delete** | `deleted_at` 컬럼 사용 |
- **연관 데이터 보호**: orders 존재 시 `error.has_orders` 반환
- **주문 있는 거래처**: 비활성화(`is_active = false`)로 처리 권장
### 9.4 비밀번호 보호
```php
protected $hidden = ['account_password'];
```
- `account_password`는 API 응답에서 자동 제외
- 저장 시 평문 저장 (필요시 암호화 적용 검토)
---
## 10. 필드 분류
### 10.1 기본 정보 (4개)
| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| `client_code` | string(50) | ✅ | 거래처 코드 |
| `name` | string(100) | ✅ | 거래처명 |
| `client_type` | enum | ❌ | 매입/매출/매입매출 |
| `is_active` | boolean | ❌ | 활성 상태 (기본: true) |
### 10.2 사업자 정보 (3개)
| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| `business_no` | string(20) | ❌ | 사업자등록번호 |
| `business_type` | string(50) | ❌ | 업태 |
| `business_item` | string(100) | ❌ | 업종 |
### 10.3 연락처 정보 (6개)
| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| `contact_person` | string(50) | ❌ | 담당자명 |
| `phone` | string(30) | ❌ | 전화번호 |
| `mobile` | string(20) | ❌ | 휴대폰 |
| `fax` | string(20) | ❌ | 팩스 |
| `email` | string(80) | ❌ | 이메일 |
| `address` | string(255) | ❌ | 주소 |
### 10.4 담당자 정보 (3개)
| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| `manager_name` | string(50) | ❌ | 당사 담당자명 |
| `manager_tel` | string(20) | ❌ | 당사 담당자 연락처 |
| `system_manager` | string(50) | ❌ | 시스템 담당자 |
### 10.5 계정/발주 정보 (4개)
| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| `account_id` | string(50) | ❌ | 계정 ID |
| `account_password` | string(255) | ❌ | 계정 비밀번호 (hidden) |
| `purchase_payment_day` | string(20) | ❌ | 매입 결제일 |
| `sales_payment_day` | string(20) | ❌ | 매출 결제일 |
### 10.6 세금계산서 합의 (4개)
| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| `tax_agreement` | boolean | ❌ | 합의 여부 |
| `tax_amount` | decimal(15,2) | ❌ | 합의 금액 |
| `tax_start_date` | date | ❌ | 합의 시작일 |
| `tax_end_date` | date | ❌ | 합의 종료일 |
### 10.7 불량 채권 (5개)
| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| `bad_debt` | boolean | ❌ | 불량 채권 여부 |
| `bad_debt_amount` | decimal(15,2) | ❌ | 불량 채권 금액 |
| `bad_debt_receive_date` | date | ❌ | 채권 발생일 |
| `bad_debt_end_date` | date | ❌ | 채권 종료일 |
| `bad_debt_progress` | enum | ❌ | 진행 상태 |
### 10.8 기타 (2개)
| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| `client_group_id` | bigint | ❌ | 고객그룹 ID |
| `memo` | text | ❌ | 메모 |
---
## 11. 관련 문서
- [단가 정책](./pricing-policy.md) - 고객그룹별 단가 적용
- [API 개발 규칙](../standards/api-rules.md)
- [프론트엔드 요청서](../front/[API-2025-12-04]%20client-api-analysis.md)
---
**최종 업데이트**: 2025-12-08

View File

@@ -0,0 +1,116 @@
# SAM 서비스 요금 안내
> **작성일**: 2026-02-21
> **상태**: 설계 확정
---
## 1. 개요
### 1.1 목적
SAM 서비스 도입 시 고객에게 안내하는 요금 체계를 정리한다.
### 1.2 용어 정의
| 용어 | 설명 |
|------|------|
| **개발비** | 서비스 도입 시 1회 납부하는 초기 비용 |
| **구독료** | 서비스 유지를 위한 월 정기 비용 |
| **토큰** | AI가 언어를 처리하는 최소 단위 (한글 ~1.5자 = 1토큰) |
---
## 2. 기본 서비스 요금
### 2.1 제조업 기본 패키지
- **포함**: 품목관리 → 견적 → 수주 → 생산 → 출하 (ERP 인사/회계 무료 포함)
- **개발비**: 2,000만원 (VAT 별도)
- **구독료**: 50만원/월 (VAT 별도)
### 2.2 개별 모듈
| 모듈명 | 개발비 (VAT 별도) | 구독료/월 (VAT 별도) |
|--------|------------------:|-----------------:|
| QR코드 관리 | 1,020만원 | 5만원 |
| 사진/출하 관리 | 1,920만원 | 10만원 |
| 검사/토큰 적용 | 1,020만원 | 5만원 |
| 이카운트 연동 | 1,920만원 | 10만원 |
### 2.3 통합 패키지
| 패키지명 | 개발비 (VAT 별도) | 구독료/월 (VAT 별도) |
|---------|------------------:|-----------------:|
| 공사관리 패키지 | 4,000만원 | 20만원 |
| 공정/정부지원사업 | 8,000만원 | 40만원 |
---
## 3. 추가 옵션 요금
| 옵션명 | 개발비 추가 (VAT 별도) | 구독료 추가/월 (VAT 별도) |
|--------|---------------------:|----------------------:|
| 생산공정 1개 추가 | 500만원 | 10만원 |
| 품질관리 (인정검사) | 2,000만원 | 50만원 |
| 사진 등록 | - | 10만원 |
| 챗봇/녹음/업무일지 | - | 각 20만원 |
| 연구소 연구노트 | - | 5만원 |
| 장비점검, 사무소 정비 | - | 5만원 |
> **참고**: 품질관리(인정검사)에는 '장비점검, 사무소 정비' 기능이 기본 포함된다.
---
## 4. 사용량 기반 추가 과금
기본 제공 한도 초과 시 실비 과금한다.
| 항목 | 기본 제공 | 추가 과금 기준 |
|------|----------|--------------|
| 파일 저장 공간 | 100GB | 100GB당 **10만원/월** |
| AI 토큰 | 월 100만 토큰 | 1,000토큰 단위 실비 과금 |
### AI 토큰 사용량 체감 (100만 토큰 기준)
| 활용 시나리오 | 예상 처리량 |
|-------------|-----------|
| 음성 회의 요약 | 약 520분 (8.6시간) |
| 문서 자료 정리 (A4) | 약 300~400매 |
| 이메일/노트 분류 | 약 1,500~2,000건 |
- 미사용 잔여 토큰은 이월되지 않는다 (매월 1일 갱신)
- 기본 제공량 80%, 100% 소진 시 자동 알림 발송
---
## 5. 바로빌 부가 서비스 요금
고객이 선택적으로 이용하는 바로빌 연동 서비스이다.
| 서비스 | 과금 방식 | 기본 제공 | 추가 과금 | 부담 주체 |
|--------|---------|---------|---------|----------|
| 계좌조회 | 월정액 10,000원 | 1계좌 | 추가 1계좌당 10,000원 | 고객 |
| 카드내역 | 월정액 10,000원 | 5장 | 추가 1장당 5,000원 | 고객 |
| 홈택스 매입/매출 | 월 33,000원 × 2 | - | - | 본사 (무료) |
| 세금계산서 발행 | 건별 | 100건 | 추가 50건당 5,000원 | 고객 |
> **과금 계산 예시**:
> - 법인카드 8장 등록 → (8-5) × 5,000 = 15,000원 추가
> - 세금계산서 151건 → ceil((151-100)/50) × 5,000 = 10,000원 추가
---
## 6. 관련 문서
- [내부 과금정책](billing-policy.md) - 본사 지출 원가 및 코드 참조 (내부용)
- [영업파트너 수당 체계](partner-commission.md) - 수당률 및 정산 프로세스 (파트너용)
- [단가 정책 (품목)](pricing-policy.md) - 품목 단가/원가 계산
---
> **공통 안내**: 본 문서에 명시된 모든 개발비 및 구독료는 **부가가치세(VAT) 별도** 금액이다.
---
**최종 업데이트**: 2026-02-21

Binary file not shown.

View File

@@ -0,0 +1,258 @@
# Department Tree API (부서트리 조회 API) 규칙
## 개요
부서트리 API는 테넌트 내 조직도를 계층 구조로 조회하는 API입니다.
`departments` 테이블의 `parent_id`를 통한 자기참조 관계로 무한 depth 계층 구조를 지원합니다.
## 핵심 모델
### Department
- **위치**: `App\Models\Tenants\Department`
- **역할**: 부서/조직 정보
- **특징**:
- `parent_id` 자기참조로 계층 구조
- `HasRoles` 트레이트 (부서도 권한/역할 보유 가능)
- `ModelTrait` 적용 (is_active, 날짜 처리)
## 엔드포인트
### 부서 트리 전용
| Method | Path | 설명 |
|--------|------|------|
| GET | `/v1/departments/tree` | 부서 트리 조회 |
### 기본 CRUD (참고)
| Method | Path | 설명 |
|--------|------|------|
| GET | `/v1/departments` | 부서 목록 조회 |
| GET | `/v1/departments/{id}` | 부서 상세 조회 |
| POST | `/v1/departments` | 부서 생성 |
| PATCH | `/v1/departments/{id}` | 부서 수정 |
| DELETE | `/v1/departments/{id}` | 부서 삭제 |
### 부서-사용자 관리
| Method | Path | 설명 |
|--------|------|------|
| GET | `/v1/departments/{id}/users` | 부서 사용자 목록 |
| POST | `/v1/departments/{id}/users` | 사용자 배정 |
| DELETE | `/v1/departments/{id}/users/{user}` | 사용자 제거 |
| PATCH | `/v1/departments/{id}/users/{user}/primary` | 주부서 설정 |
## 데이터 구조
### 기본 필드
| 필드 | 타입 | 설명 |
|------|------|------|
| `id` | int | PK |
| `tenant_id` | int | 테넌트 ID |
| `parent_id` | int | 상위 부서 ID (nullable, 최상위는 null) |
| `code` | string | 부서 코드 (unique) |
| `name` | string | 부서명 |
| `description` | string | 부서 설명 |
| `is_active` | bool | 활성화 상태 |
| `sort_order` | int | 정렬 순서 |
| `created_by` | int | 생성자 |
| `updated_by` | int | 수정자 |
| `deleted_by` | int | 삭제자 |
### 트리 응답 구조
```json
[
{
"id": 1,
"tenant_id": 1,
"parent_id": null,
"code": "DEPT001",
"name": "경영지원본부",
"is_active": true,
"sort_order": 1,
"children": [
{
"id": 2,
"tenant_id": 1,
"parent_id": 1,
"code": "DEPT002",
"name": "인사팀",
"is_active": true,
"sort_order": 1,
"children": [],
"users": []
},
{
"id": 3,
"tenant_id": 1,
"parent_id": 1,
"code": "DEPT003",
"name": "재무팀",
"is_active": true,
"sort_order": 2,
"children": [],
"users": []
}
],
"users": [
{ "id": 1, "name": "홍길동", "email": "hong@example.com" }
]
}
]
```
## 트리 조회 로직
### tree() 메서드 구현
```php
public function tree(array $params = []): array
{
// 1. 파라미터 검증
$withUsers = filter_var($params['with_users'] ?? false, FILTER_VALIDATE_BOOLEAN);
// 2. 최상위 부서 조회 (parent_id가 null)
$query = Department::query()
->whereNull('parent_id')
->orderBy('sort_order')
->orderBy('name');
// 3. 재귀적으로 자식 부서 로드
$query->with(['children' => function ($q) use ($withUsers) {
$q->orderBy('sort_order')->orderBy('name');
$this->loadChildrenRecursive($q, $withUsers);
}]);
// 4. 사용자 포함 옵션
if ($withUsers) {
$query->with(['users:id,name,email']);
}
return $query->get()->toArray();
}
// 재귀 로딩 헬퍼
private function loadChildrenRecursive($query, bool $withUsers): void
{
$query->with(['children' => function ($q) use ($withUsers) {
$q->orderBy('sort_order')->orderBy('name');
$this->loadChildrenRecursive($q, $withUsers);
}]);
if ($withUsers) {
$query->with(['users:id,name,email']);
}
}
```
### 정렬 규칙
1. `sort_order` 오름차순
2. `name` 오름차순 (동일 sort_order일 때)
## 요청 파라미터
### GET /v1/departments/tree
| 파라미터 | 타입 | 기본값 | 설명 |
|----------|------|--------|------|
| `with_users` | bool | false | 부서별 사용자 목록 포함 |
### 예시
```bash
# 기본 트리 조회
GET /v1/departments/tree
# 사용자 포함 트리 조회
GET /v1/departments/tree?with_users=1
```
## 관계 (Relationships)
```php
public function parent(): BelongsTo // 상위 부서
public function children() // 하위 부서들 (HasMany)
public function users() // 소속 사용자들 (BelongsToMany)
public function departmentUsers() // 부서-사용자 pivot (HasMany)
public function permissionOverrides() // 권한 오버라이드 (MorphMany)
```
## 부서-사용자 관계 (Pivot)
### department_user 테이블
| 필드 | 타입 | 설명 |
|------|------|------|
| `department_id` | int | 부서 ID |
| `user_id` | int | 사용자 ID |
| `tenant_id` | int | 테넌트 ID |
| `is_primary` | bool | 주부서 여부 |
| `joined_at` | timestamp | 배정일 |
| `left_at` | timestamp | 해제일 |
| `deleted_at` | timestamp | Soft Delete |
### 주부서 규칙
- 한 사용자는 여러 부서에 소속 가능
- 주부서(`is_primary`)는 사용자당 1개만 가능
- 주부서 설정 시 기존 주부서는 자동 해제
## 권한 관리
### 부서 권한 시스템
부서는 Spatie Permission과 연동되어 권한을 가질 수 있습니다.
- **ALLOW**: `model_has_permissions` 테이블
- **DENY**: `permission_overrides` 테이블 (effect: -1)
### 관련 엔드포인트
| Method | Path | 설명 |
|--------|------|------|
| GET | `/v1/departments/{id}/permissions` | 부서 권한 목록 |
| POST | `/v1/departments/{id}/permissions` | 권한 부여/차단 |
| DELETE | `/v1/departments/{id}/permissions/{permission}` | 권한 제거 |
## 주의사항
1. **무한 재귀 방지**: Eloquent eager loading으로 처리, 별도 depth 제한 없음
2. **성능 고려**: 대규모 조직도의 경우 `with_users` 사용 시 응답 시간 증가
3. **정렬 일관성**: 모든 레벨에서 동일한 정렬 규칙 적용
4. **멀티테넌트**: tenant_id 기반 자동 스코핑
5. **주부서 제약**: 사용자당 주부서 1개만 허용
6. **Soft Delete**: department_user pivot도 Soft Delete 적용
## 트리 구축 예시
### 조직도 예시
```
경영지원본부 (parent_id: null)
├── 인사팀 (parent_id: 1)
│ ├── 채용파트 (parent_id: 2)
│ └── 교육파트 (parent_id: 2)
├── 재무팀 (parent_id: 1)
└── 총무팀 (parent_id: 1)
개발본부 (parent_id: null)
├── 프론트엔드팀 (parent_id: 4)
├── 백엔드팀 (parent_id: 4)
└── QA팀 (parent_id: 4)
```
### SQL 예시 (데이터 삽입)
```sql
-- 최상위 부서
INSERT INTO departments (tenant_id, parent_id, code, name, sort_order)
VALUES (1, NULL, 'HQ', '경영지원본부', 1);
-- 하위 부서
INSERT INTO departments (tenant_id, parent_id, code, name, sort_order)
VALUES (1, 1, 'HR', '인사팀', 1);
```

181
docs/rules/employee-api.md Normal file
View File

@@ -0,0 +1,181 @@
# Employee API (사원관리 API) 규칙
## 개요
사원관리 API는 테넌트 내 사원 정보를 관리하는 API입니다.
`users` 테이블과 `tenant_user_profiles` 테이블을 조합하여 사원 정보를 구성합니다.
## 핵심 모델
### TenantUserProfile
- **위치**: `App\Models\Tenants\TenantUserProfile`
- **역할**: 테넌트별 사용자 프로필 (사원 정보)
- **특징**: `json_extra` 필드에 사원 상세 정보 저장
### User
- **위치**: `App\Models\Members\User`
- **역할**: 기본 사용자 계정 (이름, 이메일, 비밀번호)
## 엔드포인트
| Method | Path | 설명 |
|--------|------|------|
| GET | `/v1/employees` | 사원 목록 조회 |
| GET | `/v1/employees/{id}` | 사원 상세 조회 |
| POST | `/v1/employees` | 사원 등록 |
| PATCH | `/v1/employees/{id}` | 사원 수정 |
| DELETE | `/v1/employees/{id}` | 사원 삭제 (상태 변경) |
| DELETE | `/v1/employees/bulk` | 사원 일괄 삭제 |
| GET | `/v1/employees/stats` | 사원 통계 |
| POST | `/v1/employees/{id}/account` | 시스템 계정 생성 |
## 데이터 구조
### 기본 필드 (TenantUserProfile)
| 필드 | 타입 | 설명 |
|------|------|------|
| `tenant_id` | int | 테넌트 ID |
| `user_id` | int | 사용자 ID (FK → users) |
| `department_id` | int | 부서 ID (nullable) |
| `position_key` | string | 직위 코드 |
| `job_title_key` | string | 직책 코드 |
| `work_location_key` | string | 근무지 코드 |
| `employment_type_key` | string | 고용 형태 코드 |
| `employee_status` | string | 고용 상태 (active/leave/resigned) |
| `manager_user_id` | int | 상위 관리자 ID (nullable) |
| `profile_photo_path` | string | 프로필 사진 경로 |
| `display_name` | string | 표시명 |
| `json_extra` | json | 확장 사원 정보 |
### json_extra 필드 구조
```json
{
"employee_code": "EMP001",
"resident_number": "encrypted_value",
"gender": "male|female",
"address": "서울시 강남구...",
"salary": 5000000,
"hire_date": "2024-01-15",
"rank": "대리",
"bank_account": {
"bank": "국민은행",
"account": "123-456-789",
"holder": "홍길동"
},
"work_type": "regular|contract|part_time",
"contract_info": {
"start_date": "2024-01-15",
"end_date": "2025-01-14"
},
"emergency_contact": {
"name": "김부모",
"phone": "010-1234-5678",
"relation": "부모"
},
"education": [],
"certifications": []
}
```
### 허용된 json_extra 키
```php
$allowedKeys = [
'employee_code', // 사원번호
'resident_number', // 주민등록번호 (암호화 필수)
'gender', // 성별
'address', // 주소
'salary', // 급여
'hire_date', // 입사일
'rank', // 직급
'bank_account', // 급여계좌
'work_type', // 근무유형
'contract_info', // 계약 정보
'emergency_contact', // 비상연락처
'education', // 학력
'certifications', // 자격증
];
```
## 비즈니스 규칙
### 사원 등록 (store)
1. `users` 테이블에 사용자 생성
2. `user_tenants` pivot에 관계 추가 (is_default: true)
3. `tenant_user_profiles` 생성
4. `json_extra`에 사원 정보 설정
```php
// 자동 생성되는 user_id 형식
$userId = strtolower(explode('@', $email)[0] . '_' . Str::random(4));
```
### 사원 삭제 (destroy)
- **Hard Delete 하지 않음**
- `employee_status``resigned`로 변경
- 사용자 계정은 유지됨
### 사원 상태 (employee_status)
| 상태 | 설명 |
|------|------|
| `active` | 재직 중 |
| `leave` | 휴직 |
| `resigned` | 퇴사 |
### 시스템 계정 (has_account)
- 시스템 계정 = `users.password`가 NULL이 아닌 경우
- `POST /employees/{id}/account`로 비밀번호 설정 시 계정 생성
- 첫 로그인 시 비밀번호 변경 필요 (`must_change_password: true`)
## 검색/필터 파라미터
| 파라미터 | 타입 | 설명 |
|----------|------|------|
| `q` | string | 이름/이메일/사원코드 검색 |
| `status` | string | 고용 상태 필터 |
| `department_id` | int | 부서 필터 |
| `has_account` | bool | 시스템 계정 보유 여부 |
| `sort_by` | string | 정렬 기준 (기본: created_at) |
| `sort_dir` | string | 정렬 방향 (asc/desc) |
| `per_page` | int | 페이지당 항목 수 (기본: 20) |
## 관계 (Relationships)
```php
// TenantUserProfile
public function user(): BelongsTo // 기본 사용자 정보
public function department(): BelongsTo // 소속 부서
public function manager(): BelongsTo // 상위 관리자
```
## 스코프 (Scopes)
```php
$query->active(); // employee_status = 'active'
$query->onLeave(); // employee_status = 'leave'
$query->resigned(); // employee_status = 'resigned'
```
## Accessor
```php
$profile->employee_code; // json_extra['employee_code']
$profile->hire_date; // json_extra['hire_date']
$profile->address; // json_extra['address']
$profile->emergency_contact; // json_extra['emergency_contact']
```
## 주의사항
1. **주민등록번호**: 반드시 암호화하여 저장
2. **멀티테넌트**: tenant_id 자동 스코핑
3. **Audit**: created_by/updated_by 자동 기록
4. **삭제**: Hard Delete 금지, employee_status 변경으로 처리

293
docs/rules/item-policy.md Normal file
View File

@@ -0,0 +1,293 @@
# 품목(Items) 비즈니스 정책
> 품목 관리 시스템의 핵심 비즈니스 규칙 정의
>
> **최종 업데이트**: 2025-12-09
---
## 1. 품목 유형 체계 (item_type)
### 1.1 품목 유형 코드 정의
| 코드 | 한글명 | 영문명 | source_table | 설명 |
|------|--------|--------|--------------|------|
| `FG` | 완제품 | Finished Goods | products | 판매 가능한 최종 제품 |
| `PT` | 부품 | Parts | products | 제품 구성에 사용되는 부품 |
| `SM` | 부자재 | Sub-Materials | materials | 생산에 사용되는 보조 자재 |
| `RM` | 원자재 | Raw Materials | materials | 생산의 주요 원료 |
| `CS` | 소모품 | Consumables | materials | 일회성 소모 자재 |
### 1.2 저장 위치
```
common_codes 테이블
├─ code_group = 'item_type'
├─ code = 'FG' | 'PT' | 'SM' | 'RM' | 'CS'
└─ attributes.source_table = 'products' | 'materials'
```
### 1.3 source_table 매핑 규칙
```
item_type → source_table 자동 매핑:
FG (완제품) ─┐
PT (부품) ─┴─→ products 테이블
SM (부자재) ─┐
RM (원자재) ─┼─→ materials 테이블
CS (소모품) ─┘
```
### 1.4 테넌트별 확장
- 품목 유형은 테넌트별로 커스터마이징 가능
- `common_codes.attributes` JSON 필드 활용 (스키마 변경 없음)
- 새 품목 유형 추가 시 source_table 매핑 필수
---
## 2. 용어 정의 및 구분
### 2.1 핵심 용어
| 용어 | 필드명 | 값 | 용도 |
|------|--------|-----|------|
| **품목 유형** | `item_type` | FG, PT, SM, RM, CS | API 파라미터, UI 필터링, 비즈니스 분류 |
| **저장 테이블** | `source_table` | products, materials | 내부 DB 분기, 서비스 로직 |
| **참조 타입** | `ref_type` | PRODUCT, MATERIAL | 폴리모픽 관계 (BOM, Prices 등) |
### 2.2 사용 규칙
- **API 레벨**: `item_type` 파라미터 사용
- **서비스 레벨**: `source_table`로 테이블 분기
- **폴리모픽 관계**: `ref_type`으로 참조 (기존 호환성 유지)
### 2.3 API 흐름 예시
```
1. 클라이언트 요청: GET /api/v1/items?item_type=FG
2. 서버 처리: item_type='FG' → common_codes 조회
3. 테이블 분기: source_table='products' 확인
4. 데이터 조회: products 테이블에서 조회
5. 응답 반환: item_type='FG' 포함하여 응답
```
---
## 3. 필드 키 예약어 정책
### 3.1 products 테이블 예약어
```php
// 사용 불가 field_key 목록
'code', 'name', 'unit', 'category_id', 'product_type', 'description',
'is_sellable', 'is_purchasable', 'is_producible', 'is_variable_size', 'is_active',
'safety_stock', 'lead_time', 'product_category', 'part_type',
'bending_diagram', 'bending_details',
'specification_file', 'specification_file_name',
'certification_file', 'certification_file_name',
'certification_number', 'certification_start_date', 'certification_end_date',
'attributes', 'attributes_archive'
```
### 3.2 materials 테이블 예약어
```php
// 사용 불가 field_key 목록
'name', 'item_name', 'specification', 'material_code', 'material_type',
'unit', 'category_id', 'is_inspection', 'is_active',
'search_tag', 'remarks', 'attributes', 'options'
```
### 3.3 공통 시스템 컬럼 (모든 테이블)
```php
// 절대 사용 불가
'id', 'tenant_id', 'created_by', 'updated_by', 'deleted_by',
'created_at', 'updated_at', 'deleted_at'
```
### 3.4 검증 규칙
1. **field_key 저장**: 입력값 그대로 저장 (id 접두사 없음)
2. **예약어 검증 흐름**:
```
field_key 입력
source_table 확인 (products / materials)
해당 테이블 예약어 체크
기존 필드 중복 체크
저장
```
3. **에러 메시지**:
- 예약어 충돌: `"{field_key}"은(는) 시스템 예약어로 사용할 수 없습니다.`
- 중복: `field_key은(는) 이미 사용 중입니다.`
---
## 4. API 파라미터 규칙
### 4.1 목록 조회 (GET /api/v1/items)
| 파라미터 | 필수 | 값 | 설명 |
|---------|:----:|-----|------|
| `type` | ❌ | FG,PT,SM,RM,CS | 품목 유형 필터 (쉼표 구분) |
| `search` | ❌ | string | 코드/명칭 검색 |
| `page` | ❌ | int | 페이지 번호 |
| `size` | ❌ | int | 페이지 크기 |
### 4.2 단건 조회 (GET /api/v1/items/{id})
| 파라미터 | 필수 | 값 | 설명 |
|---------|:----:|-----|------|
| `item_type` | ✅ | FG/PT/SM/RM/CS | 품목 유형 (테이블 분기용) |
| `include_price` | ❌ | boolean | 단가 정보 포함 |
### 4.3 생성 (POST /api/v1/items)
| 파라미터 | 필수 | 값 | 설명 |
|---------|:----:|-----|------|
| `product_type` | ✅ | FG/PT/SM/RM/CS | 품목 유형 |
| `code` | ✅ | string | 품목 코드 |
| `name` | ✅ | string | 품목명 |
| `unit` | ✅ | string | 단위 |
### 4.4 수정 (PUT /api/v1/items/{id})
| 파라미터 | 필수 | 값 | 설명 |
|---------|:----:|-----|------|
| `item_type` | ✅ | FG/PT/SM/RM/CS | 품목 유형 (테이블 분기용) |
### 4.5 삭제 (DELETE /api/v1/items/{id})
| 파라미터 | 필수 | 값 | 설명 |
|---------|:----:|-----|------|
| `item_type` | ✅ | FG/PT/SM/RM/CS | 품목 유형 (테이블 분기용) |
### 4.6 일괄 삭제 (DELETE /api/v1/items/batch)
| 파라미터 | 필수 | 값 | 설명 |
|---------|:----:|-----|------|
| `item_type` | ✅ | FG/PT/SM/RM/CS | 품목 유형 |
| `ids` | ✅ | array | 삭제할 ID 목록 |
---
## 5. 데이터 저장 규칙
### 5.1 저장 방식 구분
| 저장 방식 | 대상 | 설명 |
|----------|------|------|
| **column** | 고정 컬럼 | DB 테이블 컬럼에 직접 저장 |
| **json** | 동적 속성 | `attributes` JSON 필드에 저장 |
### 5.2 고정 컬럼 (column)
- DB 스키마에 정의된 컬럼
- 필드 매핑: `item_fields.source_column` 사용
- 예: code, name, unit, category_id 등
### 5.3 동적 속성 (json)
- `attributes` JSON 필드에 저장
- 필드 매핑: `item_fields.json_path` 사용
- 예: `attributes.custom_size`, `attributes.color` 등
### 5.4 API 응답 규칙
- **플랫 구조**: attributes 내부 값을 최상위로 전개
- **매핑 정보 미노출**: source_table, source_column 등 내부 필드 숨김
```json
// 응답 예시
{
"id": 1,
"item_type": "FG",
"code": "P-001",
"name": "스크린 제품",
"color": "white", // attributes.color → 플랫 전개
"size": "100x200" // attributes.size → 플랫 전개
}
```
---
## 6. 삭제 규칙
### 6.1 BOM 사용 체크
- 품목이 다른 BOM의 구성품으로 사용 중이면 삭제 불가
- 에러 메시지: `다른 BOM의 구성품으로 사용 중입니다. (N건)`
### 6.2 Soft Delete
- 모든 품목은 soft delete 방식 사용
- `deleted_at` 타임스탬프로 삭제 표시
- 복구 가능
---
## 7. 관련 파일
### 7.1 API 파일
| 파일 | 경로 | 역할 |
|------|------|------|
| ItemsController | `api/app/Http/Controllers/Api/V1/ItemsController.php` | API 컨트롤러 |
| ItemsService | `api/app/Services/ItemsService.php` | 비즈니스 로직 |
| ItemTypeHelper | `api/app/Helpers/ItemTypeHelper.php` | item_type 헬퍼 |
| SystemFields | `api/app/Constants/SystemFields.php` | 예약어 상수 |
### 7.2 Seeder 파일
| 파일 | 경로 | 역할 |
|------|------|------|
| ItemTypeSeeder | `api/database/seeders/ItemTypeSeeder.php` | item_type 코드 시딩 |
### 7.3 Request 파일
| 파일 | 경로 |
|------|------|
| ItemStoreRequest | `api/app/Http/Requests/Item/ItemStoreRequest.php` |
| ItemUpdateRequest | `api/app/Http/Requests/Item/ItemUpdateRequest.php` |
| ItemBatchDeleteRequest | `api/app/Http/Requests/Item/ItemBatchDeleteRequest.php` |
---
## 8. 구현 현황
### 8.1 완료 항목
- ✅ item_type 코드 시딩 (ItemTypeSeeder)
- ✅ common_codes에 attributes.source_table 매핑
- ✅ field_key 예약어 검증 (SystemFields)
- ✅ ItemMaster CRUD API (Pages, Sections, Fields)
- ✅ 독립 엔티티 아키텍처 (entity_relationships)
### 8.2 개발 필요 항목
| API | Product | Material | 작업 내용 |
|-----|:-------:|:--------:|----------|
| `PUT /items/{id}` | ✅ | ❌ | Material 수정 지원 추가 |
| `DELETE /items/{id}` | ✅ | ❌ | Material 삭제 지원 추가 |
| `DELETE /items/batch` | ✅ | ❌ | Material 일괄삭제 지원 |
| `GET /items/code/{code}` | ✅ | ❌ | Material 코드 조회 지원 |
---
## 변경 이력
| 날짜 | 내용 |
|------|------|
| 2025-12-09 | 문서 생성 - 4개 문서 통합 (items-api-unified-plan, field-integration, field-key-validation, INDEX) |

View File

@@ -0,0 +1,108 @@
# 채번규칙 (Numbering Rules)
> **상태**: 내부 서비스 (직접 API 없음)
> **최종 갱신**: 2026-02-27
---
## 1. 개요
문서 번호(견적번호, 수주번호 등)를 규칙 기반으로 자동 생성하는 내부 서비스. 테넌트별로 채번 규칙을 설정하면, 해당 규칙에 따라 일련번호가 자동 생성된다. 규칙이 없는 경우 레거시 포맷으로 폴백.
**핵심 기능:**
- 유연한 패턴 기반 번호 생성 (6가지 세그먼트 유형)
- Atomic UPSERT로 동시성 안전 시퀀스 관리
- 기간별 자동 리셋 (일/월/년/무제한)
- 미리보기 기능 (DB 업데이트 없음)
---
## 2. 모델
| 모델 | 테이블 | 설명 |
|------|--------|------|
| `NumberingRule` | `numbering_rules` | 채번 규칙 정의 (document_type, pattern, reset_period) |
| `NumberingSequence` | `numbering_sequences` | 일련번호 카운터 (tenant + type + scope + period) |
**지원 문서 유형:** quote, order, sale, work_order, material_receipt
**리셋 주기:** daily, monthly, yearly, never
---
## 3. 패턴 구조
패턴은 JSON 배열로 세그먼트를 정의한다.
| 세그먼트 | 설명 | 예시 |
|---------|------|------|
| `static` | 고정 문자열 | `{ "type": "static", "value": "QT" }` |
| `date` | 날짜 포맷 | `{ "type": "date", "format": "ymd" }``260227` |
| `sequence` | 일련번호 | `{ "type": "sequence", "padding": 4 }``0001` |
| `separator` | 구분자 | `{ "type": "separator", "value": "-" }` |
| `param` | 외부 파라미터 | `{ "type": "param", "key": "product_category" }` |
| `mapping` | 값 매핑 | `{ "type": "mapping", "key": "category", "map": {"A": "PR"} }` |
**패턴 예시:**
```json
[
{ "type": "static", "value": "KD" },
{ "type": "separator", "value": "-" },
{ "type": "mapping", "key": "category", "map": { "A": "PR" }, "default": "XX" },
{ "type": "separator", "value": "-" },
{ "type": "date", "format": "ymd" },
{ "type": "separator", "value": "-" },
{ "type": "sequence", "padding": 2 }
]
```
`KD-PR-260227-01`
---
## 4. 서비스
| 서비스 | 메서드 | 설명 |
|--------|--------|------|
| `NumberingService` | `generate($documentType, $params)` | 번호 생성 (규칙 없으면 null → 레거시 폴백) |
| | `preview($documentType, $params)` | 미리보기 (시퀀스 증가 없음) |
| `QuoteNumberService` | `generate()` | 견적번호 생성 (NumberingService → 레거시 폴백) |
| | `validate()` | 형식 검증 |
| | `isUnique()` | 중복 체크 |
**레거시 포맷:** `QT{YYYYMMDD}{NNNN}` (예: `QT202602270001`)
---
## 5. 동시성 처리
```sql
INSERT INTO numbering_sequences (tenant_id, document_type, scope_key, period_key, last_sequence)
VALUES (?, ?, ?, ?, 1)
ON DUPLICATE KEY UPDATE last_sequence = last_sequence + 1
```
MySQL의 `UPSERT`를 사용하여 동시 요청에서도 시퀀스 충돌 없이 안전하게 번호 생성.
---
## 6. 호출 위치
직접 API 엔드포인트는 없으며, 아래 서비스에서 내부 호출된다:
| 서비스 | 용도 |
|--------|------|
| `QuoteNumberService` | 견적번호 생성 |
| `OrderService` | 수주번호 생성 |
| `WorkOrderService` | 작업지시번호 생성 |
| `MaterialReceiptService` | 입고번호 생성 |
---
## 관련 문서
- [DB 스키마 — 공통](../system/database/commons.md)
- [품목 정책](item-policy.md) — 품목 코드 체계
---
**최종 업데이트**: 2026-02-27

View File

@@ -0,0 +1,114 @@
# SAM 영업파트너 수당 체계
> **작성일**: 2026-02-21
> **상태**: 설계 확정
---
## 1. 개요
### 1.1 목적
영업파트너가 알아야 할 수당 체계 및 정산 프로세스를 안내한다.
### 1.2 기본 원칙
- 수당은 **개발비에 대해서만** 지급한다
- 구독료는 플랫폼 유지보수 및 클라우드 인프라 비용으로 활용되며 수당 대상이 아니다
- 기준금액은 개발비의 50%이며, 2단계(1차/2차) 분할 지급한다
---
## 2. 가입 유형별 수당률
| 가입 유형 | 파트너/단체 수당 | 매니저 수당 | 협업지원금(유치자) | **본사 총 지급률** |
|-----------|:--------------:|:----------:|:-----------------:|:----------------:|
| **개인 가입** | 20% | 5% | 3% | **28%** |
| **단체 가입** | 30% | 0% | 3% | **33%** |
- **협업지원금**: 유치자(parent)가 자신이 유치한 하위 파트너의 매출에서 3%를 수령하는 내부 제도
- 1단계까지만 적용 (유치자 → 하위 파트너, 그 이상 상위로는 올라가지 않음)
- 단체 가입 시 매니저 수당은 0%
- 단체 가입 시 수수료율은 개발비의 33% (VAT 별도)
---
## 3. 수당 산정 예시
### 3.1 기준금액 100만원 기준
| 가입 유형 | 파트너/단체 | 매니저 | 협업지원금 | 본사 총 지급 |
|-----------|----------:|-------:|----------:|------------:|
| 개인 (유치자 있음) | 200,000원 | 50,000원 | 30,000원 | **280,000원 (28%)** |
| 개인 (유치자 없음) | 200,000원 | 50,000원 | 0원 | 250,000원 (25%) |
| 단체 | 300,000원 | 0원 | 30,000원 | **330,000원 (33%)** |
### 3.2 제조업 기본 패키지 (개발비 2,000만원) 기준
**개인 가입:**
| 항목 | 금액 |
|------|-----:|
| 판매자(파트너) 수당 | 400만원 (20%) |
| 매니저 수당 | 100만원 (5%) |
| 협업지원금(유치자) | 60만원 (3%) |
**단체 가입:**
| 항목 | 금액 |
|------|-----:|
| 단체 수당 | 600만원 (30%) |
| 매니저 수당 | 0원 (0%) |
| 협업지원금(유치자) | 60만원 (3%) |
---
## 4. 수당 지급 프로세스
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 1. 계약 및 입금 │ → │ 2. 수당 확정 │ → │ 3. 지급 │
│ │ │ │ │ │
│ 개발비 전액 │ │ 매월 정산일에 │ │ 파트너 등록 │
│ 완납 확인 │ │ 건별 수당 확정 │ │ 계좌로 지급 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
- **지급 시점**: 개발비 입금 완료 확인 후 익월 정산일
---
## 5. 추가 옵션별 수당 참고
개발비가 있는 옵션만 수당 대상이다. 서비스 요금 상세는 [고객 요금 안내](customer-pricing.md)를 참조한다.
| 옵션명 | 개발비 (VAT 별도) | 판매자 수당 (20%) |
|--------|------------------:|------------------:|
| 생산공정 1개 추가 | 500만원 | 100만원 |
| 품질관리 (인정검사) | 2,000만원 | 400만원 |
> **참고**: 구독료만 있는 옵션(사진 등록, 챗봇/녹음/업무일지 등)은 수당 대상이 아니다.
---
## 6. 기타 정책
- **계약 유지**: 장기 구독을 전제로 한 초기 비용 할인 정책이므로, 중도 해지 시 별도의 위약금 규정이 적용될 수 있다
- **구독료**: 플랫폼 유지보수 및 클라우드 인프라 비용으로 활용되며, 수당 지급 대상이 아니다
---
## 7. 관련 문서
- [고객 요금 안내](customer-pricing.md) - 서비스 요금 상세 (고객용)
- [내부 과금정책](billing-policy.md) - 본사 지출 원가 및 코드 참조 (내부용)
- `sales/price/수당지급체계.md` - 수당 지급 체계 원본
- `sales/policy/SAM_영업정책문서.md` - 영업 정책 상세
---
> **공통 안내**: 본 문서에 명시된 모든 개발비 및 구독료는 **부가가치세(VAT) 별도** 금액이다.
---
**최종 업데이트**: 2026-02-21

Binary file not shown.

View File

@@ -0,0 +1,402 @@
# 단가 정책 (Pricing Policy)
> **작성일**: 2025-12-08
> **상태**: 설계 확정
> **관련 요청**: `docs/front/[API-2025-12-08] pricing-api-enhancement-request.md`
---
## 1. 개요
### 1.1 목적
- 품목(제품/자재)의 **표준단가** 관리
- **실제 입고단가** 기반 원가 계산
- 단가 변경 **이력(리비전)** 추적
- 고객그룹별 **차등 판매가** 지원
### 1.2 핵심 원칙
| 원칙 | 설명 |
|------|------|
| **실제원가 우선** | 수입검사 입고단가 > 표준원가 |
| **시점 기반 유효성** | effective_from ~ effective_to 기간 내 유효 |
| **리비전 추적** | 모든 변경 사항 이력 보관 |
| **확정 후 불변** | finalized 상태는 수정 불가 |
---
## 2. 테이블 구조
### 2.1 ERD 개요
```
┌─────────────────┐ ┌─────────────────────┐
│ prices │──────<│ price_revisions │
│ (단가 마스터) │ │ (변경 이력) │
└────────┬────────┘ └─────────────────────┘
│ item_type_code + item_id
┌────┴────┐
│ │
┌───▼───┐ ┌───▼─────┐
│products│ │materials│
└───────┘ └────┬────┘
│ material_id
┌─────────────────┐
│material_receipts│
│ (실제 입고단가) │
└─────────────────┘
```
### 2.2 prices 테이블 (단가 마스터)
```sql
CREATE TABLE prices (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '테넌트 ID',
-- 품목 연결 --
item_type_code VARCHAR(20) NOT NULL COMMENT '품목유형 (PRODUCT/MATERIAL)',
item_id BIGINT UNSIGNED NOT NULL COMMENT '품목 ID',
client_group_id BIGINT UNSIGNED NULL COMMENT '고객그룹 ID (NULL=기본가)',
-- 원가 정보 --
purchase_price DECIMAL(15,4) NULL COMMENT '매입단가 (표준원가)',
processing_cost DECIMAL(15,4) NULL COMMENT '가공비',
loss_rate DECIMAL(5,2) NULL COMMENT 'LOSS율 (%)',
-- 판매가 정보 --
margin_rate DECIMAL(5,2) NULL COMMENT '마진율 (%)',
sales_price DECIMAL(15,4) NULL COMMENT '판매단가',
rounding_rule ENUM('round','ceil','floor') DEFAULT 'round' COMMENT '반올림 규칙',
rounding_unit INT DEFAULT 1 COMMENT '반올림 단위 (1,10,100,1000)',
-- 메타 정보 --
supplier VARCHAR(255) NULL COMMENT '공급업체',
effective_from DATE NOT NULL COMMENT '적용 시작일',
effective_to DATE NULL COMMENT '적용 종료일',
note TEXT NULL COMMENT '비고',
-- 상태 관리 --
status ENUM('draft','active','inactive','finalized') DEFAULT 'draft' COMMENT '상태',
is_final BOOLEAN DEFAULT FALSE COMMENT '최종 확정 여부',
finalized_at DATETIME NULL COMMENT '확정 일시',
finalized_by BIGINT UNSIGNED NULL COMMENT '확정자 ID',
-- 감사 컬럼 --
created_by BIGINT UNSIGNED NULL COMMENT '생성자 ID',
updated_by BIGINT UNSIGNED NULL COMMENT '수정자 ID',
deleted_by BIGINT UNSIGNED NULL COMMENT '삭제자 ID',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL COMMENT 'Soft Delete',
-- 인덱스 --
INDEX idx_prices_tenant (tenant_id),
INDEX idx_prices_item (tenant_id, item_type_code, item_id),
INDEX idx_prices_effective (tenant_id, effective_from, effective_to),
INDEX idx_prices_status (tenant_id, status),
UNIQUE idx_prices_unique (tenant_id, item_type_code, item_id, client_group_id, effective_from, deleted_at)
) COMMENT='단가 마스터';
```
### 2.3 price_revisions 테이블 (변경 이력)
```sql
CREATE TABLE price_revisions (
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '테넌트 ID',
price_id BIGINT UNSIGNED NOT NULL COMMENT '단가 ID',
-- 리비전 정보 --
revision_number INT NOT NULL COMMENT '리비전 번호',
changed_at DATETIME NOT NULL COMMENT '변경 일시',
changed_by BIGINT UNSIGNED NOT NULL COMMENT '변경자 ID',
change_reason VARCHAR(500) NULL COMMENT '변경 사유',
-- 변경 스냅샷 (JSON) --
before_snapshot JSON NULL COMMENT '변경 전 데이터',
after_snapshot JSON NOT NULL COMMENT '변경 후 데이터',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- 인덱스 --
INDEX idx_revisions_price (price_id),
INDEX idx_revisions_tenant (tenant_id),
UNIQUE idx_revisions_unique (price_id, revision_number),
FOREIGN KEY (price_id) REFERENCES prices(id) ON DELETE CASCADE
) COMMENT='단가 변경 이력';
```
### 2.4 material_receipts 테이블 (기존 - 실제 입고단가)
```sql
-- 기존 테이블, purchase_price_excl_vat 필드 활용
-- 수입검사 시 실제 입고 단가 입력
```
---
## 3. 원가 계산 정책
### 3.1 원가 조회 우선순위
```
┌─────────────────────────────────────────────────────────┐
│ 원가 조회 로직 │
├─────────────────────────────────────────────────────────┤
│ 1순위: 수입검사 입고단가 │
│ material_receipts.purchase_price_excl_vat │
│ (가장 최근 입고 기준) │
│ │
│ 2순위: 표준원가 │
│ prices.purchase_price │
│ (해당 일자에 유효한 단가) │
│ │
│ 3순위: NULL (단가 미등록) │
│ → 경고 메시지 반환 │
└─────────────────────────────────────────────────────────┘
```
### 3.2 원가 계산 공식
```
총원가 = (매입단가 + 가공비) × (1 + LOSS율/100)
예시:
- 매입단가: 10,000원
- 가공비: 2,000원
- LOSS율: 5%
- 총원가 = (10,000 + 2,000) × 1.05 = 12,600원
```
### 3.3 품목 유형별 원가 적용
| 품목 유형 | 원가 소스 | 설명 |
|----------|----------|------|
| **MATERIAL** (자재) | material_receipts 우선 | 실제 입고단가 사용 |
| **PRODUCT** (제품) | prices 테이블 | 표준원가 사용 |
---
## 4. 판매가 계산 정책
### 4.1 판매가 계산 공식
```
판매단가 = 반올림(총원가 × (1 + 마진율/100), 반올림단위, 반올림규칙)
예시:
- 총원가: 12,600원
- 마진율: 25%
- 반올림단위: 100
- 반올림규칙: round
- 판매단가 = round(12,600 × 1.25, 100) = round(15,750, 100) = 15,800원
```
### 4.2 반올림 규칙
| 규칙 | 설명 | 예시 (단위: 100) |
|------|------|-----------------|
| `round` | 반올림 | 15,750 → 15,800 |
| `ceil` | 올림 | 15,701 → 15,800 |
| `floor` | 버림 | 15,799 → 15,700 |
### 4.3 고객그룹별 차등가
```
┌─────────────────────────────────────────────────────────┐
│ 판매가 조회 우선순위 │
├─────────────────────────────────────────────────────────┤
│ 1순위: 고객그룹별 특별가 │
│ prices WHERE client_group_id = [고객의 그룹ID] │
│ │
│ 2순위: 기본 판매가 │
│ prices WHERE client_group_id IS NULL │
└─────────────────────────────────────────────────────────┘
```
---
## 5. 상태 관리
### 5.1 단가 상태 (status)
```
┌──────────┐ 등록 ┌──────────┐ 활성화 ┌──────────┐
│ draft │ ──────────> │ active │ ─────────── │ finalized│
│ (초안) │ │ (활성) │ 확정 │ (확정) │
└──────────┘ └────┬─────┘ └──────────┘
│ 비활성화
┌──────────┐
│ inactive │
│ (비활성) │
└──────────┘
```
### 5.2 상태별 권한
| 상태 | 조회 | 수정 | 삭제 | 확정 |
|------|------|------|------|------|
| `draft` | ✅ | ✅ | ✅ | ✅ |
| `active` | ✅ | ✅ | ✅ | ✅ |
| `inactive` | ✅ | ✅ | ✅ | ❌ |
| `finalized` | ✅ | ❌ | ❌ | ❌ |
### 5.3 확정 (Finalize) 규칙
- **확정 조건**: status가 `draft` 또는 `active`일 때만 가능
- **확정 효과**:
- `is_final = true`
- `status = 'finalized'`
- `finalized_at = NOW()`
- `finalized_by = 현재 사용자`
- **확정 후**: 수정/삭제 불가, 조회만 가능
---
## 6. 리비전 관리
### 6.1 리비전 생성 시점
| 이벤트 | 리비전 생성 | 설명 |
|--------|-----------|------|
| 최초 등록 | ✅ | revision_number = 1, before_snapshot = NULL |
| 수정 | ✅ | revision_number++, 변경 전/후 기록 |
| 삭제 | ✅ | soft delete, 삭제 전 상태 기록 |
| 확정 | ✅ | 확정 시점 스냅샷 기록 |
### 6.2 스냅샷 JSON 구조
```json
{
"purchase_price": 10000,
"processing_cost": 2000,
"loss_rate": 5.0,
"margin_rate": 25.0,
"sales_price": 15800,
"effective_from": "2025-01-01",
"effective_to": null,
"status": "active",
"supplier": "ABC공급"
}
```
---
## 7. API 엔드포인트
### 7.1 엔드포인트 목록
| Method | Endpoint | 설명 | 우선순위 |
|--------|----------|------|---------|
| GET | `/api/v1/pricing` | 단가 목록 조회 | 🔴 필수 |
| GET | `/api/v1/pricing/{id}` | 단가 상세 조회 | 🔴 필수 |
| POST | `/api/v1/pricing` | 단가 등록 | 🔴 필수 |
| PUT | `/api/v1/pricing/{id}` | 단가 수정 | 🔴 필수 |
| DELETE | `/api/v1/pricing/{id}` | 단가 삭제 | 🔴 필수 |
| GET | `/api/v1/pricing/by-items` | 품목별 단가 현황 | 🔴 필수 |
| GET | `/api/v1/pricing/{id}/revisions` | 변경 이력 조회 | 🟡 중요 |
| POST | `/api/v1/pricing/{id}/finalize` | 단가 확정 | 🟢 권장 |
| GET | `/api/v1/pricing/cost` | 원가 조회 (계산) | 🟡 중요 |
### 7.2 원가 조회 API
```
GET /api/v1/pricing/cost?item_type=MATERIAL&item_id=123&date=2025-01-15
```
**Response:**
```json
{
"success": true,
"data": {
"item_type": "MATERIAL",
"item_id": 123,
"cost_source": "receipt", // "receipt" | "standard" | "not_found"
"purchase_price": 10500,
"receipt_id": 456, // cost_source가 receipt일 때
"receipt_date": "2025-01-10",
"price_id": null // cost_source가 standard일 때
}
}
```
---
## 8. 비즈니스 규칙
### 8.1 검증 규칙
| 규칙 | 설명 |
|------|------|
| **R1** | effective_from은 필수 |
| **R2** | effective_from ≤ effective_to (종료일이 있을 경우) |
| **R3** | 동일 품목+고객그룹+적용시작일 조합은 중복 불가 |
| **R4** | 확정된 단가는 수정/삭제 불가 |
| **R5** | 마진율은 0~100% 범위 |
| **R6** | LOSS율은 0~100% 범위 |
| **R7** | 반올림단위는 1, 10, 100, 1000 중 하나 |
### 8.2 기간 중복 처리
```
기존: 2025-01-01 ~ NULL (무기한)
신규: 2025-06-01 ~ NULL
→ 기존 단가의 effective_to를 2025-05-31로 자동 설정
→ 신규 단가 등록
```
### 8.3 삭제 정책
- **Soft Delete** 적용
- 삭제 시 `deleted_at`, `deleted_by` 기록
- 삭제된 단가도 리비전 이력에서 조회 가능
---
## 9. 기존 시스템 호환
### 9.1 price_histories 테이블 처리
| 상태 | 설명 |
|------|------|
| **현재** | 기존 price_histories 데이터 유지 |
| **전환 기간** | 양쪽 테이블 병행 운영 |
| **전환 완료 후** | price_histories deprecated |
### 9.2 데이터 마이그레이션
```sql
-- 기존 데이터를 prices 테이블로 마이그레이션
INSERT INTO prices (
tenant_id, item_type_code, item_id, client_group_id,
purchase_price, effective_from, effective_to,
status, created_by, created_at
)
SELECT
tenant_id, item_type_code, item_id, client_group_id,
price as purchase_price, started_at, ended_at,
'active', created_by, created_at
FROM price_histories
WHERE deleted_at IS NULL;
```
---
## 10. 관련 문서
- [API 개발 규칙](../standards/api-rules.md)
- [데이터베이스 스키마](../system/database/README.md)
- [프론트엔드 요청서](../front/[API-2025-12-08]%20pricing-api-enhancement-request.md)
---
**최종 업데이트**: 2025-12-08

View File

@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #1a0a0a;
padding: 32pt 40pt;
display: flex;
flex-direction: column;
justify-content: space-between;
}
</style>
</head>
<body>
<!-- 상단 로고 + 배지 -->
<div style="display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; align-items: center; gap: 10pt;">
<img src="/home/aweso/sam/docs/assets/bi/sam_bi_red.png" style="width: 28pt; height: 28pt; border-radius: 4pt;">
<p style="font-size: 14pt; font-weight: 700; color: #ffffff;">SAM</p>
</div>
<div style="display: inline-block; padding: 5pt 16pt; background: #C0392B; border-radius: 16pt;">
<p style="font-size: 9pt; font-weight: 700; color: #ffffff; letter-spacing: 0.08em;">CONFIDENTIAL</p>
</div>
</div>
<!-- 메인 타이틀 -->
<div>
<p style="font-size: 11pt; font-weight: 600; color: #E74C3C; letter-spacing: 0.06em; margin-bottom: 10pt;">INTERNAL USE ONLY</p>
<h1 style="font-size: 44pt; font-weight: 800; color: #ffffff; letter-spacing: -0.02em; line-height: 1.15;">SAM 과금정책</h1>
<p style="font-size: 14pt; color: rgba(255,255,255,0.4); margin-top: 12pt; line-height: 1.5;">본사 지출 원가 · 마진 구조 · 코드 참조</p>
</div>
<!-- 3개 핵심 수치 카드 -->
<div style="display: flex; gap: 14pt; margin-bottom: 14pt;">
<div style="flex: 1; padding: 14pt 16pt; background: rgba(255,255,255,0.06); border-radius: 8pt; border-left: 3pt solid #E74C3C;">
<p style="font-size: 7.5pt; color: rgba(255,255,255,0.35); letter-spacing: 0.04em; margin-bottom: 4pt;">COST PER TENANT</p>
<p style="font-size: 18pt; font-weight: 700; color: #ffffff;">~1<span style="font-size: 11pt; font-weight: 500;">만원</span><span style="font-size: 10pt; font-weight: 400; color: rgba(255,255,255,0.4);">/월</span></p>
<p style="font-size: 8pt; color: rgba(255,255,255,0.35); margin-top: 3pt;">테넌트당 월 원가</p>
</div>
<div style="flex: 1; padding: 14pt 16pt; background: rgba(255,255,255,0.06); border-radius: 8pt; border-left: 3pt solid #27AE60;">
<p style="font-size: 7.5pt; color: rgba(255,255,255,0.35); letter-spacing: 0.04em; margin-bottom: 4pt;">OPERATING MARGIN</p>
<p style="font-size: 18pt; font-weight: 700; color: #27AE60;">67~75%</p>
<p style="font-size: 8pt; color: rgba(255,255,255,0.35); margin-top: 3pt;">영업이익률</p>
</div>
<div style="flex: 1; padding: 14pt 16pt; background: rgba(255,255,255,0.06); border-radius: 8pt; border-left: 3pt solid #E74C3C;">
<p style="font-size: 7.5pt; color: rgba(255,255,255,0.35); letter-spacing: 0.04em; margin-bottom: 4pt;">SCALE ADVANTAGE</p>
<p style="font-size: 18pt; font-weight: 700; color: #ffffff;">MC → 0</p>
<p style="font-size: 8pt; color: rgba(255,255,255,0.35); margin-top: 3pt;">스케일 시 한계비용</p>
</div>
</div>
<!-- 하단 메타 -->
<div style="display: flex; gap: 48pt;">
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.25); margin-bottom: 3pt;">SCOPE</p>
<p style="font-size: 10pt; font-weight: 500; color: rgba(255,255,255,0.55);">내부 개발팀 / 관리층</p>
</div>
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.25); margin-bottom: 3pt;">DATE</p>
<p style="font-size: 10pt; font-weight: 500; color: rgba(255,255,255,0.55);">2026. 02</p>
</div>
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.25); margin-bottom: 3pt;">WARNING</p>
<p style="font-size: 10pt; font-weight: 600; color: #E74C3C;">대외 공유 금지</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #f5f5f0;
padding: 30pt 40pt;
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 18pt;">
<div style="display: flex; align-items: center; gap: 12pt;">
<div style="display: inline-block; padding: 4pt 10pt; background: #1a0a0a; border-radius: 4pt;">
<p style="color: #E74C3C; font-size: 8pt; font-weight: 600;">OVERVIEW</p>
</div>
<h2 style="font-size: 22pt; font-weight: 700; color: #1a0a0a;">과금정책 3분할 체계</h2>
</div>
<div style="display: inline-block; padding: 3pt 10pt; background: #C0392B; border-radius: 10pt;">
<p style="color: #fff; font-size: 7pt; font-weight: 600;">CONFIDENTIAL</p>
</div>
</div>
<!-- 3개 카드 -->
<div style="flex: 1; display: flex; gap: 14pt; margin-bottom: 12pt;">
<!-- 고객용 -->
<div style="flex: 1; display: flex; flex-direction: column; background: #ffffff; border-radius: 10pt; padding: 18pt; border-top: 3pt solid #2E86AB;">
<div style="display: inline-block; padding: 3pt 8pt; background: #2E86AB; border-radius: 3pt; margin-bottom: 10pt; align-self: flex-start;">
<p style="color: #fff; font-size: 7pt; font-weight: 600;">FOR CUSTOMER</p>
</div>
<h3 style="font-size: 14pt; font-weight: 700; color: #1a1a1a; margin-bottom: 6pt;">고객용</h3>
<div style="display: flex; align-items: center; gap: 4pt; margin-bottom: 10pt; padding: 5pt 8pt; background: #f0f7ff; border-radius: 4pt;">
<p style="font-size: 8pt; color: #2E86AB; font-weight: 500;">customer-pricing.md</p>
</div>
<p style="font-size: 9pt; color: #666; line-height: 1.6; margin-bottom: 8pt;">서비스 가격표, 과금 기준</p>
<div style="margin-top: auto; padding-top: 8pt; border-top: 1pt solid #eee;">
<p style="font-size: 8pt; color: #999;">고객에게 직접 전달 가능</p>
</div>
</div>
<!-- 파트너용 -->
<div style="flex: 1; display: flex; flex-direction: column; background: #ffffff; border-radius: 10pt; padding: 18pt; border-top: 3pt solid #27AE60;">
<div style="display: inline-block; padding: 3pt 8pt; background: #27AE60; border-radius: 3pt; margin-bottom: 10pt; align-self: flex-start;">
<p style="color: #fff; font-size: 7pt; font-weight: 600;">FOR PARTNER</p>
</div>
<h3 style="font-size: 14pt; font-weight: 700; color: #1a1a1a; margin-bottom: 6pt;">파트너용</h3>
<div style="display: flex; align-items: center; gap: 4pt; margin-bottom: 10pt; padding: 5pt 8pt; background: #f0faf4; border-radius: 4pt;">
<p style="font-size: 8pt; color: #27AE60; font-weight: 500;">partner-commission.md</p>
</div>
<p style="font-size: 9pt; color: #666; line-height: 1.6; margin-bottom: 8pt;">수당률, 정산 프로세스</p>
<div style="margin-top: auto; padding-top: 8pt; border-top: 1pt solid #eee;">
<p style="font-size: 8pt; color: #999;">영업파트너 제공용</p>
</div>
</div>
<!-- 내부용 -->
<div style="flex: 1; display: flex; flex-direction: column; background: #1a0a0a; border-radius: 10pt; padding: 18pt; border-top: 3pt solid #C0392B;">
<div style="display: inline-block; padding: 3pt 8pt; background: #C0392B; border-radius: 3pt; margin-bottom: 10pt; align-self: flex-start;">
<p style="color: #fff; font-size: 7pt; font-weight: 600;">INTERNAL ONLY</p>
</div>
<h3 style="font-size: 14pt; font-weight: 700; color: #ffffff; margin-bottom: 6pt;">내부용 (본 문서)</h3>
<div style="display: flex; align-items: center; gap: 4pt; margin-bottom: 10pt; padding: 5pt 8pt; background: rgba(255,255,255,0.06); border-radius: 4pt;">
<p style="font-size: 8pt; color: #E74C3C; font-weight: 500;">billing-policy.md</p>
</div>
<p style="font-size: 9pt; color: rgba(255,255,255,0.5); line-height: 1.6; margin-bottom: 8pt;">원가, 마진, 코드참조</p>
<div style="margin-top: auto; padding-top: 8pt; border-top: 1pt solid rgba(255,255,255,0.1);">
<p style="font-size: 8pt; color: #E74C3C; font-weight: 600;">대외 공유 금지</p>
</div>
</div>
</div>
<!-- 경고 -->
<div style="padding: 10pt 16pt; background: #fdedef; border-left: 3pt solid #C0392B; border-radius: 0 6pt 6pt 0; margin-bottom: 10pt;">
<p style="font-size: 9.5pt; font-weight: 600; color: #C0392B;">본 문서는 내부 개발팀/관리층 전용입니다. 고객 및 파트너에게 공유하지 마세요.</p>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 8pt; border-top: 1pt solid #e5e5e0;">
<p style="font-size: 8pt; color: #999;">SAM 내부 과금정책 | CONFIDENTIAL</p>
<p style="font-size: 8pt; color: #999;">02</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,109 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #ffffff;
padding: 28pt 40pt;
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 14pt;">
<div style="display: flex; align-items: center; gap: 12pt;">
<div style="display: inline-block; padding: 4pt 10pt; background: #1a0a0a; border-radius: 4pt;">
<p style="color: #E74C3C; font-size: 8pt; font-weight: 600;">COST</p>
</div>
<h2 style="font-size: 20pt; font-weight: 700; color: #1a1a1a;">바로빌 API 원가 분석</h2>
</div>
<p style="font-size: 10pt; color: #999;">03</p>
</div>
<!-- 2컬럼 -->
<div style="flex: 1; display: flex; gap: 18pt;">
<!-- 좌측: 월정액 서비스 -->
<div style="flex: 1.2; display: flex; flex-direction: column;">
<p style="font-size: 10pt; font-weight: 600; color: #666; margin-bottom: 8pt; letter-spacing: 0.03em;">월정액 서비스</p>
<!-- 헤더 행 -->
<div style="display: flex; background: #1a0a0a; border-radius: 4pt 4pt 0 0; padding: 7pt 10pt;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; font-weight: 600; color: #E74C3C;">서비스</p></div>
<div style="flex: 0.8; text-align: right;"><p style="font-size: 8.5pt; font-weight: 600; color: #fff;">월정액</p></div>
<div style="flex: 1.6; text-align: right;"><p style="font-size: 8.5pt; font-weight: 600; color: #fff;">처리 방식</p></div>
</div>
<!-- 계좌조회 -->
<div style="display: flex; padding: 7pt 10pt; background: #fafafa;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; color: #1a1a1a;">계좌조회</p></div>
<div style="flex: 0.8; text-align: right;"><p style="font-size: 8.5pt; color: #1a1a1a;">10,000원</p></div>
<div style="flex: 1.6; text-align: right;"><p style="font-size: 8.5pt; color: #666;">고객 부담 (전가)</p></div>
</div>
<!-- 카드내역 -->
<div style="display: flex; padding: 7pt 10pt; background: #fff;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; color: #1a1a1a;">카드내역</p></div>
<div style="flex: 0.8; text-align: right;"><p style="font-size: 8.5pt; color: #1a1a1a;">10,000원</p></div>
<div style="flex: 1.6; text-align: right;"><p style="font-size: 8.5pt; color: #666;">고객 부담 (전가)</p></div>
</div>
<!-- 홈택스 매입 -->
<div style="display: flex; padding: 7pt 10pt; background: #f0faf4;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; color: #1a1a1a;">홈택스 매입</p></div>
<div style="flex: 0.8; text-align: right;"><p style="font-size: 8.5pt; color: #1a1a1a;">33,000원</p></div>
<div style="flex: 1.6; text-align: right;"><p style="font-size: 8.5pt; font-weight: 600; color: #27AE60;">본사 흡수 (코드브릿지엑스 → 무료)</p></div>
</div>
<!-- 홈택스 매출 -->
<div style="display: flex; padding: 7pt 10pt; background: #f0faf4; border-radius: 0 0 4pt 4pt;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; color: #1a1a1a;">홈택스 매출</p></div>
<div style="flex: 0.8; text-align: right;"><p style="font-size: 8.5pt; color: #1a1a1a;">33,000원</p></div>
<div style="flex: 1.6; text-align: right;"><p style="font-size: 8.5pt; font-weight: 600; color: #27AE60;">본사 흡수 (무료)</p></div>
</div>
</div>
<!-- 우측 -->
<div style="flex: 1; display: flex; flex-direction: column; gap: 12pt;">
<!-- 건별 과금 -->
<div>
<p style="font-size: 10pt; font-weight: 600; color: #666; margin-bottom: 8pt; letter-spacing: 0.03em;">건별 과금</p>
<!-- 헤더 -->
<div style="display: flex; background: #1a0a0a; border-radius: 4pt 4pt 0 0; padding: 7pt 10pt;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; font-weight: 600; color: #E74C3C;">서비스</p></div>
<div style="flex: 1; text-align: right;"><p style="font-size: 8.5pt; font-weight: 600; color: #fff;">원가</p></div>
</div>
<div style="display: flex; padding: 7pt 10pt; background: #fafafa; border-radius: 0 0 4pt 4pt;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; color: #1a1a1a;">세금계산서 발행</p></div>
<div style="flex: 1; text-align: right;"><p style="font-size: 8.5pt; font-weight: 600; color: #E74C3C;">100원/건</p></div>
</div>
<!-- 마진 계산 -->
<div style="padding: 8pt 10pt; background: #fff8f0; border-radius: 4pt; margin-top: 6pt; border-left: 2pt solid #E74C3C;">
<p style="font-size: 8pt; color: #1a1a1a; font-weight: 500;">고객 과금: 5,000원/50건</p>
<p style="font-size: 8pt; color: #E74C3C; font-weight: 600;">마진: 4,900원 (98%)</p>
</div>
</div>
<!-- 참고 박스 -->
<div style="flex: 1; background: #f5f5f0; border-radius: 8pt; padding: 12pt; display: flex; flex-direction: column; gap: 6pt;">
<p style="font-size: 9pt; font-weight: 700; color: #1a1a1a; margin-bottom: 2pt;">핵심 요약</p>
<div style="display: flex; align-items: flex-start; gap: 6pt;">
<div style="width: 3pt; height: 3pt; background: #27AE60; border-radius: 50%; flex-shrink: 0; margin-top: 4pt;"></div>
<p style="font-size: 8pt; color: #666; line-height: 1.6;">계좌/카드 → 고객 전가, 홈택스 → 코드브릿지엑스 지원으로 본사 원가 0원</p>
</div>
<div style="display: flex; align-items: flex-start; gap: 6pt;">
<div style="width: 3pt; height: 3pt; background: #E74C3C; border-radius: 50%; flex-shrink: 0; margin-top: 4pt;"></div>
<p style="font-size: 8pt; color: #666; line-height: 1.6;">본사 실질 부담: 세금계산서 원가만 (5,000~10,000원/월)</p>
</div>
</div>
</div>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 8pt; border-top: 1pt solid #eee; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">SAM 내부 과금정책 | CONFIDENTIAL</p>
<p style="font-size: 8pt; color: #999;">03</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,142 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #ffffff;
padding: 28pt 40pt;
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12pt;">
<div style="display: flex; align-items: center; gap: 12pt;">
<div style="display: inline-block; padding: 4pt 10pt; background: #1a0a0a; border-radius: 4pt;">
<p style="color: #E74C3C; font-size: 8pt; font-weight: 600;">COST</p>
</div>
<h2 style="font-size: 20pt; font-weight: 700; color: #1a1a1a;">AI / 클라우드 원가 분석</h2>
</div>
<p style="font-size: 10pt; color: #999;">04</p>
</div>
<!-- 2컬럼 -->
<div style="flex: 1; display: flex; gap: 18pt;">
<!-- 좌측: 토큰 기반 과금 -->
<div style="flex: 1; display: flex; flex-direction: column;">
<div style="display: flex; align-items: center; gap: 8pt; margin-bottom: 10pt;">
<p style="font-size: 10pt; font-weight: 600; color: #666; letter-spacing: 0.03em;">토큰 기반 과금 (LLM)</p>
<div style="display: inline-block; padding: 2pt 6pt; background: #f5f5f0; border-radius: 3pt;">
<p style="font-size: 7pt; color: #999;">환율 1,400원/USD</p>
</div>
</div>
<!-- Gemini 카드 -->
<div style="background: #f8f9ff; border-radius: 8pt; padding: 12pt; margin-bottom: 8pt; border-left: 3pt solid #4285F4;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8pt;">
<p style="font-size: 10pt; font-weight: 700; color: #1a1a1a;">Google Gemini 2.0 Flash</p>
</div>
<div style="display: flex; gap: 10pt; margin-bottom: 6pt;">
<div style="flex: 1; padding: 6pt 8pt; background: #ffffff; border-radius: 4pt;">
<p style="font-size: 7pt; color: #999; margin-bottom: 2pt;">입력 /1M 토큰</p>
<p style="font-size: 9pt; font-weight: 600; color: #1a1a1a;"><span style="color: #999; font-weight: 400;">$0.10 →</span> 140원</p>
</div>
<div style="flex: 1; padding: 6pt 8pt; background: #ffffff; border-radius: 4pt;">
<p style="font-size: 7pt; color: #999; margin-bottom: 2pt;">출력 /1M 토큰</p>
<p style="font-size: 9pt; font-weight: 600; color: #1a1a1a;"><span style="color: #999; font-weight: 400;">$0.40 →</span> 560원</p>
</div>
</div>
<div style="padding: 4pt 8pt; background: #e8f5e9; border-radius: 3pt;">
<p style="font-size: 7.5pt; color: #27AE60; font-weight: 600;">초저비용 AI — 100만 토큰 처리해도 700원</p>
</div>
</div>
<!-- Claude 카드 -->
<div style="background: #fdf6f0; border-radius: 8pt; padding: 12pt; border-left: 3pt solid #D97706;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8pt;">
<p style="font-size: 10pt; font-weight: 700; color: #1a1a1a;">Anthropic Claude 3 Haiku</p>
</div>
<div style="display: flex; gap: 10pt; margin-bottom: 6pt;">
<div style="flex: 1; padding: 6pt 8pt; background: #ffffff; border-radius: 4pt;">
<p style="font-size: 7pt; color: #999; margin-bottom: 2pt;">입력 /1M 토큰</p>
<p style="font-size: 9pt; font-weight: 600; color: #1a1a1a;"><span style="color: #999; font-weight: 400;">$0.25 →</span> 350원</p>
</div>
<div style="flex: 1; padding: 6pt 8pt; background: #ffffff; border-radius: 4pt;">
<p style="font-size: 7pt; color: #999; margin-bottom: 2pt;">출력 /1M 토큰</p>
<p style="font-size: 9pt; font-weight: 600; color: #1a1a1a;"><span style="color: #999; font-weight: 400;">$1.25 →</span> 1,750원</p>
</div>
</div>
<div style="padding: 4pt 8pt; background: #fff8e1; border-radius: 3pt;">
<p style="font-size: 7.5pt; color: #D97706; font-weight: 600;">고품질 AI — 100만 토큰에도 약 2,100원</p>
</div>
</div>
</div>
<!-- 우측: 시간/작업 기반 과금 -->
<div style="flex: 1; display: flex; flex-direction: column;">
<p style="font-size: 10pt; font-weight: 600; color: #666; margin-bottom: 10pt; letter-spacing: 0.03em;">시간/작업 기반 과금</p>
<!-- Google STT -->
<div style="display: flex; padding: 10pt 12pt; background: #fafafa; border-radius: 6pt; margin-bottom: 6pt; border-left: 3pt solid #E74C3C;">
<div style="flex: 1;">
<p style="font-size: 9.5pt; font-weight: 600; color: #1a1a1a; margin-bottom: 3pt;">Google STT</p>
<p style="font-size: 8pt; color: #999;">$0.009 / 15초</p>
</div>
<div style="text-align: right;">
<p style="font-size: 9.5pt; font-weight: 700; color: #E74C3C;">~50원<span style="font-size: 8pt; font-weight: 400; color: #999;">/분</span></p>
<p style="font-size: 7.5pt; color: #666; margin-top: 2pt;">1시간 녹음 처리 = 3,000원</p>
</div>
</div>
<!-- Google GCS -->
<div style="display: flex; padding: 10pt 12pt; background: #f0faf4; border-radius: 6pt; margin-bottom: 6pt; border-left: 3pt solid #27AE60;">
<div style="flex: 1;">
<p style="font-size: 9.5pt; font-weight: 600; color: #1a1a1a; margin-bottom: 3pt;">Google GCS</p>
<p style="font-size: 8pt; color: #999;">$0.005 / 1,000건</p>
</div>
<div style="text-align: right;">
<p style="font-size: 9.5pt; font-weight: 700; color: #27AE60;">7원<span style="font-size: 8pt; font-weight: 400; color: #999;">/1,000건</span></p>
<p style="font-size: 7.5pt; color: #27AE60; font-weight: 500; margin-top: 2pt;">사실상 무료 수준</p>
</div>
</div>
<!-- Google FCM -->
<div style="display: flex; padding: 10pt 12pt; background: #f0faf4; border-radius: 6pt; margin-bottom: 10pt; border-left: 3pt solid #27AE60;">
<div style="flex: 1;">
<p style="font-size: 9.5pt; font-weight: 600; color: #1a1a1a; margin-bottom: 3pt;">Google FCM (푸시알림)</p>
<p style="font-size: 8pt; color: #999;">무제한</p>
</div>
<div style="text-align: right;">
<p style="font-size: 9.5pt; font-weight: 700; color: #27AE60;">무료</p>
<p style="font-size: 7.5pt; color: #27AE60; font-weight: 500; margin-top: 2pt;">완전 무료</p>
</div>
</div>
<!-- 요약 박스 -->
<div style="flex: 1; background: #f5f5f0; border-radius: 8pt; padding: 10pt 12pt; display: flex; flex-direction: column; justify-content: center;">
<p style="font-size: 8pt; font-weight: 700; color: #1a1a1a; margin-bottom: 4pt;">핵심 인사이트</p>
<p style="font-size: 8pt; color: #666; line-height: 1.6;">LLM 토큰 비용은 건당 1원 미만 수준. 클라우드 인프라 비용도 무시 가능한 수준으로, AI 기능이 수익 마진에 미치는 영향이 극히 작음.</p>
</div>
</div>
</div>
<!-- 하단 바 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding: 7pt 12pt; background: #1a0a0a; border-radius: 4pt; margin-top: 8pt;">
<p style="font-size: 8pt; color: rgba(255,255,255,0.5);">ai_pricing_configs 테이블에서 동적 관리</p>
<p style="font-size: 8pt; color: rgba(255,255,255,0.5);">캐시 TTL 1시간</p>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 7pt; margin-top: 6pt;">
<p style="font-size: 8pt; color: #999;">SAM 내부 과금정책 | CONFIDENTIAL</p>
<p style="font-size: 8pt; color: #999;">04</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,115 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #f5f5f0;
padding: 22pt 40pt 14pt;
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12pt;">
<div style="display: flex; align-items: center; gap: 12pt;">
<div style="display: inline-block; padding: 4pt 10pt; background: #1a0a0a; border-radius: 4pt;">
<p style="color: #E74C3C; font-size: 8pt; font-weight: 600;">MARGIN</p>
</div>
<h2 style="font-size: 20pt; font-weight: 700; color: #1a1a1a;">마진 구조 + 가격 책정 배경</h2>
</div>
<p style="font-size: 10pt; color: #999;">05</p>
</div>
<!-- 2컬럼 카드 -->
<div style="flex: 1; display: flex; gap: 16pt;">
<!-- 좌측: 마진 구조 (다크) -->
<div style="flex: 1; background: #1a0a0a; border-radius: 10pt; padding: 14pt; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<p style="font-size: 8pt; color: #E74C3C; font-weight: 600; letter-spacing: 0.06em; margin-bottom: 6pt;">MARGIN STRUCTURE</p>
<p style="font-size: 11pt; font-weight: 500; color: rgba(255,255,255,0.5); margin-bottom: 2pt;">회사 영업이익률</p>
<p style="font-size: 38pt; font-weight: 800; color: #ffffff; letter-spacing: -0.02em;">67~75%</p>
</div>
<div style="display: flex; flex-direction: column; gap: 6pt; margin-top: 12pt;">
<div style="display: flex; justify-content: space-between; align-items: center; padding: 8pt 10pt; background: rgba(255,255,255,0.06); border-radius: 4pt;">
<p style="font-size: 9pt; color: rgba(255,255,255,0.5);">개인 가입</p>
<p style="font-size: 9pt; font-weight: 600; color: #ffffff;">72~75%<span style="font-size: 8pt; font-weight: 400; color: rgba(255,255,255,0.35);"> (수당 25~28%)</span></p>
</div>
<div style="display: flex; justify-content: space-between; align-items: center; padding: 8pt 10pt; background: rgba(255,255,255,0.06); border-radius: 4pt;">
<p style="font-size: 9pt; color: rgba(255,255,255,0.5);">단체 가입</p>
<p style="font-size: 9pt; font-weight: 600; color: #ffffff;">~67%<span style="font-size: 8pt; font-weight: 400; color: rgba(255,255,255,0.35);"> (수당 33%)</span></p>
</div>
</div>
<div style="padding: 6pt 10pt; background: rgba(39,174,96,0.12); border-radius: 4pt; margin-top: 10pt;">
<p style="font-size: 8pt; color: #27AE60; font-weight: 600;">SaaS 업계 평균 마진 60% 대비 높은 수익성</p>
</div>
</div>
<!-- 우측: 가격 책정 배경 -->
<div style="flex: 1; background: #ffffff; border-radius: 10pt; padding: 14pt; border: 1pt solid #e5e5e0; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<p style="font-size: 8pt; color: #666; font-weight: 600; letter-spacing: 0.06em; margin-bottom: 6pt;">PRICE BACKGROUND</p>
<p style="font-size: 11pt; font-weight: 500; color: #666; margin-bottom: 2pt;">내부 총 개발비 산정</p>
<p style="font-size: 38pt; font-weight: 800; color: #1a1a1a; letter-spacing: -0.02em;">7,600<span style="font-size: 18pt; font-weight: 500;">만원</span></p>
</div>
<div style="display: flex; flex-direction: column; gap: 5pt; margin-top: 12pt;">
<div style="display: flex; align-items: center; gap: 6pt; padding: 6pt 10pt; background: #fafafa; border-radius: 4pt;">
<div style="width: 3pt; height: 3pt; background: #1a1a1a; border-radius: 50%; flex-shrink: 0;"></div>
<p style="font-size: 8.5pt; color: #666;">개발비 2,000만원 + 장기 구독 약 7년</p>
</div>
<div style="display: flex; align-items: center; gap: 6pt; padding: 6pt 10pt; background: #fafafa; border-radius: 4pt;">
<div style="width: 3pt; height: 3pt; background: #1a1a1a; border-radius: 50%; flex-shrink: 0;"></div>
<p style="font-size: 8.5pt; color: #666;">금융 비용 4.6% 포함</p>
</div>
<div style="display: flex; align-items: center; gap: 6pt; padding: 6pt 10pt; background: #fafafa; border-radius: 4pt;">
<div style="width: 3pt; height: 3pt; background: #1a1a1a; border-radius: 50%; flex-shrink: 0;"></div>
<p style="font-size: 8.5pt; color: #666;">중소기업 초기 투자 부담 분산 구조</p>
</div>
</div>
</div>
</div>
<!-- 월간 예상 바 -->
<div style="margin-top: 8pt; background: #ffffff; border-radius: 6pt; padding: 8pt 16pt; border: 1pt solid #e5e5e0;">
<p style="font-size: 8pt; font-weight: 700; color: #666; margin-bottom: 4pt;">본사 지출 월간 예상 (테넌트 1개)</p>
<div style="display: flex; gap: 12pt; align-items: center;">
<div style="flex: 1; padding: 6pt 8pt; background: #f0faf4; border-radius: 4pt; text-align: center;">
<p style="font-size: 7pt; color: #999; margin-bottom: 2pt;">바로빌 홈택스</p>
<p style="font-size: 10pt; font-weight: 700; color: #27AE60;">0원</p>
</div>
<div style="flex: 1; padding: 6pt 8pt; background: #fafafa; border-radius: 4pt; text-align: center;">
<p style="font-size: 7pt; color: #999; margin-bottom: 2pt;">세금계산서</p>
<p style="font-size: 10pt; font-weight: 700; color: #1a1a1a;">5,000~10,000원</p>
</div>
<div style="flex: 1; padding: 6pt 8pt; background: #fafafa; border-radius: 4pt; text-align: center;">
<p style="font-size: 7pt; color: #999; margin-bottom: 2pt;">AI 토큰</p>
<p style="font-size: 10pt; font-weight: 700; color: #1a1a1a;">100~5,000원</p>
</div>
<div style="flex: 1; padding: 6pt 8pt; background: #fafafa; border-radius: 4pt; text-align: center;">
<p style="font-size: 7pt; color: #999; margin-bottom: 2pt;">GCS/STT</p>
<p style="font-size: 10pt; font-weight: 700; color: #1a1a1a;">50~2,000원</p>
</div>
<div style="width: 1pt; height: 28pt; background: #e5e5e0;"></div>
<div style="padding: 6pt 10pt; background: #1a0a0a; border-radius: 4pt; text-align: center;">
<p style="font-size: 7pt; color: rgba(255,255,255,0.5); margin-bottom: 2pt;">합계 최대</p>
<p style="font-size: 10pt; font-weight: 700; color: #E74C3C;">~17,000원<span style="font-size: 7pt; font-weight: 400; color: rgba(255,255,255,0.4);">/월</span></p>
</div>
</div>
<div style="margin-top: 6pt; padding: 4pt 8pt; background: #fdedef; border-radius: 3pt; text-align: center;">
<p style="font-size: 8pt; color: #C0392B; font-weight: 600;">구독료 50만원 대비 원가율 3.4% — 스케일 시 한계비용 0에 수렴</p>
</div>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 5pt; margin-top: 4pt;">
<p style="font-size: 8pt; color: #999;">SAM 내부 과금정책 | CONFIDENTIAL</p>
<p style="font-size: 8pt; color: #999;">05</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #ffffff;
padding: 28pt 40pt;
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12pt;">
<div style="display: flex; align-items: center; gap: 12pt;">
<div style="display: inline-block; padding: 4pt 10pt; background: #1a0a0a; border-radius: 4pt;">
<p style="color: #E74C3C; font-size: 8pt; font-weight: 600;">CODE REF</p>
</div>
<h2 style="font-size: 20pt; font-weight: 700; color: #1a1a1a;">코드 참조 — 소스 파일</h2>
</div>
<p style="font-size: 10pt; color: #999;">06</p>
</div>
<!-- 2컬럼 -->
<div style="flex: 1; display: flex; gap: 18pt;">
<!-- 좌측: 바로빌 과금 -->
<div style="flex: 1; display: flex; flex-direction: column;">
<div style="display: flex; align-items: center; gap: 6pt; margin-bottom: 8pt;">
<div style="width: 10pt; height: 10pt; background: #E74C3C; border-radius: 2pt;"></div>
<p style="font-size: 10pt; font-weight: 700; color: #1a1a1a;">바로빌 과금</p>
<div style="display: inline-block; padding: 2pt 6pt; background: #fdedef; border-radius: 3pt;">
<p style="font-size: 7pt; color: #C0392B;">6개 파일</p>
</div>
</div>
<div style="display: flex; flex-direction: column; gap: 4pt;">
<div style="padding: 7pt 10pt; background: #fafafa; border-radius: 4pt; border-left: 2pt solid #E74C3C;">
<p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">BarobillSubscription.php</p>
<p style="font-size: 7pt; color: #888;">DEFAULT_MONTHLY_FEES 상수</p>
</div>
<div style="padding: 7pt 10pt; background: #fafafa; border-radius: 4pt; border-left: 2pt solid #E74C3C;">
<p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">BarobillBillingRecord.php</p>
<p style="font-size: 7pt; color: #888;">USAGE_UNIT_PRICES 상수</p>
</div>
<div style="padding: 7pt 10pt; background: #fafafa; border-radius: 4pt; border-left: 2pt solid #E74C3C;">
<p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">BarobillPricingPolicy.php</p>
<p style="font-size: 7pt; color: #888;">calculateBilling() 메서드</p>
</div>
<div style="padding: 7pt 10pt; background: #fafafa; border-radius: 4pt; border-left: 2pt solid #E74C3C;">
<p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">BarobillBillingService.php</p>
<p style="font-size: 7pt; color: #888;">월정액/건별 과금 처리</p>
</div>
<div style="padding: 7pt 10pt; background: #fafafa; border-radius: 4pt; border-left: 2pt solid #E74C3C;">
<p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">BarobillUsageService.php</p>
<p style="font-size: 7pt; color: #888;">사용량 집계</p>
</div>
<div style="padding: 7pt 10pt; background: #fafafa; border-radius: 4pt; border-left: 2pt solid #E74C3C;">
<p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">BarobillPricingPolicySeeder.php</p>
<p style="font-size: 7pt; color: #888;">5개 정책 시더</p>
</div>
</div>
</div>
<!-- 우측: AI 가격/토큰 -->
<div style="flex: 1; display: flex; flex-direction: column;">
<div style="display: flex; align-items: center; gap: 6pt; margin-bottom: 8pt;">
<div style="width: 10pt; height: 10pt; background: #1a0a0a; border-radius: 2pt;"></div>
<p style="font-size: 10pt; font-weight: 700; color: #1a1a1a;">AI 가격/토큰</p>
<div style="display: inline-block; padding: 2pt 6pt; background: #f5f5f0; border-radius: 3pt;">
<p style="font-size: 7pt; color: #999;">5개 파일</p>
</div>
</div>
<div style="display: flex; flex-direction: column; gap: 4pt;">
<div style="padding: 7pt 10pt; background: #fafafa; border-radius: 4pt; border-left: 2pt solid #1a0a0a;">
<p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">AiPricingConfig.php</p>
<p style="font-size: 7pt; color: #888;">getActivePricing()</p>
</div>
<div style="padding: 7pt 10pt; background: #fafafa; border-radius: 4pt; border-left: 2pt solid #1a0a0a;">
<p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">AiTokenUsage.php</p>
<p style="font-size: 7pt; color: #888;">토큰 사용량 기록</p>
</div>
<div style="padding: 7pt 10pt; background: #fafafa; border-radius: 4pt; border-left: 2pt solid #1a0a0a;">
<p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">AiReportService.php</p>
<p style="font-size: 7pt; color: #888;">saveTokenUsage()</p>
</div>
<div style="padding: 7pt 10pt; background: #fafafa; border-radius: 4pt; border-left: 2pt solid #1a0a0a;">
<p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">ai_pricing_configs 마이그레이션</p>
<p style="font-size: 7pt; color: #888;">AI 단가 테이블</p>
</div>
<div style="padding: 7pt 10pt; background: #fafafa; border-radius: 4pt; border-left: 2pt solid #1a0a0a;">
<p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">ai_token_usages 마이그레이션</p>
<p style="font-size: 7pt; color: #888;">토큰 사용량 테이블</p>
</div>
</div>
<!-- 공간 활용: 참고 -->
<div style="margin-top: auto; padding: 8pt 10pt; background: #f5f5f0; border-radius: 6pt;">
<p style="font-size: 7.5pt; color: #666; line-height: 1.5;">모든 과금 상수와 정책은 소스 코드에 정의되며, DB 시더/마이그레이션으로 초기 데이터가 관리됩니다.</p>
</div>
</div>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 8pt; border-top: 1pt solid #eee; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">SAM 내부 과금정책 | CONFIDENTIAL</p>
<p style="font-size: 8pt; color: #999;">06</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,128 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #ffffff;
padding: 26pt 40pt;
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 14pt;">
<div style="display: flex; align-items: center; gap: 12pt;">
<div style="display: inline-block; padding: 4pt 10pt; background: #1a0a0a; border-radius: 4pt;">
<p style="color: #E74C3C; font-size: 8pt; font-weight: 600;">CODE REF</p>
</div>
<h2 style="font-size: 20pt; font-weight: 700; color: #1a1a1a;">코드 참조 — DB 테이블</h2>
</div>
<p style="font-size: 10pt; color: #999;">07</p>
</div>
<!-- DB 테이블 리스트 (div+flexbox) -->
<div style="flex: 1; display: flex; flex-direction: column; gap: 5pt;">
<!-- 헤더 행 -->
<div style="display: flex; padding: 8pt 14pt; background: #1a0a0a; border-radius: 4pt;">
<div style="flex: 1.2;"><p style="font-size: 9pt; font-weight: 600; color: #E74C3C;">테이블</p></div>
<div style="flex: 0.4; text-align: center;"><p style="font-size: 9pt; font-weight: 600; color: rgba(255,255,255,0.5);">카테고리</p></div>
<div style="flex: 1.4;"><p style="font-size: 9pt; font-weight: 600; color: #ffffff;">설명</p></div>
</div>
<!-- barobill_subscriptions -->
<div style="display: flex; padding: 8pt 14pt; background: #fafafa; border-radius: 4pt; border-left: 3pt solid #E74C3C;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">barobill_subscriptions</p></div>
<div style="flex: 0.4; text-align: center;">
<div style="display: inline-block; padding: 1pt 6pt; background: #fdedef; border-radius: 2pt;">
<p style="font-size: 6.5pt; color: #C0392B; font-weight: 600;">바로빌</p>
</div>
</div>
<div style="flex: 1.4;"><p style="font-size: 8.5pt; color: #666;">바로빌 월정액 구독 현황</p></div>
</div>
<!-- barobill_billing_records -->
<div style="display: flex; padding: 8pt 14pt; background: #fff; border-radius: 4pt; border-left: 3pt solid #E74C3C;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">barobill_billing_records</p></div>
<div style="flex: 0.4; text-align: center;">
<div style="display: inline-block; padding: 1pt 6pt; background: #fdedef; border-radius: 2pt;">
<p style="font-size: 6.5pt; color: #C0392B; font-weight: 600;">바로빌</p>
</div>
</div>
<div style="flex: 1.4;"><p style="font-size: 8.5pt; color: #666;">바로빌 월별 과금 내역</p></div>
</div>
<!-- barobill_pricing_policies -->
<div style="display: flex; padding: 8pt 14pt; background: #fafafa; border-radius: 4pt; border-left: 3pt solid #E74C3C;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">barobill_pricing_policies</p></div>
<div style="flex: 0.4; text-align: center;">
<div style="display: inline-block; padding: 1pt 6pt; background: #fdedef; border-radius: 2pt;">
<p style="font-size: 6.5pt; color: #C0392B; font-weight: 600;">바로빌</p>
</div>
</div>
<div style="flex: 1.4;"><p style="font-size: 8.5pt; color: #666;">과금 정책 (무료 제공량, 추가 단가)</p></div>
</div>
<!-- ai_pricing_configs -->
<div style="display: flex; padding: 8pt 14pt; background: #fff; border-radius: 4pt; border-left: 3pt solid #1a0a0a;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">ai_pricing_configs</p></div>
<div style="flex: 0.4; text-align: center;">
<div style="display: inline-block; padding: 1pt 6pt; background: #f5f5f0; border-radius: 2pt;">
<p style="font-size: 6.5pt; color: #666; font-weight: 600;">AI</p>
</div>
</div>
<div style="flex: 1.4;"><p style="font-size: 8.5pt; color: #666;">AI 제공자별 단가 설정</p></div>
</div>
<!-- ai_token_usages -->
<div style="display: flex; padding: 8pt 14pt; background: #fafafa; border-radius: 4pt; border-left: 3pt solid #1a0a0a;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">ai_token_usages</p></div>
<div style="flex: 0.4; text-align: center;">
<div style="display: inline-block; padding: 1pt 6pt; background: #f5f5f0; border-radius: 2pt;">
<p style="font-size: 6.5pt; color: #666; font-weight: 600;">AI</p>
</div>
</div>
<div style="flex: 1.4;"><p style="font-size: 8.5pt; color: #666;">AI 토큰 사용량 기록</p></div>
</div>
<!-- ai_voice_recordings -->
<div style="display: flex; padding: 8pt 14pt; background: #fff; border-radius: 4pt; border-left: 3pt solid #1a0a0a;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">ai_voice_recordings</p></div>
<div style="flex: 0.4; text-align: center;">
<div style="display: inline-block; padding: 1pt 6pt; background: #f5f5f0; border-radius: 2pt;">
<p style="font-size: 6.5pt; color: #666; font-weight: 600;">AI</p>
</div>
</div>
<div style="flex: 1.4;"><p style="font-size: 8.5pt; color: #666;">AI 음성 녹음 (STT 비용 발생)</p></div>
</div>
<!-- sales_commissions -->
<div style="display: flex; padding: 8pt 14pt; background: #fafafa; border-radius: 4pt; border-left: 3pt solid #D97706;">
<div style="flex: 1.2;"><p style="font-size: 8.5pt; font-weight: 600; color: #1a1a1a;">sales_commissions</p></div>
<div style="flex: 0.4; text-align: center;">
<div style="display: inline-block; padding: 1pt 6pt; background: #fff8e1; border-radius: 2pt;">
<p style="font-size: 6.5pt; color: #D97706; font-weight: 600;">영업</p>
</div>
</div>
<div style="flex: 1.4;"><p style="font-size: 8.5pt; color: #666;">영업수수료 정산</p></div>
</div>
</div>
<!-- 하단 참고 -->
<div style="padding: 8pt 14pt; background: #f5f5f0; border-radius: 6pt; margin-top: 8pt;">
<p style="font-size: 8pt; color: #666; line-height: 1.5;">모든 테이블은 tenant_id 기반 Multi-tenant 구조이며, API 프로젝트(/home/aweso/sam/api)에서 마이그레이션을 관리합니다.</p>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 8pt; border-top: 1pt solid #eee; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">SAM 내부 과금정책 | CONFIDENTIAL</p>
<p style="font-size: 8pt; color: #999;">07</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #1B3A5C;
padding: 36pt 48pt 28pt 48pt;
display: flex;
flex-direction: column;
justify-content: space-between;
}
</style>
</head>
<body>
<!-- 상단: 로고 + 뱃지 -->
<div style="display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; align-items: center; gap: 10pt;">
<img src="/home/aweso/sam/docs/assets/bi/sam_bi_blue.png" style="width: 28pt; height: 28pt;">
<p style="font-size: 14pt; font-weight: 700; color: #ffffff;">SAM</p>
</div>
<div style="display: inline-block; padding: 5pt 14pt; border: 1px solid rgba(255,255,255,0.3); border-radius: 16pt;">
<p style="font-size: 9pt; font-weight: 500; color: rgba(255,255,255,0.7); letter-spacing: 0.05em;">SERVICE PRICING 2026</p>
</div>
</div>
<!-- 메인 타이틀 -->
<div>
<p style="font-size: 11pt; font-weight: 600; color: #2E86AB; letter-spacing: 0.06em; margin-bottom: 10pt;">SMART AUTOMATION MANAGEMENT</p>
<h1 style="font-size: 48pt; font-weight: 800; color: #ffffff; letter-spacing: -0.02em; line-height: 1.15;">SAM 서비스 요금 안내</h1>
<p style="font-size: 14pt; color: rgba(255,255,255,0.55); margin-top: 12pt; line-height: 1.5;">제조 현장의 디지털 전환, SAM 하나로 완성합니다</p>
</div>
<!-- 키 벨류 3카드 -->
<div style="display: flex; gap: 14pt;">
<div style="flex: 1; background: rgba(46,134,171,0.18); border: 1pt solid rgba(46,134,171,0.35); border-radius: 10pt; padding: 14pt 16pt; text-align: center;">
<p style="font-size: 24pt; font-weight: 800; color: #ffffff; margin-bottom: 2pt;">80%<span style="font-size: 13pt; color: #2E86AB;"> UP</span></p>
<p style="font-size: 9pt; color: rgba(255,255,255,0.6);">업무 자동화율 향상</p>
</div>
<div style="flex: 1; background: rgba(232,111,44,0.15); border: 1pt solid rgba(232,111,44,0.35); border-radius: 10pt; padding: 14pt 16pt; text-align: center;">
<p style="font-size: 24pt; font-weight: 800; color: #ffffff; margin-bottom: 2pt;">30%<span style="font-size: 13pt; color: #E86F2C;"> DOWN</span></p>
<p style="font-size: 9pt; color: rgba(255,255,255,0.6);">인건비 절감 효과</p>
</div>
<div style="flex: 1; background: rgba(255,255,255,0.08); border: 1pt solid rgba(255,255,255,0.2); border-radius: 10pt; padding: 14pt 16pt; text-align: center;">
<p style="font-size: 24pt; font-weight: 800; color: #ffffff; margin-bottom: 2pt;">100%</p>
<p style="font-size: 9pt; color: rgba(255,255,255,0.6);">실시간 현황 파악</p>
</div>
</div>
<!-- 하단 정보 -->
<div style="display: flex; gap: 48pt; align-items: flex-end;">
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.3); margin-bottom: 3pt; letter-spacing: 0.04em;">COMPANY</p>
<p style="font-size: 11pt; font-weight: 500; color: rgba(255,255,255,0.8);">(주)코드브릿지엑스</p>
</div>
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.3); margin-bottom: 3pt; letter-spacing: 0.04em;">DATE</p>
<p style="font-size: 11pt; font-weight: 500; color: rgba(255,255,255,0.8);">2026. 02</p>
</div>
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.3); margin-bottom: 3pt; letter-spacing: 0.04em;">NOTE</p>
<p style="font-size: 11pt; font-weight: 600; color: #E86F2C;">VAT 별도</p>
</div>
<div style="margin-left: auto;">
<p style="font-size: 8pt; color: rgba(255,255,255,0.3);">01 / 07</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #f7f9fc;
padding: 36pt 48pt 24pt 48pt;
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<!-- 상단 2단: 좌측 타이틀, 우측 목차 -->
<div style="flex: 1; display: flex; gap: 36pt;">
<!-- 좌측: Contents 타이틀 -->
<div style="width: 180pt; display: flex; flex-direction: column; justify-content: center;">
<div style="display: inline-block; padding: 4pt 10pt; background: #1B3A5C; border-radius: 4pt; margin-bottom: 16pt; width: fit-content;">
<p style="color: #fff; font-size: 8pt; font-weight: 600; letter-spacing: 0.06em;">CONTENTS</p>
</div>
<h1 style="font-size: 38pt; font-weight: 800; color: #1B3A5C; letter-spacing: -0.02em; line-height: 1.15;">목차</h1>
<p style="font-size: 10pt; color: #5a6b7d; margin-top: 10pt; line-height: 1.5;">SAM 서비스의 투명한 요금 체계를 한눈에 확인하세요</p>
</div>
<!-- 우측: 목차 리스트 -->
<div style="flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 10pt;">
<!-- 01 -->
<div style="display: flex; align-items: center; gap: 14pt; padding: 16pt 18pt; background: #ffffff; border-radius: 8pt; border-left: 3pt solid #E86F2C;">
<div style="display: inline-block; padding: 5pt 10pt; background: #1B3A5C; border-radius: 5pt;">
<p style="color: #fff; font-size: 9pt; font-weight: 700;">01</p>
</div>
<div style="flex: 1;">
<p style="font-size: 13pt; font-weight: 700; color: #1B3A5C;">기본 서비스 요금</p>
<p style="font-size: 9pt; color: #5a6b7d; margin-top: 2pt;">제조업 패키지, 개별 모듈, 통합 패키지</p>
</div>
</div>
<!-- 02 -->
<div style="display: flex; align-items: center; gap: 14pt; padding: 16pt 18pt; background: #ffffff; border-radius: 8pt; border-left: 3pt solid #2E86AB;">
<div style="display: inline-block; padding: 5pt 10pt; background: #1B3A5C; border-radius: 5pt;">
<p style="color: #fff; font-size: 9pt; font-weight: 700;">02</p>
</div>
<div style="flex: 1;">
<p style="font-size: 13pt; font-weight: 700; color: #1B3A5C;">추가 옵션 요금</p>
<p style="font-size: 9pt; color: #5a6b7d; margin-top: 2pt;">생산공정 추가, 품질관리, 챗봇, 연구노트</p>
</div>
</div>
<!-- 03 -->
<div style="display: flex; align-items: center; gap: 14pt; padding: 16pt 18pt; background: #ffffff; border-radius: 8pt; border-left: 3pt solid #2E86AB;">
<div style="display: inline-block; padding: 5pt 10pt; background: #1B3A5C; border-radius: 5pt;">
<p style="color: #fff; font-size: 9pt; font-weight: 700;">03</p>
</div>
<div style="flex: 1;">
<p style="font-size: 13pt; font-weight: 700; color: #1B3A5C;">사용량 기반 과금</p>
<p style="font-size: 9pt; color: #5a6b7d; margin-top: 2pt;">파일 저장 공간, AI 토큰 사용량</p>
</div>
</div>
<!-- 04 -->
<div style="display: flex; align-items: center; gap: 14pt; padding: 16pt 18pt; background: #ffffff; border-radius: 8pt; border-left: 3pt solid #2E86AB;">
<div style="display: inline-block; padding: 5pt 10pt; background: #1B3A5C; border-radius: 5pt;">
<p style="color: #fff; font-size: 9pt; font-weight: 700;">04</p>
</div>
<div style="flex: 1;">
<p style="font-size: 13pt; font-weight: 700; color: #1B3A5C;">바로빌 부가서비스</p>
<p style="font-size: 9pt; color: #5a6b7d; margin-top: 2pt;">계좌조회, 카드내역, 세금계산서 발행</p>
</div>
</div>
</div>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 10pt; border-top: 1pt solid #e2e8f0; margin-top: 10pt;">
<p style="font-size: 8pt; color: #999;">SAM 서비스 요금 안내 | (주)코드브릿지엑스</p>
<p style="font-size: 8pt; color: #999;">02 / 07</p>
<p style="font-size: 8pt; color: #E86F2C; font-weight: 500;">모든 금액 VAT 별도</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,131 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #ffffff;
padding: 28pt 36pt 20pt 36pt;
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 14pt;">
<div style="display: flex; align-items: center; gap: 10pt;">
<div style="display: inline-block; padding: 3pt 9pt; background: #2E86AB; border-radius: 4pt;">
<p style="color: #fff; font-size: 7pt; font-weight: 600;">SECTION 01</p>
</div>
<h2 style="font-size: 20pt; font-weight: 700; color: #1B3A5C;">기본 서비스 요금</h2>
</div>
<p style="font-size: 9pt; color: #999;">03 / 07</p>
</div>
<!-- 콘텐츠: 2단 -->
<div style="flex: 1; display: flex; gap: 16pt;">
<!-- 좌측: 제조업 기본 패키지 카드 -->
<div style="width: 240pt; background: #f7f9fc; border-radius: 10pt; padding: 16pt; display: flex; flex-direction: column; justify-content: space-between; border: 1pt solid #e2e8f0;">
<div>
<div style="display: flex; align-items: center; gap: 8pt; margin-bottom: 10pt;">
<div style="display: inline-block; padding: 3pt 8pt; background: #E86F2C; border-radius: 3pt;">
<p style="color: #fff; font-size: 7pt; font-weight: 700;">BEST SELLER</p>
</div>
<div style="display: inline-block; padding: 3pt 8pt; background: #1B3A5C; border-radius: 3pt;">
<p style="color: #fff; font-size: 7pt; font-weight: 600;">BASIC</p>
</div>
</div>
<h3 style="font-size: 16pt; font-weight: 700; color: #1B3A5C; margin-bottom: 8pt;">제조업 기본 패키지</h3>
<p style="font-size: 9pt; color: #5a6b7d; line-height: 1.6;">품목관리 → 견적 → 수주 → 생산 → 출하</p>
<div style="margin-top: 8pt; padding: 6pt 10pt; background: rgba(46,134,171,0.1); border-radius: 5pt;">
<p style="font-size: 9pt; font-weight: 600; color: #2E86AB;">ERP 인사/회계 무료 포함</p>
</div>
</div>
<div>
<div style="display: flex; gap: 10pt; margin-top: 12pt;">
<div style="flex: 1; background: #1B3A5C; border-radius: 8pt; padding: 12pt; text-align: center;">
<p style="font-size: 7pt; color: rgba(255,255,255,0.6); margin-bottom: 3pt;">개발비 (1회)</p>
<p style="font-size: 18pt; font-weight: 700; color: #ffffff;">2,000<span style="font-size: 10pt; font-weight: 400;">만원</span></p>
</div>
<div style="flex: 1; background: #ffffff; border-radius: 8pt; padding: 12pt; text-align: center; border: 1pt solid #e2e8f0;">
<p style="font-size: 7pt; color: #999; margin-bottom: 3pt;">구독료 (월)</p>
<p style="font-size: 18pt; font-weight: 700; color: #E86F2C;">50<span style="font-size: 10pt; font-weight: 400;">만원</span></p>
</div>
</div>
<div style="margin-top: 8pt; text-align: center;">
<p style="font-size: 8pt; color: #2E86AB; font-weight: 500;">하루 약 1.6만원으로 제조 ERP 완성</p>
</div>
</div>
</div>
<!-- 우측: 개별 모듈 + 통합 패키지 -->
<div style="flex: 1; display: flex; flex-direction: column; gap: 10pt;">
<!-- 개별 모듈 타이틀 -->
<p style="font-size: 9pt; font-weight: 600; color: #5a6b7d; letter-spacing: 0.03em;">개별 모듈</p>
<!-- 헤더 행 -->
<div style="display: flex; background: #1B3A5C; border-radius: 5pt 5pt 0 0; padding: 5pt 10pt;">
<div style="flex: 1.2;"><p style="font-size: 8pt; font-weight: 600; color: #fff;">모듈명</p></div>
<div style="flex: 1; text-align: right;"><p style="font-size: 8pt; font-weight: 600; color: #fff;">개발비</p></div>
<div style="flex: 0.7; text-align: right;"><p style="font-size: 8pt; font-weight: 600; color: #fff;">구독/월</p></div>
</div>
<!-- 행1 -->
<div style="display: flex; background: #f7f9fc; padding: 5pt 10pt; margin-top: -10pt;">
<div style="flex: 1.2;"><p style="font-size: 8pt; color: #1e2a3a;">QR코드 관리</p></div>
<div style="flex: 1; text-align: right;"><p style="font-size: 8pt; font-weight: 600; color: #1e2a3a;">1,020만원</p></div>
<div style="flex: 0.7; text-align: right;"><p style="font-size: 8pt; color: #5a6b7d;">5만원</p></div>
</div>
<!-- 행2 -->
<div style="display: flex; background: #ffffff; padding: 5pt 10pt; margin-top: -10pt;">
<div style="flex: 1.2;"><p style="font-size: 8pt; color: #1e2a3a;">사진/출하 관리</p></div>
<div style="flex: 1; text-align: right;"><p style="font-size: 8pt; font-weight: 600; color: #1e2a3a;">1,920만원</p></div>
<div style="flex: 0.7; text-align: right;"><p style="font-size: 8pt; color: #5a6b7d;">10만원</p></div>
</div>
<!-- 행3 -->
<div style="display: flex; background: #f7f9fc; padding: 5pt 10pt; margin-top: -10pt;">
<div style="flex: 1.2;"><p style="font-size: 8pt; color: #1e2a3a;">검사/토큰 적용</p></div>
<div style="flex: 1; text-align: right;"><p style="font-size: 8pt; font-weight: 600; color: #1e2a3a;">1,020만원</p></div>
<div style="flex: 0.7; text-align: right;"><p style="font-size: 8pt; color: #5a6b7d;">5만원</p></div>
</div>
<!-- 행4 -->
<div style="display: flex; background: #ffffff; padding: 5pt 10pt; margin-top: -10pt; border-radius: 0 0 5pt 5pt;">
<div style="flex: 1.2;"><p style="font-size: 8pt; color: #1e2a3a;">이카운트 연동</p></div>
<div style="flex: 1; text-align: right;"><p style="font-size: 8pt; font-weight: 600; color: #1e2a3a;">1,920만원</p></div>
<div style="flex: 0.7; text-align: right;"><p style="font-size: 8pt; color: #5a6b7d;">10만원</p></div>
</div>
<!-- 통합 패키지 타이틀 -->
<p style="font-size: 9pt; font-weight: 600; color: #5a6b7d; letter-spacing: 0.03em; margin-top: 4pt;">통합 패키지</p>
<!-- 헤더 행 -->
<div style="display: flex; background: #2E86AB; border-radius: 5pt 5pt 0 0; padding: 5pt 10pt;">
<div style="flex: 1.2;"><p style="font-size: 8pt; font-weight: 600; color: #fff;">패키지명</p></div>
<div style="flex: 1; text-align: right;"><p style="font-size: 8pt; font-weight: 600; color: #fff;">개발비</p></div>
<div style="flex: 0.7; text-align: right;"><p style="font-size: 8pt; font-weight: 600; color: #fff;">구독/월</p></div>
</div>
<!-- 행1 -->
<div style="display: flex; background: #f0f7fa; padding: 5pt 10pt; margin-top: -10pt;">
<div style="flex: 1.2;"><p style="font-size: 8pt; font-weight: 500; color: #1e2a3a;">공사관리 패키지</p></div>
<div style="flex: 1; text-align: right;"><p style="font-size: 8pt; font-weight: 700; color: #1B3A5C;">4,000만원</p></div>
<div style="flex: 0.7; text-align: right;"><p style="font-size: 8pt; color: #5a6b7d;">20만원</p></div>
</div>
<!-- 행2 -->
<div style="display: flex; background: #ffffff; padding: 5pt 10pt; margin-top: -10pt; border-radius: 0 0 5pt 5pt;">
<div style="flex: 1.2;"><p style="font-size: 8pt; font-weight: 500; color: #1e2a3a;">공정/정부지원사업</p></div>
<div style="flex: 1; text-align: right;"><p style="font-size: 8pt; font-weight: 700; color: #1B3A5C;">8,000만원</p></div>
<div style="flex: 0.7; text-align: right;"><p style="font-size: 8pt; color: #5a6b7d;">40만원</p></div>
</div>
</div>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 8pt; border-top: 1pt solid #e2e8f0; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">SAM 서비스 요금 안내 | (주)코드브릿지엑스</p>
<p style="font-size: 8pt; color: #E86F2C; font-weight: 500;">모든 금액 VAT 별도</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,163 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #ffffff;
padding: 28pt 36pt 20pt 36pt;
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 14pt;">
<div style="display: flex; align-items: center; gap: 10pt;">
<div style="display: inline-block; padding: 3pt 9pt; background: #2E86AB; border-radius: 4pt;">
<p style="color: #fff; font-size: 7pt; font-weight: 600;">SECTION 02</p>
</div>
<h2 style="font-size: 20pt; font-weight: 700; color: #1B3A5C;">추가 옵션 요금</h2>
</div>
<p style="font-size: 9pt; color: #999;">04 / 07</p>
</div>
<!-- 옵션 카드 그리드: 3열 2행 -->
<div style="flex: 1; display: flex; flex-direction: column; gap: 10pt;">
<!-- 1행 -->
<div style="display: flex; gap: 10pt; flex: 1;">
<!-- 카드1: 생산공정 -->
<div style="flex: 1; background: #f7f9fc; border-radius: 8pt; padding: 14pt; border: 1pt solid #e2e8f0; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<p style="font-size: 11pt; font-weight: 700; color: #1B3A5C; margin-bottom: 4pt;">생산공정 1개 추가</p>
<p style="font-size: 8pt; color: #5a6b7d; line-height: 1.4;">생산 라인별 개별 공정 확장</p>
</div>
<div>
<div style="display: flex; justify-content: space-between; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">개발비</p>
<p style="font-size: 10pt; font-weight: 700; color: #1B3A5C;">500만원</p>
</div>
<div style="display: flex; justify-content: space-between; margin-top: 3pt;">
<p style="font-size: 8pt; color: #999;">구독/월</p>
<p style="font-size: 10pt; font-weight: 600; color: #E86F2C;">10만원</p>
</div>
</div>
</div>
<!-- 카드2: 품질관리 -->
<div style="flex: 1; background: #1B3A5C; border-radius: 8pt; padding: 14pt; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<div style="display: flex; align-items: center; gap: 6pt; margin-bottom: 4pt;">
<p style="font-size: 11pt; font-weight: 700; color: #ffffff;">품질관리 (인정검사)</p>
</div>
<div style="display: inline-block; padding: 2pt 7pt; background: #E86F2C; border-radius: 3pt; margin-bottom: 2pt;">
<p style="font-size: 7pt; font-weight: 600; color: #fff;">품질 인증 필수!</p>
</div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.6); line-height: 1.4;">ISO 인증 대응 필수 모듈</p>
</div>
<div>
<div style="display: flex; justify-content: space-between; margin-top: 8pt;">
<p style="font-size: 8pt; color: rgba(255,255,255,0.5);">개발비</p>
<p style="font-size: 10pt; font-weight: 700; color: #ffffff;">2,000만원</p>
</div>
<div style="display: flex; justify-content: space-between; margin-top: 3pt;">
<p style="font-size: 8pt; color: rgba(255,255,255,0.5);">구독/월</p>
<p style="font-size: 10pt; font-weight: 600; color: #E86F2C;">50만원</p>
</div>
</div>
</div>
<!-- 카드3: 사진 등록 -->
<div style="flex: 1; background: #f7f9fc; border-radius: 8pt; padding: 14pt; border: 1pt solid #e2e8f0; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<p style="font-size: 11pt; font-weight: 700; color: #1B3A5C; margin-bottom: 4pt;">사진 등록</p>
<p style="font-size: 8pt; color: #5a6b7d; line-height: 1.4;">제품/공정 사진 관리 기능</p>
</div>
<div>
<div style="display: flex; justify-content: space-between; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">개발비</p>
<p style="font-size: 10pt; font-weight: 700; color: #bbb;">-</p>
</div>
<div style="display: flex; justify-content: space-between; margin-top: 3pt;">
<p style="font-size: 8pt; color: #999;">구독/월</p>
<p style="font-size: 10pt; font-weight: 600; color: #E86F2C;">10만원</p>
</div>
</div>
</div>
</div>
<!-- 2행 -->
<div style="display: flex; gap: 10pt; flex: 1;">
<!-- 카드4: 챗봇/녹음/업무일지 -->
<div style="flex: 1; background: #f7f9fc; border-radius: 8pt; padding: 14pt; border: 1pt solid #e2e8f0; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<p style="font-size: 11pt; font-weight: 700; color: #1B3A5C; margin-bottom: 4pt;">챗봇 / 녹음 / 업무일지</p>
<p style="font-size: 8pt; color: #5a6b7d; line-height: 1.4;">AI 기반 업무 보조 도구 3종</p>
</div>
<div>
<div style="display: flex; justify-content: space-between; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">개발비</p>
<p style="font-size: 10pt; font-weight: 700; color: #bbb;">-</p>
</div>
<div style="display: flex; justify-content: space-between; margin-top: 3pt;">
<p style="font-size: 8pt; color: #999;">구독/월</p>
<p style="font-size: 10pt; font-weight: 600; color: #E86F2C;">각 20만원</p>
</div>
</div>
</div>
<!-- 카드5: 연구소 연구노트 -->
<div style="flex: 1; background: #f7f9fc; border-radius: 8pt; padding: 14pt; border: 1pt solid #e2e8f0; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<p style="font-size: 11pt; font-weight: 700; color: #1B3A5C; margin-bottom: 4pt;">연구소 연구노트</p>
<p style="font-size: 8pt; color: #5a6b7d; line-height: 1.4;">R&D 기록 및 지식재산 관리</p>
</div>
<div>
<div style="display: flex; justify-content: space-between; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">개발비</p>
<p style="font-size: 10pt; font-weight: 700; color: #bbb;">-</p>
</div>
<div style="display: flex; justify-content: space-between; margin-top: 3pt;">
<p style="font-size: 8pt; color: #999;">구독/월</p>
<p style="font-size: 10pt; font-weight: 600; color: #E86F2C;">5만원</p>
</div>
</div>
</div>
<!-- 카드6: 장비점검/사무소정비 -->
<div style="flex: 1; background: #f7f9fc; border-radius: 8pt; padding: 14pt; border: 1pt solid #e2e8f0; display: flex; flex-direction: column; justify-content: space-between;">
<div>
<p style="font-size: 11pt; font-weight: 700; color: #1B3A5C; margin-bottom: 4pt;">장비점검 / 사무소 정비</p>
<p style="font-size: 8pt; color: #5a6b7d; line-height: 1.4;">설비 유지보수 이력 관리</p>
</div>
<div>
<div style="display: flex; justify-content: space-between; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">개발비</p>
<p style="font-size: 10pt; font-weight: 700; color: #bbb;">-</p>
</div>
<div style="display: flex; justify-content: space-between; margin-top: 3pt;">
<p style="font-size: 8pt; color: #999;">구독/월</p>
<p style="font-size: 10pt; font-weight: 600; color: #E86F2C;">5만원</p>
</div>
</div>
</div>
</div>
</div>
<!-- 참고 박스 -->
<div style="margin-top: 10pt; padding: 8pt 14pt; background: #fff8f3; border-left: 3pt solid #E86F2C; border-radius: 0 5pt 5pt 0;">
<p style="font-size: 9pt; color: #5a6b7d;"><span style="font-weight: 700; color: #E86F2C;">참고</span> 품질관리(인정검사)에는 장비점검/사무소 정비 기능이 기본 포함됩니다.</p>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 8pt; border-top: 1pt solid #e2e8f0; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">SAM 서비스 요금 안내 | (주)코드브릿지엑스</p>
<p style="font-size: 8pt; color: #E86F2C; font-weight: 500;">모든 금액 VAT 별도</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,124 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #f7f9fc;
padding: 28pt 36pt 20pt 36pt;
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 14pt;">
<div style="display: flex; align-items: center; gap: 10pt;">
<div style="display: inline-block; padding: 3pt 9pt; background: #2E86AB; border-radius: 4pt;">
<p style="color: #fff; font-size: 7pt; font-weight: 600;">SECTION 03</p>
</div>
<h2 style="font-size: 20pt; font-weight: 700; color: #1B3A5C;">사용량 기반 추가 과금</h2>
</div>
<p style="font-size: 9pt; color: #999;">05 / 07</p>
</div>
<!-- 콘텐츠 2단 -->
<div style="flex: 1; display: flex; gap: 16pt;">
<!-- 좌측: 기본 제공량 카드 -->
<div style="width: 260pt; display: flex; flex-direction: column; gap: 12pt;">
<!-- 파일 저장 공간 -->
<div style="background: #ffffff; border-radius: 10pt; padding: 16pt; border: 1pt solid #e2e8f0; flex: 1;">
<div style="display: flex; align-items: center; gap: 8pt; margin-bottom: 10pt;">
<div style="width: 26pt; height: 26pt; background: #2E86AB; border-radius: 6pt; display: flex; align-items: center; justify-content: center;">
<p style="color: #fff; font-size: 13pt; font-weight: 700;">F</p>
</div>
<h3 style="font-size: 14pt; font-weight: 700; color: #1B3A5C;">파일 저장 공간</h3>
</div>
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 6pt;">
<p style="font-size: 9pt; color: #5a6b7d;">기본 제공</p>
<p style="font-size: 16pt; font-weight: 800; color: #1B3A5C;">100<span style="font-size: 10pt; font-weight: 500;">GB</span></p>
</div>
<div style="width: 100%; height: 1pt; background: #e2e8f0; margin-bottom: 6pt;"></div>
<div style="display: flex; justify-content: space-between; align-items: center;">
<p style="font-size: 9pt; color: #5a6b7d;">초과 시</p>
<p style="font-size: 11pt; font-weight: 700; color: #E86F2C;">100GB당 10만원/월</p>
</div>
</div>
<!-- AI 토큰 -->
<div style="background: #ffffff; border-radius: 10pt; padding: 16pt; border: 1pt solid #e2e8f0; flex: 1;">
<div style="display: flex; align-items: center; gap: 8pt; margin-bottom: 10pt;">
<div style="width: 26pt; height: 26pt; background: #1B3A5C; border-radius: 6pt; display: flex; align-items: center; justify-content: center;">
<p style="color: #fff; font-size: 13pt; font-weight: 700;">AI</p>
</div>
<h3 style="font-size: 14pt; font-weight: 700; color: #1B3A5C;">AI 토큰</h3>
</div>
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 6pt;">
<p style="font-size: 9pt; color: #5a6b7d;">기본 제공</p>
<p style="font-size: 16pt; font-weight: 800; color: #1B3A5C;">100<span style="font-size: 10pt; font-weight: 500;">만 토큰/월</span></p>
</div>
<div style="width: 100%; height: 1pt; background: #e2e8f0; margin-bottom: 6pt;"></div>
<div style="display: flex; justify-content: space-between; align-items: center;">
<p style="font-size: 9pt; color: #5a6b7d;">초과 시</p>
<p style="font-size: 11pt; font-weight: 700; color: #E86F2C;">실비 정산</p>
</div>
</div>
</div>
<!-- 우측: AI 100만 토큰 활용 예시 -->
<div style="flex: 1; background: #1B3A5C; border-radius: 10pt; padding: 18pt; display: flex; flex-direction: column;">
<p style="font-size: 10pt; font-weight: 700; color: #2E86AB; letter-spacing: 0.04em; margin-bottom: 4pt;">AI 100만 토큰, 이만큼 쓸 수 있습니다</p>
<p style="font-size: 8pt; color: rgba(255,255,255,0.4); margin-bottom: 12pt;">대부분의 중소 제조업에서 충분한 사용량</p>
<!-- 음성 회의 요약 -->
<div style="background: rgba(255,255,255,0.08); border-radius: 8pt; padding: 12pt 14pt; margin-bottom: 8pt;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div>
<p style="font-size: 10pt; font-weight: 600; color: #ffffff;">음성 회의 요약</p>
<p style="font-size: 8pt; color: rgba(255,255,255,0.5); margin-top: 2pt;">하루 30분씩 매일 회의해도 한 달 충분</p>
</div>
<p style="font-size: 18pt; font-weight: 800; color: #ffffff;">520<span style="font-size: 9pt; font-weight: 400; color: rgba(255,255,255,0.5);"></span></p>
</div>
</div>
<!-- 문서 자동 정리 -->
<div style="background: rgba(255,255,255,0.08); border-radius: 8pt; padding: 12pt 14pt; margin-bottom: 8pt;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div>
<p style="font-size: 10pt; font-weight: 600; color: #ffffff;">문서 자동 정리</p>
<p style="font-size: 8pt; color: rgba(255,255,255,0.5); margin-top: 2pt;">매일 15장씩 처리해도 여유</p>
</div>
<p style="font-size: 18pt; font-weight: 800; color: #ffffff;">300~400<span style="font-size: 9pt; font-weight: 400; color: rgba(255,255,255,0.5);">매(A4)</span></p>
</div>
</div>
<!-- 이메일/노트 분류 -->
<div style="background: rgba(255,255,255,0.08); border-radius: 8pt; padding: 12pt 14pt;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div>
<p style="font-size: 10pt; font-weight: 600; color: #ffffff;">이메일/노트 자동 분류</p>
<p style="font-size: 8pt; color: rgba(255,255,255,0.5); margin-top: 2pt;">하루 75건 자동 분류 가능</p>
</div>
<p style="font-size: 18pt; font-weight: 800; color: #ffffff;">2,000<span style="font-size: 9pt; font-weight: 400; color: rgba(255,255,255,0.5);"></span></p>
</div>
</div>
<div style="margin-top: auto; padding-top: 8pt;">
<p style="font-size: 8pt; color: rgba(255,255,255,0.35);">미사용 토큰 이월 불가 | 80% / 100% 소진 시 자동 알림</p>
</div>
</div>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 8pt; border-top: 1pt solid #e2e8f0; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">SAM 서비스 요금 안내 | (주)코드브릿지엑스</p>
<p style="font-size: 8pt; color: #E86F2C; font-weight: 500;">모든 금액 VAT 별도</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,117 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #ffffff;
padding: 28pt 36pt 20pt 36pt;
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12pt;">
<div style="display: flex; align-items: center; gap: 10pt;">
<div style="display: inline-block; padding: 3pt 9pt; background: #2E86AB; border-radius: 4pt;">
<p style="color: #fff; font-size: 7pt; font-weight: 600;">SECTION 04</p>
</div>
<h2 style="font-size: 20pt; font-weight: 700; color: #1B3A5C;">바로빌 부가서비스</h2>
</div>
<p style="font-size: 9pt; color: #999;">06 / 07</p>
</div>
<!-- 데이터 행 (div+flexbox 테이블 대체) -->
<div style="flex: 1; display: flex; flex-direction: column; gap: 0;">
<!-- 헤더 행 -->
<div style="display: flex; background: #1B3A5C; border-radius: 6pt 6pt 0 0; padding: 7pt 12pt;">
<div style="flex: 1;"><p style="font-size: 8pt; font-weight: 600; color: #fff;">서비스</p></div>
<div style="flex: 1;"><p style="font-size: 8pt; font-weight: 600; color: #fff;">과금 방식</p></div>
<div style="flex: 0.7;"><p style="font-size: 8pt; font-weight: 600; color: #fff;">기본 제공</p></div>
<div style="flex: 1.2;"><p style="font-size: 8pt; font-weight: 600; color: #fff;">추가 과금</p></div>
<div style="flex: 0.4; text-align: center;"><p style="font-size: 8pt; font-weight: 600; color: #fff;">부담</p></div>
</div>
<!-- 행1: 계좌조회 -->
<div style="display: flex; background: #f7f9fc; padding: 8pt 12pt; align-items: center;">
<div style="flex: 1;"><p style="font-size: 9pt; font-weight: 600; color: #1e2a3a;">계좌조회</p></div>
<div style="flex: 1;"><p style="font-size: 8pt; color: #5a6b7d;">월정액 10,000원</p></div>
<div style="flex: 0.7;"><p style="font-size: 8pt; color: #5a6b7d;">1계좌</p></div>
<div style="flex: 1.2;"><p style="font-size: 8pt; color: #5a6b7d;">추가 1계좌당 10,000원</p></div>
<div style="flex: 0.4; text-align: center;">
<div style="display: inline-block; padding: 2pt 7pt; background: #e2e8f0; border-radius: 3pt;">
<p style="font-size: 7pt; font-weight: 600; color: #1B3A5C;">고객</p>
</div>
</div>
</div>
<!-- 행2: 카드내역 -->
<div style="display: flex; background: #ffffff; padding: 8pt 12pt; align-items: center;">
<div style="flex: 1;"><p style="font-size: 9pt; font-weight: 600; color: #1e2a3a;">카드내역</p></div>
<div style="flex: 1;"><p style="font-size: 8pt; color: #5a6b7d;">월정액 10,000원</p></div>
<div style="flex: 0.7;"><p style="font-size: 8pt; color: #5a6b7d;">5장</p></div>
<div style="flex: 1.2;"><p style="font-size: 8pt; color: #5a6b7d;">추가 1장당 5,000원</p></div>
<div style="flex: 0.4; text-align: center;">
<div style="display: inline-block; padding: 2pt 7pt; background: #e2e8f0; border-radius: 3pt;">
<p style="font-size: 7pt; font-weight: 600; color: #1B3A5C;">고객</p>
</div>
</div>
</div>
<!-- 행3: 홈택스 매입/매출 -->
<div style="display: flex; background: #f7f9fc; padding: 8pt 12pt; align-items: center;">
<div style="flex: 1;"><p style="font-size: 9pt; font-weight: 600; color: #1e2a3a;">홈택스 매입/매출</p></div>
<div style="flex: 1;"><p style="font-size: 8pt; color: #5a6b7d;">월 33,000원 x 2</p></div>
<div style="flex: 0.7;"><p style="font-size: 8pt; color: #5a6b7d;">-</p></div>
<div style="flex: 1.2;"><p style="font-size: 8pt; color: #5a6b7d;">-</p></div>
<div style="flex: 0.4; text-align: center;">
<div style="display: inline-block; padding: 2pt 7pt; background: #2E86AB; border-radius: 3pt;">
<p style="font-size: 7pt; font-weight: 700; color: #fff;">SAM 무료!</p>
</div>
</div>
</div>
<!-- 행4: 세금계산서 발행 -->
<div style="display: flex; background: #ffffff; padding: 8pt 12pt; align-items: center; border-radius: 0 0 6pt 6pt;">
<div style="flex: 1;"><p style="font-size: 9pt; font-weight: 600; color: #1e2a3a;">세금계산서 발행</p></div>
<div style="flex: 1;"><p style="font-size: 8pt; color: #5a6b7d;">건별</p></div>
<div style="flex: 0.7;"><p style="font-size: 8pt; color: #5a6b7d;">100건</p></div>
<div style="flex: 1.2;"><p style="font-size: 8pt; color: #5a6b7d;">추가 50건당 5,000원</p></div>
<div style="flex: 0.4; text-align: center;">
<div style="display: inline-block; padding: 2pt 7pt; background: #e2e8f0; border-radius: 3pt;">
<p style="font-size: 7pt; font-weight: 600; color: #1B3A5C;">고객</p>
</div>
</div>
</div>
</div>
<!-- 과금 계산 예시 -->
<div style="margin-top: 12pt; background: #f7f9fc; border-radius: 8pt; padding: 14pt 16pt; border: 1pt solid #e2e8f0;">
<p style="font-size: 10pt; font-weight: 700; color: #1B3A5C; margin-bottom: 10pt;">과금 계산 예시</p>
<div style="display: flex; gap: 12pt;">
<!-- 예시1 -->
<div style="flex: 1; background: #ffffff; border-radius: 6pt; padding: 10pt 14pt; border-left: 3pt solid #2E86AB;">
<p style="font-size: 8pt; color: #5a6b7d; margin-bottom: 4pt;">법인카드 8장 등록 시</p>
<p style="font-size: 10pt; font-weight: 600; color: #1B3A5C;">(8 - 5) x 5,000 = <span style="color: #E86F2C; font-weight: 700;">15,000원</span> 추가</p>
</div>
<!-- 예시2 -->
<div style="flex: 1; background: #ffffff; border-radius: 6pt; padding: 10pt 14pt; border-left: 3pt solid #2E86AB;">
<p style="font-size: 8pt; color: #5a6b7d; margin-bottom: 4pt;">세금계산서 151건 발행 시</p>
<p style="font-size: 10pt; font-weight: 600; color: #1B3A5C;">ceil((151-100)/50) x 5,000 = <span style="color: #E86F2C; font-weight: 700;">10,000원</span> 추가</p>
</div>
</div>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 8pt; border-top: 1pt solid #e2e8f0; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">SAM 서비스 요금 안내 | (주)코드브릿지엑스</p>
<p style="font-size: 8pt; color: #E86F2C; font-weight: 500;">모든 금액 VAT 별도</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #1B3A5C;
padding: 40pt 48pt 28pt 48pt;
display: flex;
flex-direction: column;
justify-content: space-between;
}
</style>
</head>
<body>
<!-- 로고 -->
<div style="display: flex; align-items: center; gap: 10pt;">
<img src="/home/aweso/sam/docs/assets/bi/sam_bi_blue.png" style="width: 28pt; height: 28pt;">
<p style="font-size: 14pt; font-weight: 700; color: #ffffff;">SAM</p>
</div>
<!-- 메인 메시지 -->
<div>
<h1 style="font-size: 40pt; font-weight: 800; color: #ffffff; letter-spacing: -0.02em; line-height: 1.25;">지금 SAM과 함께 시작하세요</h1>
<p style="font-size: 15pt; color: rgba(255,255,255,0.5); margin-top: 14pt; line-height: 1.6;">제조 현장의 모든 흐름을 하나의 플랫폼에서 관리합니다</p>
<div style="display: flex; gap: 20pt; margin-top: 20pt;">
<div style="padding: 10pt 18pt; background: rgba(46,134,171,0.2); border: 1pt solid rgba(46,134,171,0.4); border-radius: 8pt;">
<p style="font-size: 10pt; color: #2E86AB; font-weight: 600;">ERP + MES 통합</p>
</div>
<div style="padding: 10pt 18pt; background: rgba(232,111,44,0.15); border: 1pt solid rgba(232,111,44,0.35); border-radius: 8pt;">
<p style="font-size: 10pt; color: #E86F2C; font-weight: 600;">AI 기반 업무 자동화</p>
</div>
<div style="padding: 10pt 18pt; background: rgba(255,255,255,0.08); border: 1pt solid rgba(255,255,255,0.2); border-radius: 8pt;">
<p style="font-size: 10pt; color: rgba(255,255,255,0.7); font-weight: 600;">실시간 현황 대시보드</p>
</div>
</div>
</div>
<!-- 하단 정보 -->
<div style="display: flex; gap: 48pt; align-items: flex-end;">
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.3); margin-bottom: 3pt; letter-spacing: 0.04em;">COMPANY</p>
<p style="font-size: 11pt; font-weight: 500; color: rgba(255,255,255,0.8);">(주)코드브릿지엑스</p>
</div>
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.3); margin-bottom: 3pt; letter-spacing: 0.04em;">SYSTEM</p>
<p style="font-size: 11pt; font-weight: 500; color: rgba(255,255,255,0.8);">Smart Automation Management</p>
</div>
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.3); margin-bottom: 3pt; letter-spacing: 0.04em;">CONTACT</p>
<p style="font-size: 11pt; font-weight: 500; color: rgba(255,255,255,0.8);">담당 영업파트너 또는 본사</p>
</div>
<div style="margin-left: auto;">
<div style="display: inline-block; padding: 4pt 12pt; border: 1pt solid #E86F2C; border-radius: 4pt;">
<p style="font-size: 9pt; font-weight: 600; color: #E86F2C;">모든 금액 VAT 별도</p>
</div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.3); margin-top: 6pt; text-align: right;">07 / 07</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #0d2818;
padding: 36pt 44pt 28pt;
display: flex;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
}
</style>
</head>
<body>
<!-- 상단 로고 + 배지 -->
<div style="display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; align-items: center; gap: 10pt;">
<img src="/home/aweso/sam/docs/assets/bi/sam_bi_green.png" style="width: 28pt; height: 28pt; border-radius: 5pt;">
<p style="font-size: 14pt; font-weight: 700; color: #ffffff; letter-spacing: 0.05em;">SAM</p>
</div>
<div style="display: inline-block; padding: 5pt 16pt; border: 1pt solid rgba(255,255,255,0.2); border-radius: 20pt;">
<p style="font-size: 8pt; font-weight: 600; color: rgba(255,255,255,0.5); letter-spacing: 0.08em;">PARTNER COMMISSION GUIDE</p>
</div>
</div>
<!-- 메인 타이틀 영역 -->
<div>
<p style="font-size: 11pt; font-weight: 600; color: #27AE60; letter-spacing: 0.06em; margin-bottom: 10pt;">SALES PARTNER COMMISSION</p>
<h1 style="font-size: 40pt; font-weight: 800; color: #ffffff; letter-spacing: -0.02em; line-height: 1.2;">SAM 영업파트너<br>수당 체계</h1>
<p style="font-size: 12pt; color: rgba(255,255,255,0.45); margin-top: 8pt; line-height: 1.5;">Smart Automation Management</p>
<p style="font-size: 13pt; font-weight: 500; color: rgba(255,255,255,0.7); margin-top: 10pt; line-height: 1.5;">업계 최고 수준 수당률, 함께 성장하는 파트너십</p>
</div>
<!-- 핵심 수치 3개 카드 -->
<div style="display: flex; gap: 12pt;">
<div style="flex: 1; background: rgba(39,174,96,0.15); border: 1pt solid rgba(39,174,96,0.3); border-radius: 10pt; padding: 14pt 16pt;">
<p style="font-size: 22pt; font-weight: 800; color: #27AE60; margin-bottom: 4pt;">33%</p>
<p style="font-size: 9pt; color: rgba(255,255,255,0.6); line-height: 1.4;">최대 수당률</p>
</div>
<div style="flex: 1; background: rgba(39,174,96,0.15); border: 1pt solid rgba(39,174,96,0.3); border-radius: 10pt; padding: 14pt 16pt;">
<p style="font-size: 22pt; font-weight: 800; color: #ffffff; margin-bottom: 4pt;">660<span style="font-size: 13pt;">만원</span></p>
<p style="font-size: 9pt; color: rgba(255,255,255,0.6); line-height: 1.4;">개발비 2,000만원 기준</p>
</div>
<div style="flex: 1; background: rgba(39,174,96,0.15); border: 1pt solid rgba(39,174,96,0.3); border-radius: 10pt; padding: 14pt 16pt;">
<p style="font-size: 22pt; font-weight: 800; color: #ffffff; margin-bottom: 4pt;">무제한</p>
<p style="font-size: 9pt; color: rgba(255,255,255,0.6); line-height: 1.4;">누적 파트너 수익</p>
</div>
</div>
<!-- 하단 정보 -->
<div style="display: flex; gap: 48pt; padding-top: 10pt; border-top: 1pt solid rgba(255,255,255,0.1);">
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.3); margin-bottom: 3pt;">COMPANY</p>
<p style="font-size: 10pt; font-weight: 500; color: rgba(255,255,255,0.7);">(주)코드브릿지엑스</p>
</div>
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.3); margin-bottom: 3pt;">DATE</p>
<p style="font-size: 10pt; font-weight: 500; color: rgba(255,255,255,0.7);">2026. 02</p>
</div>
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.3); margin-bottom: 3pt;">NOTE</p>
<p style="font-size: 10pt; font-weight: 600; color: #27AE60;">VAT 별도</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #f5faf5;
padding: 30pt 44pt 20pt;
display: flex;
flex-direction: column;
overflow: hidden;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20pt;">
<div style="display: flex; align-items: center; gap: 12pt;">
<div style="display: inline-block; padding: 4pt 10pt; background: #0d2818; border-radius: 4pt;">
<p style="color: #27AE60; font-size: 8pt; font-weight: 600;">SECTION 01</p>
</div>
<h2 style="font-size: 22pt; font-weight: 800; color: #0d2818;">수당 지급 3대 원칙</h2>
</div>
<p style="font-size: 10pt; color: #999;">02</p>
</div>
<!-- 3개 원칙 카드 -->
<div style="flex: 1; display: flex; gap: 14pt;">
<!-- 원칙 1 -->
<div style="flex: 1; background: #ffffff; border-radius: 12pt; padding: 20pt 18pt; border-top: 3pt solid #27AE60; display: flex; flex-direction: column;">
<div style="width: 38pt; height: 38pt; background: #0d2818; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-bottom: 12pt;">
<p style="color: #27AE60; font-size: 18pt; font-weight: 800;">1</p>
</div>
<h3 style="font-size: 16pt; font-weight: 700; color: #0d2818; margin-bottom: 8pt;">개발비 기반</h3>
<p style="font-size: 10pt; color: #5a6b5d; line-height: 1.65;">수당은 <span style="font-weight: 700; color: #0d2818;">개발비에 대해서만</span> 지급합니다.</p>
<p style="font-size: 10pt; color: #5a6b5d; line-height: 1.65; margin-top: 4pt;">구독료는 인프라 비용으로 활용되며 수당 대상이 아닙니다.</p>
<div style="margin-top: auto; padding-top: 10pt;">
<div style="display: inline-block; padding: 4pt 10pt; background: #e8f5e9; border-radius: 4pt;">
<p style="font-size: 8pt; font-weight: 600; color: #27AE60;">개발비 = 수당 대상</p>
</div>
</div>
</div>
<!-- 원칙 2 -->
<div style="flex: 1; background: #ffffff; border-radius: 12pt; padding: 20pt 18pt; border-top: 3pt solid #27AE60; display: flex; flex-direction: column;">
<div style="width: 38pt; height: 38pt; background: #0d2818; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-bottom: 12pt;">
<p style="color: #27AE60; font-size: 18pt; font-weight: 800;">2</p>
</div>
<h3 style="font-size: 16pt; font-weight: 700; color: #0d2818; margin-bottom: 8pt;">기준금액 50% 적용</h3>
<p style="font-size: 10pt; color: #5a6b5d; line-height: 1.65;">개발비의 <span style="font-weight: 700; color: #0d2818;">50%</span>를 기준금액으로 산정합니다.</p>
<p style="font-size: 10pt; color: #5a6b5d; line-height: 1.65; margin-top: 4pt;">기준금액에 수당률을 적용하여 2단계 분할 지급합니다.</p>
<div style="margin-top: auto; padding-top: 10pt;">
<div style="display: inline-block; padding: 4pt 10pt; background: #e8f5e9; border-radius: 4pt;">
<p style="font-size: 8pt; font-weight: 600; color: #27AE60;">2단계 분할 지급</p>
</div>
</div>
</div>
<!-- 원칙 3 -->
<div style="flex: 1; background: #ffffff; border-radius: 12pt; padding: 20pt 18pt; border-top: 3pt solid #27AE60; display: flex; flex-direction: column;">
<div style="width: 38pt; height: 38pt; background: #0d2818; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-bottom: 12pt;">
<p style="color: #27AE60; font-size: 18pt; font-weight: 800;">3</p>
</div>
<h3 style="font-size: 16pt; font-weight: 700; color: #0d2818; margin-bottom: 8pt;">투명한 정산</h3>
<p style="font-size: 10pt; color: #5a6b5d; line-height: 1.65;">매월 정산일에 <span style="font-weight: 700; color: #0d2818;">건별 수당 확정</span>합니다.</p>
<p style="font-size: 10pt; color: #5a6b5d; line-height: 1.65; margin-top: 4pt;">익월 파트너 등록 계좌로 입금합니다.</p>
<div style="margin-top: auto; padding-top: 10pt;">
<div style="display: inline-block; padding: 4pt 10pt; background: #e8f5e9; border-radius: 4pt;">
<p style="font-size: 8pt; font-weight: 600; color: #27AE60;">매월 정산 + 익월 지급</p>
</div>
</div>
</div>
</div>
<!-- 하단 강조 문구 -->
<div style="margin-top: 14pt; padding: 10pt 20pt; background: #0d2818; border-radius: 8pt; text-align: center;">
<p style="font-size: 12pt; font-weight: 700; color: #27AE60;">명확한 기준, 신뢰할 수 있는 파트너십</p>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 8pt; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">SAM 영업파트너 수당 체계 | (주)코드브릿지엑스</p>
<p style="font-size: 8pt; color: #999;">02</p>
<p style="font-size: 8pt; color: #27AE60; font-weight: 500;">VAT 별도</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,118 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #ffffff;
padding: 24pt 44pt 14pt;
display: flex;
flex-direction: column;
overflow: hidden;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10pt;">
<div style="display: flex; align-items: center; gap: 12pt;">
<div style="display: inline-block; padding: 4pt 10pt; background: #0d2818; border-radius: 4pt;">
<p style="color: #27AE60; font-size: 8pt; font-weight: 600;">SECTION 02</p>
</div>
<h2 style="font-size: 20pt; font-weight: 800; color: #0d2818;">가입 유형별 수당률</h2>
</div>
<p style="font-size: 10pt; color: #999;">03</p>
</div>
<!-- 2단 비교 카드 -->
<div style="flex: 1; display: flex; gap: 18pt;">
<!-- 개인 가입 -->
<div style="flex: 1; background: #f5faf5; border-radius: 12pt; padding: 16pt; border: 1pt solid #c8e6c9; display: flex; flex-direction: column;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10pt;">
<h3 style="font-size: 17pt; font-weight: 700; color: #0d2818;">개인 가입</h3>
<div style="display: inline-block; padding: 5pt 14pt; background: #0d2818; border-radius: 6pt;">
<p style="color: #27AE60; font-size: 10pt; font-weight: 800;">총 28%</p>
</div>
</div>
<!-- 큰 숫자 -->
<div style="text-align: center; margin-bottom: 8pt;">
<p style="font-size: 36pt; font-weight: 900; color: #0d2818; letter-spacing: -0.02em;">28<span style="font-size: 20pt;">%</span></p>
</div>
<!-- 항목 3행 -->
<div style="display: flex; flex-direction: column; gap: 6pt; flex: 1;">
<div style="display: flex; justify-content: space-between; align-items: center; padding: 8pt 12pt; background: #ffffff; border-radius: 6pt;">
<p style="font-size: 10pt; color: #5a6b5d;">파트너 수당</p>
<p style="font-size: 15pt; font-weight: 800; color: #0d2818;">20%</p>
</div>
<div style="display: flex; justify-content: space-between; align-items: center; padding: 8pt 12pt; background: #ffffff; border-radius: 6pt;">
<p style="font-size: 10pt; color: #5a6b5d;">매니저 수당</p>
<p style="font-size: 15pt; font-weight: 800; color: #0d2818;">5%</p>
</div>
<div style="display: flex; justify-content: space-between; align-items: center; padding: 8pt 12pt; background: #ffffff; border-radius: 6pt;">
<p style="font-size: 10pt; color: #5a6b5d;">협업지원금(유치자)</p>
<p style="font-size: 15pt; font-weight: 800; color: #27AE60;">3%</p>
</div>
</div>
<div style="margin-top: 10pt; text-align: center;">
<p style="font-size: 9pt; color: #5a6b5d;">매니저와 유치자를 통한 추가 수익 구조</p>
</div>
</div>
<!-- 단체 가입 -->
<div style="flex: 1; background: #0d2818; border-radius: 12pt; padding: 16pt; display: flex; flex-direction: column;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10pt;">
<h3 style="font-size: 17pt; font-weight: 700; color: #ffffff;">단체 가입</h3>
<div style="display: inline-block; padding: 5pt 14pt; background: #27AE60; border-radius: 6pt;">
<p style="color: #ffffff; font-size: 10pt; font-weight: 800;">총 33%</p>
</div>
</div>
<!-- 큰 숫자 -->
<div style="text-align: center; margin-bottom: 8pt;">
<p style="font-size: 40pt; font-weight: 900; color: #27AE60; letter-spacing: -0.02em;">33<span style="font-size: 22pt;">%</span></p>
</div>
<!-- 항목 3행 -->
<div style="display: flex; flex-direction: column; gap: 6pt; flex: 1;">
<div style="display: flex; justify-content: space-between; align-items: center; padding: 8pt 12pt; background: rgba(255,255,255,0.08); border-radius: 6pt;">
<p style="font-size: 10pt; color: rgba(255,255,255,0.6);">단체 수당</p>
<p style="font-size: 15pt; font-weight: 800; color: #ffffff;">30%</p>
</div>
<div style="display: flex; justify-content: space-between; align-items: center; padding: 8pt 12pt; background: rgba(255,255,255,0.08); border-radius: 6pt;">
<p style="font-size: 10pt; color: rgba(255,255,255,0.6);">매니저</p>
<p style="font-size: 15pt; font-weight: 800; color: rgba(255,255,255,0.25);">0%</p>
</div>
<div style="display: flex; justify-content: space-between; align-items: center; padding: 8pt 12pt; background: rgba(255,255,255,0.08); border-radius: 6pt;">
<p style="font-size: 10pt; color: rgba(255,255,255,0.6);">협업지원금(유치자)</p>
<p style="font-size: 15pt; font-weight: 800; color: #27AE60;">3%</p>
</div>
</div>
<div style="margin-top: 10pt; text-align: center;">
<p style="font-size: 9pt; font-weight: 600; color: #27AE60;">단체 가입 시 최고 수당률!</p>
</div>
</div>
</div>
<!-- 하단 바 -->
<div style="margin-top: 8pt; padding: 6pt 16pt; background: #e8f5e9; border-radius: 6pt; display: flex; justify-content: center; gap: 20pt;">
<p style="font-size: 9pt; color: #2e7d32; font-weight: 500;">유치자 수당은 하위 파트너 1단계까지 적용</p>
<p style="font-size: 9pt; color: #2e7d32;">|</p>
<p style="font-size: 9pt; color: #2e7d32; font-weight: 500;">단체 가입 시 수수료율 개발비의 33% (VAT 별도)</p>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 8pt; margin-top: 6pt;">
<p style="font-size: 8pt; color: #999;">SAM 영업파트너 수당 체계 | (주)코드브릿지엑스</p>
<p style="font-size: 8pt; color: #999;">03</p>
<p style="font-size: 8pt; color: #27AE60; font-weight: 500;">VAT 별도</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,180 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #f5faf5;
padding: 24pt 44pt 16pt;
display: flex;
flex-direction: column;
overflow: hidden;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12pt;">
<div style="display: flex; align-items: center; gap: 12pt;">
<div style="display: inline-block; padding: 4pt 10pt; background: #0d2818; border-radius: 4pt;">
<p style="color: #27AE60; font-size: 8pt; font-weight: 600;">SECTION 03</p>
</div>
<h2 style="font-size: 20pt; font-weight: 800; color: #0d2818;">수당 산정 시뮬레이션</h2>
</div>
<p style="font-size: 10pt; color: #999;">04</p>
</div>
<!-- 상단: 기준금액 100만원 기준 -->
<div style="margin-bottom: 10pt;">
<p style="font-size: 10pt; font-weight: 700; color: #0d2818; margin-bottom: 7pt;">기준금액 100만원 기준</p>
<!-- 헤더행 -->
<div style="display: flex; gap: 1pt; margin-bottom: 2pt;">
<div style="flex: 2; padding: 5pt 10pt; background: #0d2818; border-radius: 3pt 0 0 0;">
<p style="font-size: 8pt; font-weight: 600; color: #27AE60;">가입 유형</p>
</div>
<div style="flex: 1.2; padding: 5pt 8pt; background: #0d2818; text-align: right;">
<p style="font-size: 8pt; font-weight: 600; color: #fff;">파트너/단체</p>
</div>
<div style="flex: 1; padding: 5pt 8pt; background: #0d2818; text-align: right;">
<p style="font-size: 8pt; font-weight: 600; color: #fff;">매니저</p>
</div>
<div style="flex: 1; padding: 5pt 8pt; background: #0d2818; text-align: right;">
<p style="font-size: 8pt; font-weight: 600; color: #fff;">협업지원금</p>
</div>
<div style="flex: 1.5; padding: 5pt 8pt; background: #0d2818; text-align: right; border-radius: 0 3pt 0 0;">
<p style="font-size: 8pt; font-weight: 600; color: #27AE60;">총 지급</p>
</div>
</div>
<!-- 데이터 행 1 -->
<div style="display: flex; gap: 1pt; margin-bottom: 1pt;">
<div style="flex: 2; padding: 5pt 10pt; background: #ffffff;">
<p style="font-size: 8pt; font-weight: 600; color: #0d2818;">개인 (유치자O)</p>
</div>
<div style="flex: 1.2; padding: 5pt 8pt; background: #ffffff; text-align: right;">
<p style="font-size: 8pt; color: #0d2818;">200,000원</p>
</div>
<div style="flex: 1; padding: 5pt 8pt; background: #ffffff; text-align: right;">
<p style="font-size: 8pt; color: #0d2818;">50,000원</p>
</div>
<div style="flex: 1; padding: 5pt 8pt; background: #ffffff; text-align: right;">
<p style="font-size: 8pt; color: #0d2818;">30,000원</p>
</div>
<div style="flex: 1.5; padding: 5pt 8pt; background: #ffffff; text-align: right;">
<p style="font-size: 8pt; font-weight: 700; color: #27AE60;">280,000원 (28%)</p>
</div>
</div>
<!-- 데이터 행 2 -->
<div style="display: flex; gap: 1pt; margin-bottom: 1pt;">
<div style="flex: 2; padding: 5pt 10pt; background: #eef6ee;">
<p style="font-size: 8pt; font-weight: 600; color: #0d2818;">개인 (유치자X)</p>
</div>
<div style="flex: 1.2; padding: 5pt 8pt; background: #eef6ee; text-align: right;">
<p style="font-size: 8pt; color: #0d2818;">200,000원</p>
</div>
<div style="flex: 1; padding: 5pt 8pt; background: #eef6ee; text-align: right;">
<p style="font-size: 8pt; color: #0d2818;">50,000원</p>
</div>
<div style="flex: 1; padding: 5pt 8pt; background: #eef6ee; text-align: right;">
<p style="font-size: 8pt; color: #bbb;">0원</p>
</div>
<div style="flex: 1.5; padding: 5pt 8pt; background: #eef6ee; text-align: right;">
<p style="font-size: 8pt; font-weight: 600; color: #5a6b5d;">250,000원 (25%)</p>
</div>
</div>
<!-- 데이터 행 3 -->
<div style="display: flex; gap: 1pt;">
<div style="flex: 2; padding: 5pt 10pt; background: #ffffff;">
<p style="font-size: 8pt; font-weight: 600; color: #0d2818;">단체</p>
</div>
<div style="flex: 1.2; padding: 5pt 8pt; background: #ffffff; text-align: right;">
<p style="font-size: 8pt; color: #0d2818;">300,000원</p>
</div>
<div style="flex: 1; padding: 5pt 8pt; background: #ffffff; text-align: right;">
<p style="font-size: 8pt; color: #bbb;">0원</p>
</div>
<div style="flex: 1; padding: 5pt 8pt; background: #ffffff; text-align: right;">
<p style="font-size: 8pt; color: #0d2818;">30,000원</p>
</div>
<div style="flex: 1.5; padding: 5pt 8pt; background: #ffffff; text-align: right;">
<p style="font-size: 8pt; font-weight: 700; color: #27AE60;">330,000원 (33%)</p>
</div>
</div>
</div>
<!-- 하단: 제조업 기본 패키지 실제 수당 -->
<div style="flex: 1; display: flex; flex-direction: column;">
<div style="display: flex; align-items: center; gap: 8pt; margin-bottom: 8pt;">
<p style="font-size: 10pt; font-weight: 700; color: #0d2818;">제조업 기본 패키지 (개발비 2,000만원) 실제 수당</p>
<div style="display: inline-block; padding: 2pt 8pt; background: #27AE60; border-radius: 3pt;">
<p style="font-size: 7pt; font-weight: 700; color: #fff;">실전 시뮬레이션</p>
</div>
</div>
<div style="flex: 1; display: flex; gap: 16pt;">
<!-- 개인 가입 카드 -->
<div style="flex: 1; background: #ffffff; border-radius: 10pt; padding: 14pt 16pt; border: 1pt solid #c8e6c9; display: flex; flex-direction: column;">
<p style="font-size: 10pt; font-weight: 700; color: #0d2818; margin-bottom: 10pt;">개인 가입</p>
<div style="display: flex; justify-content: space-between; padding: 5pt 0; border-bottom: 1pt solid #e8f5e9;">
<p style="font-size: 9pt; color: #5a6b5d;">판매자(파트너)</p>
<p style="font-size: 10pt; font-weight: 700; color: #0d2818;">400만원</p>
</div>
<div style="display: flex; justify-content: space-between; padding: 5pt 0; border-bottom: 1pt solid #e8f5e9;">
<p style="font-size: 9pt; color: #5a6b5d;">매니저</p>
<p style="font-size: 10pt; font-weight: 700; color: #0d2818;">100만원</p>
</div>
<div style="display: flex; justify-content: space-between; padding: 5pt 0;">
<p style="font-size: 9pt; color: #5a6b5d;">협업지원금</p>
<p style="font-size: 10pt; font-weight: 700; color: #27AE60;">60만원</p>
</div>
<div style="margin-top: auto; padding-top: 8pt; text-align: center;">
<div style="display: inline-block; padding: 5pt 16pt; background: #e8f5e9; border-radius: 6pt;">
<p style="font-size: 12pt; font-weight: 800; color: #0d2818;">총 560만원 수익!</p>
</div>
</div>
</div>
<!-- 단체 가입 카드 -->
<div style="flex: 1; background: #0d2818; border-radius: 10pt; padding: 14pt 16pt; display: flex; flex-direction: column;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10pt;">
<p style="font-size: 10pt; font-weight: 700; color: #27AE60;">단체 가입</p>
<div style="display: inline-block; padding: 2pt 8pt; background: #27AE60; border-radius: 3pt;">
<p style="font-size: 7pt; font-weight: 700; color: #fff;">BEST</p>
</div>
</div>
<div style="display: flex; justify-content: space-between; padding: 5pt 0; border-bottom: 1pt solid rgba(255,255,255,0.1);">
<p style="font-size: 9pt; color: rgba(255,255,255,0.5);">단체</p>
<p style="font-size: 10pt; font-weight: 700; color: #ffffff;">600만원</p>
</div>
<div style="display: flex; justify-content: space-between; padding: 5pt 0; border-bottom: 1pt solid rgba(255,255,255,0.1);">
<p style="font-size: 9pt; color: rgba(255,255,255,0.5);">매니저</p>
<p style="font-size: 10pt; font-weight: 700; color: rgba(255,255,255,0.25);">0원</p>
</div>
<div style="display: flex; justify-content: space-between; padding: 5pt 0;">
<p style="font-size: 9pt; color: rgba(255,255,255,0.5);">협업지원금</p>
<p style="font-size: 10pt; font-weight: 700; color: #27AE60;">60만원</p>
</div>
<div style="margin-top: auto; padding-top: 8pt; text-align: center;">
<div style="display: inline-block; padding: 5pt 16pt; background: #27AE60; border-radius: 6pt;">
<p style="font-size: 14pt; font-weight: 900; color: #ffffff;">총 660만원 수익!</p>
</div>
</div>
</div>
</div>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 6pt; margin-top: 6pt;">
<p style="font-size: 8pt; color: #999;">SAM 영업파트너 수당 체계 | (주)코드브릿지엑스</p>
<p style="font-size: 8pt; color: #999;">04</p>
<p style="font-size: 8pt; color: #27AE60; font-weight: 500;">VAT 별도</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,129 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #ffffff;
padding: 26pt 44pt 18pt;
display: flex;
flex-direction: column;
overflow: hidden;
}
</style>
</head>
<body>
<!-- 헤더 -->
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16pt;">
<div style="display: flex; align-items: center; gap: 12pt;">
<div style="display: inline-block; padding: 4pt 10pt; background: #0d2818; border-radius: 4pt;">
<p style="color: #27AE60; font-size: 8pt; font-weight: 600;">SECTION 04</p>
</div>
<h2 style="font-size: 22pt; font-weight: 800; color: #0d2818;">수당 지급 프로세스</h2>
</div>
<p style="font-size: 10pt; color: #999;">05</p>
</div>
<!-- 3단계 프로세스 -->
<div style="display: flex; align-items: center; gap: 8pt; margin-bottom: 16pt;">
<!-- Step 1 -->
<div style="flex: 1; background: #f5faf5; border-radius: 10pt; padding: 18pt 14pt; text-align: center; border: 1pt solid #c8e6c9;">
<div style="width: 40pt; height: 40pt; background: #0d2818; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10pt;">
<p style="color: #27AE60; font-size: 18pt; font-weight: 800;">1</p>
</div>
<h3 style="font-size: 14pt; font-weight: 700; color: #0d2818; margin-bottom: 6pt;">계약 및 입금</h3>
<p style="font-size: 9pt; color: #5a6b5d; line-height: 1.5;">개발비 전액 완납 확인</p>
</div>
<!-- 화살표 -->
<div style="display: flex; align-items: center;">
<p style="font-size: 20pt; color: #27AE60; font-weight: 300;">&#10140;</p>
</div>
<!-- Step 2 -->
<div style="flex: 1; background: #f5faf5; border-radius: 10pt; padding: 18pt 14pt; text-align: center; border: 1pt solid #c8e6c9;">
<div style="width: 40pt; height: 40pt; background: #0d2818; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10pt;">
<p style="color: #27AE60; font-size: 18pt; font-weight: 800;">2</p>
</div>
<h3 style="font-size: 14pt; font-weight: 700; color: #0d2818; margin-bottom: 6pt;">수당 확정</h3>
<p style="font-size: 9pt; color: #5a6b5d; line-height: 1.5;">매월 정산일 건별 수당 확정</p>
</div>
<!-- 화살표 -->
<div style="display: flex; align-items: center;">
<p style="font-size: 20pt; color: #27AE60; font-weight: 300;">&#10140;</p>
</div>
<!-- Step 3 -->
<div style="flex: 1; background: #0d2818; border-radius: 10pt; padding: 18pt 14pt; text-align: center;">
<div style="width: 40pt; height: 40pt; background: #27AE60; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 10pt;">
<p style="color: #ffffff; font-size: 18pt; font-weight: 800;">3</p>
</div>
<h3 style="font-size: 14pt; font-weight: 700; color: #ffffff; margin-bottom: 6pt;">지급</h3>
<p style="font-size: 9pt; color: rgba(255,255,255,0.6); line-height: 1.5;">파트너 등록 계좌로 입금</p>
</div>
</div>
<!-- 추가 옵션 수당 참고 -->
<div style="flex: 1; display: flex; flex-direction: column;">
<div style="display: flex; align-items: center; gap: 8pt; margin-bottom: 8pt;">
<p style="font-size: 10pt; font-weight: 700; color: #0d2818;">추가 옵션 수당 참고</p>
<div style="display: inline-block; padding: 2pt 8pt; background: #e8f5e9; border-radius: 3pt;">
<p style="font-size: 7pt; font-weight: 600; color: #27AE60;">개발비가 있는 옵션만 수당 대상</p>
</div>
</div>
<div style="display: flex; gap: 12pt; flex: 1;">
<!-- 생산공정 추가 -->
<div style="flex: 1; background: #f5faf5; border-radius: 8pt; padding: 14pt 16pt; border: 1pt solid #c8e6c9; display: flex; flex-direction: column; justify-content: center;">
<p style="font-size: 9pt; font-weight: 700; color: #0d2818; margin-bottom: 6pt;">생산공정 추가</p>
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4pt;">
<p style="font-size: 8pt; color: #5a6b5d;">개발비</p>
<p style="font-size: 9pt; font-weight: 600; color: #0d2818;">500만원</p>
</div>
<div style="display: flex; justify-content: space-between; align-items: center;">
<p style="font-size: 8pt; color: #5a6b5d;">판매자 수당</p>
<p style="font-size: 11pt; font-weight: 800; color: #27AE60;">100만원</p>
</div>
</div>
<!-- 품질관리 인정검사 -->
<div style="flex: 1; background: #f5faf5; border-radius: 8pt; padding: 14pt 16pt; border: 1pt solid #c8e6c9; display: flex; flex-direction: column; justify-content: center;">
<p style="font-size: 9pt; font-weight: 700; color: #0d2818; margin-bottom: 6pt;">품질관리 인정검사</p>
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4pt;">
<p style="font-size: 8pt; color: #5a6b5d;">개발비</p>
<p style="font-size: 9pt; font-weight: 600; color: #0d2818;">2,000만원</p>
</div>
<div style="display: flex; justify-content: space-between; align-items: center;">
<p style="font-size: 8pt; color: #5a6b5d;">판매자 수당</p>
<p style="font-size: 11pt; font-weight: 800; color: #27AE60;">400만원</p>
</div>
</div>
<!-- 구독료만 있는 옵션 -->
<div style="flex: 1; background: #fafafa; border-radius: 8pt; padding: 14pt 16pt; border: 1pt solid #e0e0e0; display: flex; flex-direction: column; justify-content: center;">
<p style="font-size: 9pt; font-weight: 700; color: #999; margin-bottom: 6pt;">구독료만 있는 옵션</p>
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4pt;">
<p style="font-size: 8pt; color: #bbb;">개발비</p>
<p style="font-size: 9pt; font-weight: 600; color: #bbb;">없음</p>
</div>
<div style="display: flex; justify-content: space-between; align-items: center;">
<p style="font-size: 8pt; color: #bbb;">판매자 수당</p>
<p style="font-size: 11pt; font-weight: 800; color: #bbb;">비대상</p>
</div>
</div>
</div>
</div>
<!-- 푸터 -->
<div style="display: flex; justify-content: space-between; align-items: center; padding-top: 8pt; margin-top: 8pt;">
<p style="font-size: 8pt; color: #999;">SAM 영업파트너 수당 체계 | (주)코드브릿지엑스</p>
<p style="font-size: 8pt; color: #999;">05</p>
<p style="font-size: 8pt; color: #27AE60; font-weight: 500;">VAT 별도</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 720pt;
height: 405pt;
font-family: 'Pretendard', sans-serif;
background: #0d2818;
padding: 36pt 44pt 28pt;
display: flex;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
}
</style>
</head>
<body>
<!-- 상단 로고 -->
<div style="display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; align-items: center; gap: 10pt;">
<img src="/home/aweso/sam/docs/assets/bi/sam_bi_green.png" style="width: 28pt; height: 28pt; border-radius: 5pt;">
<p style="font-size: 14pt; font-weight: 700; color: #ffffff; letter-spacing: 0.05em;">SAM</p>
</div>
<p style="font-size: 10pt; color: rgba(255,255,255,0.3);">06</p>
</div>
<!-- 메인 콘텐츠 -->
<div>
<p style="font-size: 11pt; font-weight: 600; color: #27AE60; letter-spacing: 0.06em; margin-bottom: 10pt;">PARTNERSHIP</p>
<h1 style="font-size: 36pt; font-weight: 800; color: #ffffff; letter-spacing: -0.02em; line-height: 1.25;">지금, SAM 파트너로<br>함께하세요</h1>
<p style="font-size: 13pt; color: rgba(255,255,255,0.55); margin-top: 12pt; line-height: 1.6;">제조업 디지털 전환 시장, 폭발적 성장 중</p>
<p style="font-size: 13pt; color: rgba(255,255,255,0.55); line-height: 1.6;">대한민국 제조업 디지털 전환, 당신이 이끄는 비즈니스 기회</p>
</div>
<!-- 핵심 수치 요약 카드 -->
<div style="display: flex; gap: 12pt; margin-bottom: 16pt;">
<div style="flex: 1; background: rgba(39,174,96,0.15); border: 1pt solid rgba(39,174,96,0.3); border-radius: 8pt; padding: 12pt 14pt; text-align: center;">
<p style="font-size: 20pt; font-weight: 800; color: #27AE60;">33%</p>
<p style="font-size: 8pt; color: rgba(255,255,255,0.5); margin-top: 2pt;">최대 수당률</p>
</div>
<div style="flex: 1; background: rgba(39,174,96,0.15); border: 1pt solid rgba(39,174,96,0.3); border-radius: 8pt; padding: 12pt 14pt; text-align: center;">
<p style="font-size: 20pt; font-weight: 800; color: #ffffff;">660<span style="font-size: 11pt;">만원</span></p>
<p style="font-size: 8pt; color: rgba(255,255,255,0.5); margin-top: 2pt;">건당 최대 수익</p>
</div>
<div style="flex: 1; background: rgba(39,174,96,0.15); border: 1pt solid rgba(39,174,96,0.3); border-radius: 8pt; padding: 12pt 14pt; text-align: center;">
<p style="font-size: 20pt; font-weight: 800; color: #ffffff;">무제한</p>
<p style="font-size: 8pt; color: rgba(255,255,255,0.5); margin-top: 2pt;">누적 수익 상한</p>
</div>
</div>
<!-- 연락처 + 하단 정보 -->
<div style="display: flex; justify-content: space-between; align-items: flex-end; padding-top: 10pt; border-top: 1pt solid rgba(255,255,255,0.1);">
<div style="display: flex; gap: 40pt;">
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.3); margin-bottom: 3pt;">COMPANY</p>
<p style="font-size: 10pt; font-weight: 500; color: rgba(255,255,255,0.7);">(주)코드브릿지엑스</p>
</div>
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.3); margin-bottom: 3pt;">SYSTEM</p>
<p style="font-size: 10pt; font-weight: 500; color: rgba(255,255,255,0.7);">Smart Automation Management</p>
</div>
<div>
<p style="font-size: 8pt; color: rgba(255,255,255,0.3); margin-bottom: 3pt;">CONTACT</p>
<p style="font-size: 10pt; font-weight: 500; color: rgba(255,255,255,0.7);">본사 정산팀</p>
</div>
</div>
<p style="font-size: 9pt; font-weight: 600; color: #27AE60;">모든 금액 VAT 별도</p>
</div>
</body>
</html>