feat: bootstrap lunch picker miniapp with backend, docs, and branding assets

This commit is contained in:
mingking2
2026-04-15 14:03:08 +09:00
commit 7faf251fd3
85 changed files with 31332 additions and 0 deletions

View File

@@ -0,0 +1,356 @@
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]