Files
sam-api/app/Swagger/v1/PushApi.php
hskwon 81a6dfab5a fix: Swagger 경로 수정 및 Internal API 문서 추가
- PushApi: /api/push → /api/v1/push 경로 수정
- InternalApi: exchange-token 엔드포인트 Swagger 문서 추가
2025-12-18 22:08:08 +09:00

338 lines
13 KiB
PHP

<?php
namespace App\Swagger\v1;
/**
* @OA\Tag(name="Push", description="푸시 알림 관리")
*/
/**
* Push 관련 스키마 정의
* -----------------------------------------------------------------------------
*/
/**
* @OA\Schema(
* schema="PushDeviceToken",
* type="object",
* description="푸시 디바이스 토큰",
*
* @OA\Property(property="id", type="integer", example=1),
* @OA\Property(property="tenant_id", type="integer", example=1),
* @OA\Property(property="user_id", type="integer", example=5),
* @OA\Property(property="token", type="string", example="dGhpcyBpcyBhIHNhbXBsZSBGQ00gdG9rZW4..."),
* @OA\Property(property="platform", type="string", enum={"ios", "android", "web"}, example="android"),
* @OA\Property(property="device_name", type="string", nullable=true, example="Samsung Galaxy S24"),
* @OA\Property(property="app_version", type="string", nullable=true, example="1.0.0"),
* @OA\Property(property="is_active", type="boolean", example=true),
* @OA\Property(property="last_used_at", type="string", format="date-time", example="2025-12-18 10:30:00"),
* @OA\Property(property="created_at", type="string", format="date-time", example="2025-12-18 10:00:00"),
* @OA\Property(property="updated_at", type="string", format="date-time", example="2025-12-18 10:30:00")
* )
*
* @OA\Schema(
* schema="PushNotificationSetting",
* type="object",
* description="푸시 알림 설정",
*
* @OA\Property(property="id", type="integer", example=1),
* @OA\Property(property="tenant_id", type="integer", example=1),
* @OA\Property(property="user_id", type="integer", example=5),
* @OA\Property(property="notification_type", type="string", enum={"deposit", "withdrawal", "order", "approval", "attendance", "notice", "system"}, example="deposit"),
* @OA\Property(property="is_enabled", type="boolean", example=true),
* @OA\Property(property="sound", type="string", enum={"default.wav", "deposit.wav", "withdrawal.wav", "order.wav", "approval.wav", "urgent.wav"}, example="deposit.wav"),
* @OA\Property(property="vibrate", type="boolean", example=true),
* @OA\Property(property="show_preview", type="boolean", example=true),
* @OA\Property(property="created_at", type="string", format="date-time", example="2025-12-18 10:00:00"),
* @OA\Property(property="updated_at", type="string", format="date-time", example="2025-12-18 10:30:00")
* )
*
* @OA\Schema(
* schema="RegisterTokenRequest",
* type="object",
* required={"token", "platform"},
*
* @OA\Property(property="token", type="string", minLength=10, example="dGhpcyBpcyBhIHNhbXBsZSBGQ00gdG9rZW4...", description="FCM 토큰"),
* @OA\Property(property="platform", type="string", enum={"ios", "android", "web"}, example="android", description="디바이스 플랫폼"),
* @OA\Property(property="device_name", type="string", nullable=true, maxLength=255, example="Samsung Galaxy S24", description="디바이스명"),
* @OA\Property(property="app_version", type="string", nullable=true, maxLength=50, example="1.0.0", description="앱 버전")
* )
*
* @OA\Schema(
* schema="UnregisterTokenRequest",
* type="object",
* required={"token"},
*
* @OA\Property(property="token", type="string", example="dGhpcyBpcyBhIHNhbXBsZSBGQ00gdG9rZW4...", description="해제할 FCM 토큰")
* )
*
* @OA\Schema(
* schema="UpdatePushSettingsRequest",
* type="object",
* required={"settings"},
*
* @OA\Property(
* property="settings",
* type="array",
* description="알림 설정 배열",
*
* @OA\Items(
* type="object",
* required={"notification_type", "is_enabled"},
*
* @OA\Property(property="notification_type", type="string", enum={"deposit", "withdrawal", "order", "approval", "attendance", "notice", "system"}, example="deposit"),
* @OA\Property(property="is_enabled", type="boolean", example=true),
* @OA\Property(property="sound", type="string", nullable=true, enum={"default.wav", "deposit.wav", "withdrawal.wav", "order.wav", "approval.wav", "urgent.wav"}, example="deposit.wav"),
* @OA\Property(property="vibrate", type="boolean", nullable=true, example=true),
* @OA\Property(property="show_preview", type="boolean", nullable=true, example=true)
* )
* )
* )
*
* @OA\Schema(
* schema="NotificationTypesResponse",
* type="object",
*
* @OA\Property(
* property="types",
* type="array",
* description="지원하는 알림 유형 목록",
*
* @OA\Items(type="string", example="deposit")
* ),
*
* @OA\Property(
* property="sounds",
* type="array",
* description="지원하는 알림음 목록",
*
* @OA\Items(type="string", example="deposit.wav")
* )
* )
*/
class PushApi
{
/**
* @OA\Post(
* path="/api/v1/push/register-token",
* tags={"Push"},
* summary="FCM 토큰 등록",
* description="디바이스의 FCM 토큰을 등록합니다. 동일한 토큰이 이미 존재하면 업데이트됩니다.",
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
*
* @OA\RequestBody(
* required=true,
*
* @OA\JsonContent(ref="#/components/schemas/RegisterTokenRequest")
* ),
*
* @OA\Response(
* response=200,
* description="토큰 등록 성공",
*
* @OA\JsonContent(
* allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(
*
* @OA\Property(property="message", type="string", example="푸시 토큰이 등록되었습니다."),
* @OA\Property(property="data", ref="#/components/schemas/PushDeviceToken")
* )
* }
* )
* ),
*
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function registerToken() {}
/**
* @OA\Post(
* path="/api/v1/push/unregister-token",
* tags={"Push"},
* summary="FCM 토큰 해제",
* description="디바이스의 FCM 토큰을 비활성화합니다.",
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
*
* @OA\RequestBody(
* required=true,
*
* @OA\JsonContent(ref="#/components/schemas/UnregisterTokenRequest")
* ),
*
* @OA\Response(
* response=200,
* description="토큰 해제 성공",
*
* @OA\JsonContent(
* allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(
*
* @OA\Property(property="message", type="string", example="푸시 토큰이 해제되었습니다."),
* @OA\Property(
* property="data",
* type="object",
* @OA\Property(property="unregistered", type="boolean", example=true)
* )
* )
* }
* )
* ),
*
* @OA\Response(response=400, description="토큰 누락", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function unregisterToken() {}
/**
* @OA\Get(
* path="/api/v1/push/tokens",
* tags={"Push"},
* summary="사용자 토큰 목록 조회",
* description="현재 사용자의 활성화된 디바이스 토큰 목록을 조회합니다.",
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
*
* @OA\Response(
* response=200,
* description="조회 성공",
*
* @OA\JsonContent(
* allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(
*
* @OA\Property(
* property="data",
* type="array",
*
* @OA\Items(ref="#/components/schemas/PushDeviceToken")
* )
* )
* }
* )
* ),
*
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function getTokens() {}
/**
* @OA\Get(
* path="/api/v1/push/settings",
* tags={"Push"},
* summary="알림 설정 조회",
* description="현재 사용자의 알림 유형별 설정을 조회합니다. 설정이 없는 유형은 기본값으로 반환됩니다.",
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
*
* @OA\Response(
* response=200,
* description="조회 성공",
*
* @OA\JsonContent(
* allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(
*
* @OA\Property(
* property="data",
* type="object",
* description="알림 유형별 설정 (키: notification_type)",
* @OA\Property(property="deposit", ref="#/components/schemas/PushNotificationSetting"),
* @OA\Property(property="withdrawal", ref="#/components/schemas/PushNotificationSetting"),
* @OA\Property(property="order", ref="#/components/schemas/PushNotificationSetting"),
* @OA\Property(property="approval", ref="#/components/schemas/PushNotificationSetting"),
* @OA\Property(property="attendance", ref="#/components/schemas/PushNotificationSetting"),
* @OA\Property(property="notice", ref="#/components/schemas/PushNotificationSetting"),
* @OA\Property(property="system", ref="#/components/schemas/PushNotificationSetting")
* )
* )
* }
* )
* ),
*
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function getSettings() {}
/**
* @OA\Put(
* path="/api/v1/push/settings",
* tags={"Push"},
* summary="알림 설정 업데이트",
* description="사용자의 알림 설정을 업데이트합니다. 여러 알림 유형을 한 번에 설정할 수 있습니다.",
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
*
* @OA\RequestBody(
* required=true,
*
* @OA\JsonContent(ref="#/components/schemas/UpdatePushSettingsRequest")
* ),
*
* @OA\Response(
* response=200,
* description="설정 업데이트 성공",
*
* @OA\JsonContent(
* allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(
*
* @OA\Property(property="message", type="string", example="알림 설정이 업데이트되었습니다."),
* @OA\Property(
* property="data",
* type="array",
*
* @OA\Items(ref="#/components/schemas/PushNotificationSetting")
* )
* )
* }
* )
* ),
*
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")),
* @OA\Response(response=422, description="검증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function updateSettings() {}
/**
* @OA\Get(
* path="/api/v1/push/notification-types",
* tags={"Push"},
* summary="알림 유형 목록 조회",
* description="지원하는 알림 유형과 알림음 목록을 조회합니다.",
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
*
* @OA\Response(
* response=200,
* description="조회 성공",
*
* @OA\JsonContent(
* allOf={
*
* @OA\Schema(ref="#/components/schemas/ApiResponse"),
* @OA\Schema(
*
* @OA\Property(property="data", ref="#/components/schemas/NotificationTypesResponse")
* )
* }
* )
* ),
*
* @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse"))
* )
*/
public function getNotificationTypes() {}
}