openapi: 3.0.3 info: title: Lunch MiniApp API version: 0.1.0 description: | 직장인 점심 추천 미니앱 MVP API servers: - url: https://api.example.com tags: - name: Health - name: Restaurants - name: Reviews - name: Likes - name: Users paths: /v1/health: get: tags: [Health] summary: 헬스 체크 responses: '200': description: OK content: application/json: schema: type: object properties: status: type: string example: ok /v1/restaurants/nearby: get: tags: [Restaurants] summary: 주변 식당 목록 조회 parameters: - in: query name: lat required: true schema: type: number format: double - in: query name: lng required: true schema: type: number format: double - in: query name: radiusMeters required: false schema: type: integer default: 1000 enum: [500, 1000, 2000] - in: query name: category required: false schema: $ref: '#/components/schemas/RestaurantCategory' - in: query name: sort required: false schema: type: string enum: [distance, rating, likes] default: distance - in: query name: cursor required: false schema: type: string - in: query name: size required: false schema: type: integer minimum: 1 maximum: 50 default: 20 responses: '200': description: 조회 성공 content: application/json: schema: type: object properties: items: type: array items: $ref: '#/components/schemas/RestaurantListItem' nextCursor: type: string nullable: true /v1/restaurants/{restaurantId}: get: tags: [Restaurants] summary: 식당 상세 조회 parameters: - in: path name: restaurantId required: true schema: type: string format: uuid responses: '200': description: 조회 성공 content: application/json: schema: $ref: '#/components/schemas/RestaurantDetail' '404': description: 식당 없음 /v1/restaurants/{restaurantId}/reviews: get: tags: [Reviews] summary: 식당 리뷰 목록 조회 parameters: - in: path name: restaurantId required: true schema: type: string format: uuid - in: query name: cursor required: false schema: type: string - in: query name: size required: false schema: type: integer default: 20 minimum: 1 maximum: 50 responses: '200': description: 조회 성공 content: application/json: schema: type: object properties: items: type: array items: $ref: '#/components/schemas/ReviewItem' nextCursor: type: string nullable: true post: tags: [Reviews] summary: 리뷰 작성 또는 수정(upsert) parameters: - in: path name: restaurantId required: true schema: type: string format: uuid requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReviewUpsertRequest' responses: '200': description: 저장 성공 content: application/json: schema: $ref: '#/components/schemas/ReviewItem' '400': description: 유효성 오류 '401': description: 인증 필요 /v1/reviews/{reviewId}: delete: tags: [Reviews] summary: 리뷰 삭제 parameters: - in: path name: reviewId required: true schema: type: string format: uuid responses: '204': description: 삭제 성공 '401': description: 인증 필요 '403': description: 본인 리뷰만 삭제 가능 /v1/restaurants/{restaurantId}/like: post: tags: [Likes] summary: 좋아요 토글 parameters: - in: path name: restaurantId required: true schema: type: string format: uuid responses: '200': description: 토글 성공 content: application/json: schema: type: object properties: liked: type: boolean likeCount: type: integer /v1/users/me/reviews: get: tags: [Users] summary: 내 리뷰 목록 parameters: - in: query name: cursor schema: type: string - in: query name: size schema: type: integer default: 20 minimum: 1 maximum: 50 responses: '200': description: 조회 성공 content: application/json: schema: type: object properties: items: type: array items: $ref: '#/components/schemas/ReviewItem' nextCursor: type: string nullable: true components: schemas: RestaurantCategory: type: string enum: - KOREAN - CHINESE - JAPANESE - WESTERN - OTHER RestaurantListItem: type: object properties: id: type: string format: uuid name: type: string category: $ref: '#/components/schemas/RestaurantCategory' distanceMeters: type: integer averageRating: type: number format: float reviewCount: type: integer likeCount: type: integer likedByMe: type: boolean required: [id, name, category, distanceMeters, averageRating, reviewCount, likeCount, likedByMe] RestaurantDetail: allOf: - $ref: '#/components/schemas/RestaurantListItem' - type: object properties: address: type: string phone: type: string nullable: true openingHours: type: string nullable: true lat: type: number format: double lng: type: number format: double ReviewUpsertRequest: type: object properties: rating: type: integer minimum: 1 maximum: 5 content: type: string minLength: 1 maxLength: 500 required: [rating, content] ReviewItem: type: object properties: id: type: string format: uuid restaurantId: type: string format: uuid userId: type: string format: uuid nickName: type: string rating: type: integer content: type: string createdAt: type: string format: date-time updatedAt: type: string format: date-time mine: type: boolean required: [id, restaurantId, userId, nickName, rating, content, createdAt, updatedAt, mine]