์คํฐ๋ ์ฐธ๊ฐ์ ํผ๋๋ฐฑ์ ํ๊ณณ์ ๋ชจ์ผ๋ ์ฌ์ดํธ. https://feedback.dalestudy.com
์คํฐ๋ยทํ๋ก์ ํธ(dalestudy.com/programs ์ ํ๋ก๊ทธ๋จ) ๋ฆฌ๋๋ง๋ค ๋ค๋ฅธ ๋๊ตฌ๋ก ํผ๋๋ฐฑ์ ๋ฐ๋ค ๋ณด๋ ์ง๋ ๊ธฐ์ ํผ๋๋ฐฑ์ ์ฐพ๊ธฐ๋, ๊ธฐ์ ๊ฐ ๋น๊ต๋ ์ด๋ ค์ ๋ค. GitHub ๋ก๊ทธ์ธ์ผ๋ก ์ค๋ณต ์๋ต์ ๋ง๊ณ , ์๋ต์ D1 ์ ์๋๋ค.
- TanStack Start (React) on Cloudflare Workers
- D1 (SQLite) + Drizzle
- daleui ๋์์ธ ์์คํ
- ๋ก๊ทธ์ธ: DaleStudy GitHub App ์ user-to-server OAuth
surveys โโฌโ questions
โโ responses โ answers
โโ survey_editors (survey_id, login) โ ์ค๋ฌธ์ ๊ณ ์น๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ ์ฌ๋
users โ sessions โ users.can_create_surveys: maintainer ํ์ด๋ฉด ์ ์ค๋ฌธ์ ๋ง๋ ๋ค
๊ด๊ณ์ ์ค๊ณ ์ด์ ๋ docs/erd.md, ํ ์ด๋ธ๋ณ ์ปฌ๋ผ๊ณผ ์์ ํ์ docs/tables.md ์ ์๋ค. ๋ฌด์์ ์ ๊ทธ๋ ๊ฒ ์ ํ๊ณ ๋ฌด์์ ๊ฐ์ํ๋์ง๋ docs/decisions.md ์ ๋ ์ง์์ผ๋ก ์๋๋ค. ๋ฏธ๋ค๋ ์ผ๋ ๊ทธ ๋ฌธ์ ๋์ ์๋ค.
์ค๋ฌธ์ ๊ธฐ์๋ ํ๋ก๊ทธ๋จ์ ๋งค์ด์ง ์๋๋ค. ๋งฅ๋ฝ์ ์ ๋ชฉ("๋ธ๋ก๊ทธ ์คํฐ๋ 1๊ธฐ ์ฐธ์ฌ ํ๊ณ ")์ด ๋ด๋๋ค. ๊ณต๊ฐ ๋ฒ์(listed)๊ฐ "ํ์ ๋ณด์ด๊ธฐ" ๋ฉด ๋ก๊ทธ์ธํ ๋๊ตฌ๋ ํ์์ ๋ณด๊ณ , "๋งํฌ๋ก๋ง" ์ด๋ฉด ๋งํฌ๋ก๋ง ๋ค์ด์จ๋ค.
์ฐธ๊ฐ์ ๋ช ๋จ์ ๋์ง ์๋๋ค. ์ค๋ฌธ ๋งํฌ๋ ํด๋น ํ๋ก๊ทธ๋จ ์ฑ๋์๋ง ๊ณต์ ๋๊ณ , ๋ตํ๋ ค๋ฉด GitHub ๋ก๊ทธ์ธ์ด ํ์ํ๋ฉฐ, ๊ฐ์ ์ฌ๋์ ์ค๋ณต ์๋ต์ ๋งํ๋ฏ๋ก ๋ช ๋จ์ด ์ฃผ๋ ์ถ๊ฐ ์์ ์ด DiscordโGitHub ๋งคํ์ ์ ์งํ๋ ๋น์ฉ๋ณด๋ค ์๋ค.
์๋ต์ responses.user_id ๋ก GitHub ๊ณ์ ๊ณผ ํจ๊ป ์ ์ฅํ๋ค. ๊ฒฐ๊ณผ ํ๋ฉด์ ๋๊ฐ ๋ตํ๋์ง ๋ณด์ฌ ์ฃผ์ง ์๊ณ ๋ต๋ง ๋ชจ์๋ค.
bun install
bun run cf-typegen # wrangler.jsonc ๋ฐ๋ ๋๋ง๋ค
bun run db:migrate:local
bun run db:seed:local seed/example.json
bun run dev # http://localhost:3000๋ก์ปฌ ์ํฌ๋ฆฟ์ .dev.vars ์ ๋๋ค (git ์ ์ฌ๋ผ๊ฐ์ง ์์).
GITHUB_CLIENT_ID=... # DaleStudy GitHub App ์ Client ID
GITHUB_CLIENT_SECRET=... # ๊ฐ์ ์ฑ์ Client secret
GitHub App ์ค์ ์ Callback URL ์ http://localhost:3000/auth/callback ์ด ๋ฑ๋ก๋ผ ์์ด์ผ ํ๋ค.
__Host- ์ ๋์ฌ ์ฟ ํค๋ Secure ๊ฐ ํ์๋ผ ๋ก์ปฌ ๊ฐ๋ฐ์ localhost ๋ฅผ secure context ๋ก ์ทจ๊ธํ๋ Chrome/Firefox ์์ ํ๋ค.
DaleStudy ์กฐ์ง์ maintainer ํ ๋ฉค๋ฒ๊ฐ ๋ก๊ทธ์ธํ๋ฉด ํค๋์ ๊ด๋ฆฌ ํญ(/manage)์ด ์๊ธฐ๊ณ ์ ์ค๋ฌธ์ ๋ง๋ค ์ ์๋ค. ํ ๋ฉค๋ฒ์ธ์ง๋ ๋ก๊ทธ์ธํ ๋ GitHub ์ ๋ฌผ์ด users.can_create_surveys ์ ์ ๋๋ค โ ํ์ด ๋ฐ๋๋ฉด ๋ค์ ๋ก๊ทธ์ธ ๋ ๋ฐ์๋๋ค. ์ค๋ฌธ์ ํธ์ง์๋ก ์ถ๊ฐ๋ ์ฌ๋์๊ฒ๋ ๊ด๋ฆฌ ํญ์ด ๋ณด์ธ๋ค(์๊ธฐ ์ค๋ฌธ๋ง).
์ ์ค๋ฌธ์ ์ ๋ชฉ๊ณผ ์ค๋ช
๋ง ๋ฐ๊ณ , id ๋ ์๋์ผ๋ก ๋ง๋ ๋ค(/V1StGXR8, nanoid 8์). ๋๋จธ์ง๋ ํธ์ง ํ๋ฉด์์ ์ ํ๋ค.
- ๋ฌธํญ ํญ: ์ผ์ชฝ ๋ชฉ๋ก ยท ๊ฐ์ด๋ฐ ํธ์ง ยท ์ค๋ฅธ์ชฝ ์๋ต ํ๋ฉด ๋ฏธ๋ฆฌ๋ณด๊ธฐ. ๊ณตํต ๋ฌธํญ์ ๊ณจ๋ผ ๋ฃ๊ฑฐ๋(
์ฐธ์ฌ ํ๊ณ ๊ธฐ๋ณธ ๋ฌธํญ ๋ฃ๊ธฐ) ์ง์ ์ด๋ค. ๊ณตํต ๋ฌธํญ์ ๋ฌธ๊ตฌ๋ ์ค๋ฌธ์ ๊ณตํต ๋ฌธํญ ๋ณ์(vars)๋ก ์ฑ์์ง๋ฉฐ ์์ผ๋ก ๊ณ ์น ์ ์๋ค. - ์ค์ ํญ: ์ค๋ช ยท๋ง๊ฐ์ผยท๊ณต๊ฐ ๋ฒ์ยท๊ณตํต ๋ฌธํญ ๋ณ์ยทํธ์ง์.
์๋ต์ด 1๊ฑด์ด๋ผ๋ ๋ค์ด์ค๋ฉด ๋ฌธํญ๊ณผ ๋ณ์๋ ์ ๊ธฐ๊ณ ์ ๋ชฉยท์ค๋ช ยท๋ง๊ฐ์ผยท๊ณต๊ฐ ๋ฒ์๋ง ๊ณ ์น ์ ์๋ค. ์ค๋ฌธ ์ญ์ ๋ ์๋ต์ด ์์ ๋๋ง ๋๋ค.
๋ก์ปฌ D1 ์ ์ค๋ฌธ์ ๋ฃ์ ๋ seed/ ์ JSON ์ ์ด๋ค. seed/example.json ์ด ํ์ ์ค๋ช
์ด๋ค. editors ๊ฐ ํธ์ง์, survey.id ๋ฅผ ์๋ตํ๋ฉด ์๋์ผ๋ก ๋ง๋ ๋ค.
bun run db:seed:local seed/blog01-final.json๊ฐ์ id ์ ์ค๋ฌธ์ด ์ด๋ฏธ ์์ผ๋ฉด ์คํจํ๋ค.
seed ์ ๋ฌธํญ์ ๋ ์ข ๋ฅ๋ค.
{ "common": "goal_achieved" }โsrc/questions/common.ts์ ๊ณตํต ๋ฌธํญ. ๋ชจ๋ ํ๋ก๊ทธ๋จ์ด ๊ฐ์key๋ก ๋ฌป๋๋ค. ๋ฌธ๊ตฌ ์{program},{activity}๊ฐ์ ์๋ฆฌํ์์๋ ์ค๋ฌธ์vars๋ก ์ฑ์ด๋ค. ํ๋ก๊ทธ๋จ๋ณ ๊ฐ์ docs/questions.md ์ฐธ๊ณ . ์ค๋ฌธ๋ผ๋ฆฌ ๋น๊ต๋ ์ดkey๋ก ํ๋ค. ๊ณตํต ๋ฌธํญ ๋ฌธ๊ตฌ๋ฅผ ๊ณ ์น๋ฉด ์ด์ ์ค๋ฌธ๊ณผ ๋น๊ต๊ฐ ๊นจ์ง๋ฏ๋ก ์ ์คํ.{ "type": "long", "label": "โฆ" }โ ์ด ์ค๋ฌธ๋ง์ ๋ฌธํญ.key๋ ๋น์ด ์๋ค.
๊ณตํต ๋ฌธํญ์ required ๋ง, ์ง์ ๋ฌธํญ์ required(๊ธฐ๋ณธ true)์ config ๋ฅผ ์ค ์ ์๋ค. ์ ํ์ scale, short, long, choice ๋ค ๊ฐ์ง.
๊ฐ ์ ํ์ ์ ์ฅ๊ฐยท๊ฒ์ฆยทconfigยท๊ณตํต ๋ฌธํญ ๋ชฉ๋กยท์ ํ ์ถ๊ฐ ์ ์ฐจ๋ docs/questions.md ์ ์๋ค.
# src/db/schema.ts ์์ ํ
bunx drizzle-kit generate --name <์ค๋ช
>
bun run db:migrate:localmain ์ push ํ๋ฉด Cloudflare Workers Builds ๊ฐ bun run build โ npx wrangler deploy ๋ฅผ ์คํํ๋ค.
๋ค๋ฅธ ๋ธ๋์น๋ฅผ push ํ๋ฉด ํ๋ฆฌ๋ทฐ ๋น๋๊ฐ ๋๋ค. bun run deploy ๋ ์๋ ๋ฐฐํฌ๊ฐ ์ ๋ ๋์ ์๋ fallback.
์ด๋ฏธ ์ค์ ๋ ๊ฒ (๋ค์ ๋ง๋ค ํ์ ์์):
- D1
feedback(APAC) โ id ๋wrangler.jsonc์ ์์ - ์ํฌ๋ฆฟ
GITHUB_CLIENT_ID,GITHUB_CLIENT_SECRET - ์ปค์คํ
๋๋ฉ์ธ
feedback.dalestudy.com(wrangler.jsonc์routes) - Workers Builds โ
DaleStudy/feedback์ฐ๊ฒฐ. ๋น๋ ๋ณ์BUN_VERSION=1.4.0(๋น๋ ์ด๋ฏธ์ง ๊ธฐ๋ณธ bun 1.2.15 ๋ lockfile v2 ๋ฅผ ๋ชป ์ฝ๋๋ค. ๋ก์ปฌ bun ์ ์ฌ๋ฆฌ๋ฉด ๊ฐ์ด ์ฌ๋ฆฐ๋ค) - GitHub App Callback URL:
http://localhost:3000/auth/callback,https://feedback.dalestudy.com/auth/callback - GitHub App ์ ๊ณต๊ฐ(public) ์ฌ์ผ ํ๋ค. ๋น๊ณต๊ฐ ์ฑ์ ์์ ์กฐ์ง ๋ฉค๋ฒ๋ง authorize ํ ์ ์์ด์ ์กฐ์ง ๋ฐ ๊ณ์ ์ GitHub ์ authorize ํ์ด์ง์์ 404 ๋ฅผ ๋ณธ๋ค (์ฐ๋ฆฌ ๋ก๊ทธ์ ์๋ฌด๊ฒ๋ ์ ๋จ๋๋ค). Advanced โ Make public. ์ฐธ๊ฐ์๋ฅผ ์กฐ์ง ๋ฉค๋ฒ๋ก ์ ํํ๋ ค๋ฉด ํ๋ก๊ทธ๋จ ์ฐธ์ฌ ์ ์ฐจ์ ์กฐ์ง ์ด๋๊ฐ ๋จผ์ ๋ค์ด๊ฐ์ผ ํ๋ค โ ๋ธ๋ก๊ทธ ์คํฐ๋ 1๊ธฐ ์ฐธ๊ฐ์์ 40% ๋ ์กฐ์ง ๋ฉค๋ฒ๊ฐ ์๋๋ค.
์คํค๋ง๊ฐ ๋ฐ๋๋ฉด ๋ฐฐํฌ ์ ์ bun run db:migrate:remote ๋ฅผ ์ง์ ์คํํ๋ค.