๋ฌธ์ ํด๊ฒฐ
StudioGo ์ด์ ์ค ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํฉ๋๋ค.
์ผ๋ฐ์ ์ธ ๋ฌธ์
๋ก๊ทธ์ธ ์คํจ
์ฆ์
์นด์นด์ค ๋ก๊ทธ์ธ ๋ฒํผ์ ํญํด๋ ๋ก๊ทธ์ธ์ด ์๋ฃ๋์ง ์๊ฑฐ๋ ์ค๋ฅ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค.
์์ธ ๋ฐ ํด๊ฒฐ
| ์์ธ | ์ฆ์ | ํด๊ฒฐ ๋ฐฉ๋ฒ |
|---|---|---|
| ์นด์นด์ค ๊ณ์ ๋ฏธ์ฐ๋ | โ์นด์นด์ค ๊ณ์ ์ ํ์ธํด์ฃผ์ธ์โ ๋ฉ์์ง | ์นด์นด์คํก ์ฑ์์ ๊ณ์ ๋ก๊ทธ์ธ ์ํ ํ์ธ |
| ์นด์นด์คํก ๋ฏธ์ค์น (๋ชจ๋ฐ์ผ) | ์นด์นด์ค ๋ก๊ทธ์ธ ํ๋ฉด์ด ์น์ผ๋ก ์ด๋ฆผ | ์นด์นด์คํก ์ฑ ์ค์น ํ ์ฌ์๋ |
| ๋คํธ์ํฌ ์ค๋ฅ | โ๋คํธ์ํฌ ์ค๋ฅโ ๋๋ ๋ฌดํ ๋ก๋ฉ | Wi-Fi/๋ชจ๋ฐ์ผ ๋ฐ์ดํฐ ํ์ธ ํ ์ฌ์๋ |
| OAuth ํ ํฐ ๋ง๋ฃ | ์๋ ๋ก๊ทธ์ธ ์คํจ ํ ์ฌ๋ก๊ทธ์ธ ์๊ตฌ | ์ ์ ๋์. ์นด์นด์ค ๊ณ์ ์ผ๋ก ์ฌ๋ก๊ทธ์ธ |
| ์ฑ ๋ฒ์ ๋ฏธ์ง์ | โ์ฑ์ ์ ๋ฐ์ดํธํด์ฃผ์ธ์โ ๋ฉ์์ง | ์ฑ์คํ ์ด/ํ๋ ์ด์คํ ์ด์์ ์ต์ ๋ฒ์ ์ ๋ฐ์ดํธ |
| ์๋ฒ ์ ๊ฒ ์ค | โ์๋ฒ ์ ๊ฒ ์ค์ ๋๋คโ ๋ฉ์์ง | ๊ณต์ง ํ์ธ ํ ์ ๊ฒ ์ข ๋ฃ ์ ์ฌ์๋ |
์ด์์ ์กฐ์น
์ฌ์ฉ์๊ฐ ์ง์์ ์ผ๋ก ๋ก๊ทธ์ธ์ ์คํจํ๋ค๊ณ ๋ณด๊ณ ํ๋ฉด ๋ค์์ ํ์ธํฉ๋๋ค.
- Hono API ์๋ฒ ์ํ ํ์ธ (Vercel ๋์๋ณด๋)
- ์นด์นด์ค ๊ฐ๋ฐ์ ์ฝ์์์ OAuth ์ค์ ํ์ธ (Redirect URI, ์ฑ ํค)
- Neon DB ์ฐ๊ฒฐ ์ํ ํ์ธ
์ฌ๋กฏ ์ถฉ๋
์ฆ์
BJ๊ฐ ๊ฐ์ฉ ์ํ์ ์ฌ๋กฏ์ ์ ํํ์ผ๋ โ์ด๋ฏธ ์์ฝ๋ ์ฌ๋กฏ์ ๋๋คโ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค.
์์ธ
๋ ๋ช ์ด์์ ์ฌ์ฉ์๊ฐ ๊ฑฐ์ ๋์์ ๊ฐ์ ์ฌ๋กฏ์ ์ ํํ๋ ๊ฒฝ์ฐ ๋ฐ์ํฉ๋๋ค. Hold ๋ฉ์ปค๋์ฆ์ด ๋์์ฑ์ ์ ์ดํ์ง๋ง, ๊ทนํ ์งง์ ์๊ฐ ์ฐจ์ด๋ก ์ถฉ๋์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ
| ๋์ | ์กฐ์น |
|---|---|
| BJ (์ฌ์ฉ์) | ๋ค๋ฅธ ๊ฐ์ฉ ์ฌ๋กฏ์ ์ ํํ์ฌ ์ฌ์๋ |
| ์ด์์ | ๋ณ๋ ์กฐ์น ๋ถํ์ (์์คํ ์ด ์๋ ์ฒ๋ฆฌ) |
| ๊ด๋ฆฌ์ | ๋น๋ฒ ๋ฐ์ ์ ์๋ฒ ๋ก๊ทธ์์ ๋์์ฑ ์ฒ๋ฆฌ ํ์ธ |
์๋ฐฉ
- ์ฌ๋กฏ ์ ํ ์ Hold๊ฐ ์ฆ์ ๊ฑธ๋ฆฌ๋ฏ๋ก ์ ์์ ์ธ ๊ฒฝ์ฐ ์ถฉ๋์ด ๋ฐ์ํ์ง ์์ต๋๋ค
- ์ถฉ๋์ด ๋ฐ๋ณต๋๋ค๋ฉด ์๋ฒ ์๋ต ์ง์ฐ์ด ์์ธ์ผ ์ ์์ผ๋ฏ๋ก Vercel ํจ์ ์คํ ์๊ฐ์ ๋ชจ๋ํฐ๋งํฉ๋๋ค
Hold ๋ง๋ฃ
์ฆ์
์ฌ๋กฏ์ ์ ํํ๊ณ ์์ฝ ์ ๋ณด๋ฅผ ์ ๋ ฅํ๋ ๋์ค โ์์์ ์ ์๊ฐ์ด ๋ง๋ฃ๋์์ต๋๋คโ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค.
์์ธ ๋ฐ ํด๊ฒฐ
| ์์ธ | ํด๊ฒฐ ๋ฐฉ๋ฒ |
|---|---|
| ์ ๋ ฅ ์๊ฐ ์ด๊ณผ (2๋ถ) | ์ฌ๋กฏ์ ๋ค์ ์ ํํ์ฌ ์ฌ์๋ |
| ๋คํธ์ํฌ ์ง์ฐ์ผ๋ก ์๋ฒ ํต์ ์คํจ | ๋คํธ์ํฌ ํ์ธ ํ ์ฌ์๋ |
| ์ฑ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ ํ | Hold ์ค์๋ ์ฑ์ ์ ํํ์ง ์๋๋ก ์๋ด |
์ด์์ ์ฐธ๊ณ
Hold ๋ง๋ฃ์จ์ด ๋๋ค๋ฉด ๋ค์์ ๊ฒํ ํฉ๋๋ค.
- ์์ฝ ํ์ ํ๋ฉด์ ์ ๋ ฅ ํญ๋ชฉ์ด ๋๋ฌด ๋ง์์ง ํ์ธ (๊ฐ์ํ ๊ฒํ )
- ์๋ฒ ์๋ต ์๊ฐ์ด ๋๋ ค์ ์ค์ ์ ๋ ฅ ๊ฐ๋ฅ ์๊ฐ์ด ์ค์ด๋๋์ง ํ์ธ
- 2๋ถ ์ ํ์ด ์ ์ ํ์ง ๋น์ฆ๋์ค ๊ด์ ์์ ์ฌ๊ฒํ
ํธ์ ์๋ฆผ ๋ฏธ์์
์ฆ์
์์ฝ ์ํ ๋ณ๊ฒฝ, ์ฒดํฌ์ธ ๋ฆฌ๋ง์ธ๋ ๋ฑ์ ํธ์ ์๋ฆผ์ด ์ค์ง ์์ต๋๋ค.
ํ์ธ ์ฌํญ
| ํ์ธ ํญ๋ชฉ | ์กฐ์น |
|---|---|
| ๊ธฐ๊ธฐ ์๋ฆผ ๊ถํ | ์ค์ > StudioGo > ์๋ฆผ ํ์ฉ ํ์ธ |
| ์ฑ ๋ด ์๋ฆผ ์ค์ | StudioGo ์ฑ ์ค์ > ์๋ฆผ ์ค์ ํ์ธ |
| ๋ฐฉํด ๊ธ์ง ๋ชจ๋ | ๊ธฐ๊ธฐ์ ๋ฐฉํด ๊ธ์ง ๋ชจ๋ ํด์ |
| Expo ํธ์ ํ ํฐ | ์ฑ ์ฌ์ค์น๋ก ํ ํฐ ๊ฐฑ์ |
๊ด๋ฆฌ์ ์กฐ์น
- Expo ํธ์ ๋์๋ณด๋์์ ๋ฐ์ก ์ด๋ ฅ ํ์ธ
- ์คํจํ ํธ์์ ์๋ฌ ์ฝ๋ ํ์ธ (DeviceNotRegistered, InvalidCredentials ๋ฑ)
- ํ ํฐ ๊ฐฑ์ ๋ฐฐ์น๊ฐ ์ ์ ๋์ํ๋์ง ํ์ธ
์นด์นด์ค ์๋ฆผํก ๋ฏธ์์
์ฆ์
์๋ฆผํก์ด ์นด์นด์คํก์ผ๋ก ์์ ๋์ง ์์ต๋๋ค.
ํ์ธ ์ฌํญ
| ํ์ธ ํญ๋ชฉ | ์กฐ์น |
|---|---|
| ์นด์นด์คํก ์ค์น ์ฌ๋ถ | ์นด์นด์คํก ๋ฏธ์ค์น ์ ์๋ฆผํก ์์ ๋ถ๊ฐ |
| ์ ํ๋ฒํธ ์ผ์น | ์นด์นด์ค ๊ณ์ ์ ์ ํ๋ฒํธ์ StudioGo ๋ฑ๋ก ๋ฒํธ ์ผ์น ํ์ธ |
| ์นด์นด์ค ์ฑ๋ ์ฐจ๋จ | ์นด์นด์คํก์์ StudioGo ์ฑ๋์ด ์ฐจ๋จ๋์ง ์์๋์ง ํ์ธ |
| ์๋ฆผํก ๋ฐ์ก ํ๋ | ์ผ์ผ ๋ฐ์ก ํ๋ ์ด๊ณผ ์ฌ๋ถ ํ์ธ (๊ด๋ฆฌ์) |
์์ฝ ์ํ ๋ถ์ผ์น
์ฆ์
์ฑ์ ํ์๋๋ ์์ฝ ์ํ์ ์ค์ ์ํ๊ฐ ๋ค๋ฆ ๋๋ค. ์: ์ด๋ฏธ ์น์ธ๋ ์์ฝ์ด ์ฑ์์๋ ์ฌ์ ํ ๋๊ธฐ๋ก ํ์๋ฉ๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ
- ์ฑ์ ์์ ํ ์ข ๋ฃํ๊ณ ์ฌ์์ํฉ๋๋ค
- ์์ฝ ๋ชฉ๋ก ํ๋ฉด์์ ์๋๋ก ๋น๊ฒจ ์๋ก๊ณ ์นจํฉ๋๋ค
- ๋ฌธ์ ๊ฐ ์ง์๋๋ฉด ์ฑ ์บ์๋ฅผ ์ญ์ ํฉ๋๋ค
๊ด๋ฆฌ์ ์กฐ์น
- API ์๋ต ์บ์ ์ค์ ํ์ธ (์บ์ TTL์ด ๋๋ฌด ๊ธด ๊ฒฝ์ฐ)
- DB ์กฐํ ์ฟผ๋ฆฌ์์ ์ํ ํํฐ๋ง ์ค๋ฅ ์ฌ๋ถ ํ์ธ
๋ก๊ทธ ํ์ธ ๋ฐฉ๋ฒ
์๋ฒ ๋ก๊ทธ (Vercel)
Hono API๋ Vercel Serverless Functions๋ก ๋ฐฐํฌ๋์ด ์์ต๋๋ค.
- Vercel ๋์๋ณด๋ย ์ ๋ก๊ทธ์ธํฉ๋๋ค
- StudioGo ํ๋ก์ ํธ๋ฅผ ์ ํํฉ๋๋ค
- Logs ํญ์์ ์ค์๊ฐ ๋ก๊ทธ๋ฅผ ํ์ธํฉ๋๋ค
์ฃผ์ ๋ก๊ทธ ํํฐ
| ํํฐ | ์ฉ๋ |
|---|---|
level:error | ์๋ฌ ๋ก๊ทธ๋ง ํํฐ๋ง |
path:/api/bookings | ์์ฝ ๊ด๋ จ API ํธ์ถ๋ง ํํฐ๋ง |
path:/api/auth | ์ธ์ฆ ๊ด๋ จ API ํธ์ถ๋ง ํํฐ๋ง |
path:/api/slots | ์ฌ๋กฏ ๊ด๋ จ API ํธ์ถ๋ง ํํฐ๋ง |
status:5xx | ์๋ฒ ์๋ฌ ์๋ต๋ง ํํฐ๋ง |
DB ๋ก๊ทธ (Neon)
- Neon ์ฝ์ย ์ ๋ก๊ทธ์ธํฉ๋๋ค
- StudioGo ํ๋ก์ ํธ๋ฅผ ์ ํํฉ๋๋ค
- Monitoring ํญ์์ ์ฟผ๋ฆฌ ์ฑ๋ฅ๊ณผ ์ฐ๊ฒฐ ์ํ๋ฅผ ํ์ธํฉ๋๋ค
์ฃผ์ ํ์ธ ํญ๋ชฉ
| ํญ๋ชฉ | ์ ์ ๊ธฐ์ค | ์ด์ ์งํ |
|---|---|---|
| ์ฐ๊ฒฐ ์ | 10๊ฐ ๋ฏธ๋ง | 50๊ฐ ์ด์์ด๋ฉด ์ปค๋ฅ์ ํ ์ค์ ํ์ธ |
| ์ฟผ๋ฆฌ ์๋ต ์๊ฐ | 100ms ๋ฏธ๋ง | 500ms ์ด์์ด๋ฉด ์ธ๋ฑ์ค ํ์ธ |
| ์๋ฌ์จ | 0% | 1% ์ด์์ด๋ฉด ์ฟผ๋ฆฌ/์คํค๋ง ์ ๊ฒ |
์ฑ ๋ก๊ทธ (Expo)
๊ฐ๋ฐ ํ๊ฒฝ์์ Expo DevTools๋ฅผ ํตํด ํด๋ผ์ด์ธํธ ๋ก๊ทธ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
# ๊ฐ๋ฐ ์๋ฒ์์ ๋ก๊ทธ ํ์ธ
npx expo start --dev-clientํ๋ก๋์ ์ฑ์ ํฌ๋์ ๋ก๊ทธ๋ Expo Application Services(EAS)์์ ํ์ธํฉ๋๋ค.
๋ฐ์ดํฐ ์ ํฉ์ฑ ์ฒดํฌ
์ ํฉ์ฑ ๋ฌธ์ ์ ํ
| ์ ํ | ์ค๋ช | ์ํฅ |
|---|---|---|
| ์ ๋ น Hold | Hold๊ฐ ๋ง๋ฃ๋์์ผ๋ DB์ ๋จ์ ์์ | ๊ฐ์ฉ ์ฌ๋กฏ์ด ์ค์ด ๋ณด์ |
| ์ํ ๋ถ์ผ์น | ์์ฝ ์ํ์ ์ฌ๋กฏ ์ํ๊ฐ ๋ถ์ผ์น | ์ด์ค ์์ฝ ๊ฐ๋ฅ์ฑ |
| ๊ณ ์ ์์ฝ | ์ญ์ ๋ ์คํ๋์ค์ ์์ฝ์ด ๋จ์ ์์ | ์ฌ์ฉ์ ํผ๋ |
| ์๊ฐ๋ ์ค๋ฅ | ์๋ฒ/ํด๋ผ์ด์ธํธ ์๊ฐ๋ ๋ถ์ผ์น | ์๋ชป๋ ์๊ฐ์ ์ฌ๋กฏ ํ์ |
SQL ์ ๊ฒ ์ฟผ๋ฆฌ
Neon ์ฝ์์ SQL Editor์์ ๋ค์ ์ฟผ๋ฆฌ๋ฅผ ์คํํ์ฌ ์ ํฉ์ฑ์ ํ์ธํฉ๋๋ค.
๋ง๋ฃ๋ Hold ํ์ธ
-- ๋ง๋ฃ ์๊ฐ์ด ์ง๋ Hold ์ํ ์ฌ๋กฏ ์กฐํ
SELECT s.id, s.studio_id, s.start_time, s.hold_expires_at
FROM slots s
WHERE s.status = 'HOLD'
AND s.hold_expires_at < NOW();์ํ ๋ถ์ผ์น ํ์ธ
-- ์์ฝ์ ์ทจ์์ธ๋ฐ ์ฌ๋กฏ์ด ์ฌ์ ํ ์์ฝ ์ํ์ธ ๊ฑด
SELECT b.id AS booking_id, s.id AS slot_id,
b.status AS booking_status, s.status AS slot_status
FROM bookings b
JOIN slots s ON b.slot_id = s.id
WHERE b.status IN ('CANCELLED', 'REJECTED')
AND s.status = 'BOOKED';๊ณ ์ ์์ฝ ํ์ธ
-- ์ญ์ ๋ ์คํ๋์ค์ ๋จ์ ์๋ ๋ฏธ๋ ์์ฝ
SELECT b.id, b.studio_id, b.start_time, b.status
FROM bookings b
LEFT JOIN studios st ON b.studio_id = st.id
WHERE st.id IS NULL
AND b.start_time > NOW();์ ํฉ์ฑ ๋ณต๊ตฌ
๋ฌธ์ ๊ฐ ๋ฐ๊ฒฌ๋๋ฉด ๋ค์ ์ ์ฐจ๋ก ๋ณต๊ตฌํฉ๋๋ค.
- ์ ๋ น Hold ์ ๋ฆฌ: ๋ง๋ฃ๋ Hold๋ฅผ AVAILABLE๋ก ๋ณ๊ฒฝ
UPDATE slots
SET status = 'AVAILABLE', hold_expires_at = NULL, hold_user_id = NULL
WHERE status = 'HOLD'
AND hold_expires_at < NOW();- ์ํ ๋ถ์ผ์น ๋ณต๊ตฌ: ์ทจ์/๊ฑฐ์ ๋ ์์ฝ์ ์ฌ๋กฏ์ AVAILABLE๋ก ๋ณ๊ฒฝ
UPDATE slots s
SET status = 'AVAILABLE'
FROM bookings b
WHERE s.id = b.slot_id
AND b.status IN ('CANCELLED', 'REJECTED')
AND s.status = 'BOOKED';- ๊ณ ์ ์์ฝ ์ ๋ฆฌ: ์ญ์ ๋ ์คํ๋์ค์ ๋ฏธ๋ ์์ฝ์ ์ทจ์ ์ฒ๋ฆฌ
UPDATE bookings b
SET status = 'CANCELLED', cancelled_at = NOW(), cancel_reason = '์คํ๋์ค ์ญ์ '
FROM (
SELECT b2.id
FROM bookings b2
LEFT JOIN studios st ON b2.studio_id = st.id
WHERE st.id IS NULL AND b2.start_time > NOW()
) orphan
WHERE b.id = orphan.id;์ ๊ธฐ ์ ๊ฒ ๊ถ์ฅ ์ฃผ๊ธฐ
| ์ ๊ฒ ํญ๋ชฉ | ๊ถ์ฅ ์ฃผ๊ธฐ | ์๋ํ ์ฌ๋ถ |
|---|---|---|
| ์ ๋ น Hold ์ ๋ฆฌ | ๋งค 5๋ถ | O (Cron Job) |
| ์ํ ๋ถ์ผ์น ํ์ธ | ๋งค์ผ ์๋ฒฝ 3์ | O (Cron Job) |
| ๊ณ ์ ์์ฝ ํ์ธ | ๋งค์ฃผ ์์์ผ | ์๋ |
| DB ๋ฐฑ์ ํ์ธ | ๋งค์ผ | O (Neon ์๋) |
๊ธด๊ธ ์ฐ๋ฝ์ฒ
์ฅ์ ๋ฐ์ ์ ์ฐ๋ฝ ์์
| ์์ | ๋ด๋น | ์ญํ | ์ฐ๋ฝ์ฒ |
|---|---|---|---|
| 1 | ์์คํ ๊ด๋ฆฌ์ | ์๋ฒ/DB ์ฅ์ ๋์ | ๋ด๋ถ Slack #studiogo-ops |
| 2 | ๋ฐฑ์๋ ๋ด๋น | API/๋น์ฆ๋์ค ๋ก์ง ์ด์ | ๋ด๋ถ Slack #studiogo-dev |
| 3 | ์นด์นด์ค ๊ธฐ์ ์ง์ | ์๋ฆผํก/OAuth ์ด์ | ์นด์นด์ค ๋น์ฆ๋์ค ๊ณ ๊ฐ์ผํฐย |
| 4 | Vercel ์ง์ | ๋ฐฐํฌ/์๋ฒ๋ฆฌ์ค ์ด์ | Vercel Supportย |
| 5 | Neon ์ง์ | DB ์ฐ๊ฒฐ/์ฑ๋ฅ ์ด์ | Neon Supportย |
| 6 | Expo ์ง์ | ์ฑ ๋น๋/ํธ์ ์ด์ | Expo Supportย |
์ฅ์ ๋์ ์ ์ฐจ
- ์ฆ์ ํ์ : ์ด๋ค ๊ธฐ๋ฅ์ด ์ํฅ ๋ฐ๋์ง ํ์ธํฉ๋๋ค
- ๋ฒ์ ํ๋จ: ์ ์ฒด ์ฅ์ ์ธ์ง, ํน์ ๊ธฐ๋ฅ ์ฅ์ ์ธ์ง ํ์ธํฉ๋๋ค
- ๋ก๊ทธ ํ์ธ: Vercel Logs, Neon Monitoring์์ ์๋ฌ๋ฅผ ํ์ธํฉ๋๋ค
- 1์ฐจ ์กฐ์น: ๊ฐ๋ฅํ ๊ฒฝ์ฐ ์ฆ์ ์กฐ์นํฉ๋๋ค (์ฌ๋ฐฐํฌ, ์บ์ ์ด๊ธฐํ ๋ฑ)
- ์ฌ์ฉ์ ๊ณต์ง: ์ฅ์ ์๊ฐ์ด 10๋ถ์ ์ด๊ณผํ๋ฉด ์ธ์ฑ ๊ณต์ง๋ฅผ ๋ฑ๋กํฉ๋๋ค
- ๊ทผ๋ณธ ์์ธ ๋ถ์: ์ฅ์ ํด์ ํ ์์ธ์ ๋ถ์ํ๊ณ ์ฌ๋ฐ ๋ฐฉ์ง ์กฐ์น๋ฅผ ์๋ฆฝํฉ๋๋ค
- ํฌ์คํธ๋ชจํ ์์ฑ: ์ฅ์ ํ์๋ผ์ธ, ์์ธ, ์กฐ์น ๋ด์ญ, ๊ฐ์ ์ฌํญ์ ๊ธฐ๋กํฉ๋๋ค