From 0508282e585b41f7a0a8edad3042c05c3eccd194 Mon Sep 17 00:00:00 2001 From: hskwon Date: Wed, 24 Dec 2025 19:48:15 +0900 Subject: [PATCH] =?UTF-8?q?ApiResponse=20=ED=97=AC=ED=8D=BC=20=ED=99=95?= =?UTF-8?q?=EC=9E=A5=20=EB=B0=8F=20Tenant=20=EC=9A=94=EC=B2=AD=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LOGICAL_RELATIONSHIPS.md | 4 +- app/Helpers/ApiResponse.php | 79 ++++++++++++++++++- .../Requests/Tenant/TenantUpdateRequest.php | 12 +++ app/Traits/ModelTrait.php | 6 +- 4 files changed, 97 insertions(+), 4 deletions(-) diff --git a/LOGICAL_RELATIONSHIPS.md b/LOGICAL_RELATIONSHIPS.md index d88985c..29ec5b0 100644 --- a/LOGICAL_RELATIONSHIPS.md +++ b/LOGICAL_RELATIONSHIPS.md @@ -1,6 +1,6 @@ # 논리적 데이터베이스 관계 문서 -> **자동 생성**: 2025-12-23 22:25:44 +> **자동 생성**: 2025-12-24 19:31:13 > **소스**: Eloquent 모델 관계 분석 ## 📊 모델별 관계 현황 @@ -244,8 +244,10 @@ ### users - **userTenants()**: hasMany → `user_tenants` - **userRoles()**: hasMany → `user_roles` +- **tenantProfiles()**: hasMany → `tenant_user_profiles` - **userTenant()**: hasOne → `user_tenants` - **userTenantById()**: hasOne → `user_tenants` +- **tenantProfile()**: hasOne → `tenant_user_profiles` - **tenantsMembership()**: belongsToMany → `tenants` - **files()**: morphMany → `files` diff --git a/app/Helpers/ApiResponse.php b/app/Helpers/ApiResponse.php index b8013b1..4a6f506 100644 --- a/app/Helpers/ApiResponse.php +++ b/app/Helpers/ApiResponse.php @@ -9,6 +9,80 @@ class ApiResponse { + /** + * ISO 8601 날짜를 Y-m-d 형식으로 변환 + * + * @param mixed $data 변환할 데이터 (배열, 객체, 페이지네이션 등) + * @return mixed 변환된 데이터 + */ + public static function formatDates(mixed $data): mixed + { + // null이면 그대로 반환 + if ($data === null) { + return null; + } + + // Paginator 처리 + if ($data instanceof \Illuminate\Pagination\LengthAwarePaginator || + $data instanceof \Illuminate\Pagination\Paginator) { + $items = self::formatDates($data->items()); + $data->setCollection(collect($items)); + + return $data; + } + + // Collection 처리 + if ($data instanceof \Illuminate\Support\Collection) { + return $data->map(fn ($item) => self::formatDates($item)); + } + + // Model 처리 + if ($data instanceof \Illuminate\Database\Eloquent\Model) { + return self::formatDates($data->toArray()); + } + + // 배열 처리 + if (is_array($data)) { + foreach ($data as $key => $value) { + if (is_string($value) && self::isIso8601Date($value)) { + $data[$key] = self::toDateFormat($value); + } elseif (is_array($value) || is_object($value)) { + $data[$key] = self::formatDates($value); + } + } + + return $data; + } + + // 단일 문자열이 ISO 8601 날짜인 경우 + if (is_string($data) && self::isIso8601Date($data)) { + return self::toDateFormat($data); + } + + return $data; + } + + /** + * ISO 8601 날짜 형식인지 확인 + */ + private static function isIso8601Date(string $value): bool + { + // 2025-12-22T15:00:00.000000Z 형식 매칭 + return (bool) preg_match('/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z?$/', $value); + } + + /** + * ISO 8601 날짜를 Y-m-d 형식으로 변환 + */ + private static function toDateFormat(string $value): string + { + try { + return \Carbon\Carbon::parse($value)->format('Y-m-d'); + } catch (\Exception $e) { + return $value; + } + } + public function normalizeFiles(array $laravelFiles): array { $files = ['name' => [], 'type' => [], 'tmp_name' => [], 'size' => [], 'fileType' => []]; @@ -51,10 +125,13 @@ public static function success( array $debug = [], int $statusCode = 200 ): JsonResponse { + // ISO 8601 날짜를 Y-m-d 형식으로 변환 + $formattedData = self::formatDates($data); + $response = [ 'success' => true, 'message' => $message, - 'data' => $data, + 'data' => $formattedData, ]; if (! empty($debug)) { $response['query'] = $debug; diff --git a/app/Http/Requests/Tenant/TenantUpdateRequest.php b/app/Http/Requests/Tenant/TenantUpdateRequest.php index 04c5783..ad3466a 100644 --- a/app/Http/Requests/Tenant/TenantUpdateRequest.php +++ b/app/Http/Requests/Tenant/TenantUpdateRequest.php @@ -21,6 +21,18 @@ public function rules(): array 'address' => 'nullable|string|max:255', 'business_num' => 'nullable|string|max:20', 'ceo_name' => 'nullable|string|max:100', + // 확장 필드 (JSON) + 'options' => 'nullable|array', + 'options.business_type' => 'nullable|string|max:100', + 'options.business_category' => 'nullable|string|max:100', + 'options.zip_code' => 'nullable|string|max:10', + 'options.address_detail' => 'nullable|string|max:255', + 'options.tax_invoice_email' => 'nullable|email|max:100', + 'options.manager_name' => 'nullable|string|max:100', + 'options.payment_bank' => 'nullable|string|max:100', + 'options.payment_account' => 'nullable|string|max:50', + 'options.payment_account_holder' => 'nullable|string|max:100', + 'options.payment_day' => 'nullable|string|max:10', ]; } } diff --git a/app/Traits/ModelTrait.php b/app/Traits/ModelTrait.php index 55ee57f..2868d9d 100644 --- a/app/Traits/ModelTrait.php +++ b/app/Traits/ModelTrait.php @@ -8,10 +8,12 @@ trait ModelTrait { /** * 날짜 직렬화 포맷 오버라이드 (모델에 추가해서 사용) + * + * ISO 8601 (2025-12-22T15:00:00.000000Z) → Y-m-d (2025-12-22) */ - protected function serializeDate(DateTimeInterface $date) + protected function serializeDate(DateTimeInterface $date): string { - return $date->format('Y-m-d H:i:s'); + return $date->format('Y-m-d'); } /**