Files
sam-docs/standards/api-rules.md

149 lines
4.3 KiB
Markdown
Raw Normal View History

# SAM API 개발 규칙
**업데이트**: 2025-11-10
---
## 1. Architecture Philosophy
- **Service First**: All business logic must be written in Service classes (public functions)
- **Controller**: Only responsible for DI injection of Services and calling them. Use ApiResponse::handle() for responses
- **Exception Flow**: Errors are thrown → converted to JSON by global handler
- **Context Enforcement**: Base Service requires tenantId(), apiUserId(). Throws exception if not set
---
## 2. Multi-tenancy & Models
- BelongsToTenant global scope applied
- ModelTrait for is_active, date handling
- SoftDeletes by default
- Common columns: tenant_id, created_by, updated_by, deleted_by (COMMENT required)
- FK constraints: Created during design, minimal in production
### 2.1 ModelTrait 사용 가이드
`ModelTrait`는 모든 모델에서 공통으로 사용하는 기능을 제공합니다.
**위치**: `app/Traits/ModelTrait.php`
**제공 기능**:
```php
// 1. 날짜 직렬화 포맷 (Y-m-d H:i:s)
protected function serializeDate(DateTimeInterface $date)
// 2. Active 상태 조회 Scope
public function scopeActive($query)
// 사용: Model::active()->get()
// SQL: WHERE is_active = 1
```
**⚠️ 필수 요구사항**:
`scopeActive()` 메서드 사용 시 테이블에 `is_active` 컬럼이 **반드시 존재해야 함**
```sql
-- 마이그레이션 예시
$table->boolean('is_active')
->default(true)
->comment('활성화 여부 (ModelTrait::scopeActive() 사용)');
```
**모델 설정**:
```php
class YourModel extends Model
{
use BelongsToTenant, ModelTrait, SoftDeletes;
protected $fillable = [
// ...
'is_active', // 반드시 추가
];
protected $casts = [
'is_active' => 'boolean', // 반드시 추가
];
}
```
**is_active 컬럼 적용 테이블** (2025-12-05 기준):
| 테이블 | is_active | 비고 |
|--------|-----------|------|
| materials | ✅ 있음 | |
| products | ✅ 있음 | |
| item_pages | ✅ 있음 | |
| item_fields | ✅ 있음 | 2025-12-05 추가 |
| item_sections | ❌ 없음 | 필요시 마이그레이션 추가 |
---
## 3. Middleware Stack
- ApiKeyMiddleware, CheckSwaggerAuth, CorsMiddleware, CheckPermission, PermMapper
- Default route group: auth.apikey (some with auth:sanctum)
---
## 4. Routing (v1)
- Auth, Common codes, Files, Tenants, Users (me/tenants/switch), Menus+Permissions, Roles/Permissions, Departments, Field settings, Options, Categories, Classifications, Products, BOM
- REST conventions: index/show/store/update/destroy + extensions (toggle, bulkUpsert, reorder)
---
## 5. Controller/Service Rules
- **Controller**: FormRequest type-hint → only pass $request->validated() to Service
- **Service**: extends Service, tenantId()/apiUserId() required
- **Lists**: Pagination, explicit search parameters
- **Responses**: {success, message, data}, message must be i18n key only
---
## 6. i18n & Response Messages
- Messages: lang/{locale}/message.php
- Errors: lang/{locale}/error.php
- **Rule**: No direct strings, must use __('message.xxx'), __('error.xxx')
- Common keys: message.fetched/created/updated/deleted/bulk_upsert/reordered
- Resource-specific keys allowed: message.product.created, message.bom.bulk_upsert
---
## 7. Validation (FormRequest)
- **No direct validate() calls**. Separate all into FormRequest classes
- **Reuse common Requests**: PaginateRequest, BomItemsRequest, DateRangeRequest
- **Boundary validation** (effective_from ≤ effective_to) in Request
---
## 8. Audit Logging
- **Table**: audit_logs (tenant_id, target_type, target_id, action, before/after(json), actor_id, ip, ua, created_at)
- **Actions**: created, updated, deleted, released, cloned, items_replaced, diff_viewed
- **Retention**: 13 months default, audit:prune scheduler cleanup
- **Failure tolerance**: Log failures don't block business operations
---
## 9. Domain Rules
- **Status**: Strings (DRAFT/RELEASED/ARCHIVED)
- **Unique/Indexes**: models(code), model_versions(version_no), bom_items(parent, order)
- **BOM**: Supports summary/validate/bulkUpsert/reorder
---
## 개발 시 필수 체크
```
✓ Service-First 패턴 (Controller는 단순)
✓ BelongsToTenant scope 적용
✓ ModelTrait 사용
✓ SoftDeletes 적용
✓ FormRequest 검증
✓ i18n 키 사용 (__('message.xxx'))
✓ 감사 로그 고려
✓ tenant_id 필터링 확인
```