# 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 --- ## 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 필터링 확인 ```