- PushApi: /api/push → /api/v1/push 경로 수정 - InternalApi: exchange-token 엔드포인트 Swagger 문서 추가
338 lines
13 KiB
PHP
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() {}
|
|
}
|