Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

ย 

History

108 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

aolda-ahp-backend

์ด ํ”„๋กœ์ ํŠธ๋Š” team, cloud, health ๊ณต๊ฐœ API๋ฅผ ์ œ๊ณตํ•˜๋Š” TypeScript + Fastify ๋ฐฑ์—”๋“œ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ๋Š” ์‹ค์ œ DB ์—ฐ๋™์„ ๋„ฃ๊ธฐ ์ „์ด๋ฏ€๋กœ, ๊ธฐ์กด ์‘๋‹ต์„ ์œ ์ง€ํ•˜๋ฉด์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๋กœ ์„ค๊ณ„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ team ๋ชจ๋“ˆ์€ Notion์„ ์›์ฒœ ๋ฐ์ดํ„ฐ์†Œ์Šค๋กœ ์‚ฌ์šฉํ•˜๋ฉด์„œ, ์กฐํšŒ ๋กœ์ง๊ณผ ๋ฐ์ดํ„ฐ ํ•ด์„ ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๋ฆฌํŒฉํ„ฐ๋ง ์ค‘์ž…๋‹ˆ๋‹ค.

์ด ๋ฌธ์„œ๋ฅผ ๋ณด๋Š” ์ดˆ๋ณด์ž์šฉ ๊ฐ€์ด๋“œ

ํ”„๋กœ์ ํŠธ๋ฅผ ์ฒ˜์Œ ์—ด์—ˆ์„ ๋•Œ, ์–ด๋–ค ํŒŒ์ผ์ด ๋ฌด์—‡์„ ํ•˜๋Š”์ง€ ํ•œ ๋ฒˆ์— ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ์€ ์š”์ฒญ์ด ์„œ๋ฒ„์—์„œ ์ฒ˜๋ฆฌ๋˜๋Š” ์ˆœ์„œ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ์š”์ฒญ
  โ””โ”€> Route(API ์—”๋“œํฌ์ธํŠธ)
        โ””โ”€> Service(์œ ์Šค์ผ€์ด์Šค/๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™)
              โ””โ”€> Repository(์กฐํšŒ ์‹œ๋‚˜๋ฆฌ์˜ค ์กฐํ•ฉ)
                    โ””โ”€> Fetcher(์™ธ๋ถ€ API / DB ํ˜ธ์ถœ)
                          โ””โ”€> Extractor(์ˆœ์ˆ˜ ํ•จ์ˆ˜ ๊ธฐ๋ฐ˜ ๊ฐ’ ์ถ”์ถœ)
                                โ””โ”€> ์‘๋‹ต ๋ฐ˜ํ™˜

1) ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๋ฅผ ๋จผ์ € ์ดํ•ดํ•˜๊ธฐ

src/ ๋ฃจํŠธ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์—ญํ• ๋ณ„๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.

src/
  common/
    config/
      env.ts
  constants/
    team.ts
    cloud.ts
    schemas.ts
  routes/
    health.ts
    team.ts
    cloud.ts
  modules/
    team/
      services/
      repositories/
      datasources/
      notion/
        fetchers/
        extractors/
        parsers/
        assemblers/
    cloud/
      services/
      repositories/
      datasources/
    internal-example/
      routes/
      services/
      repositories/
      datasources/
  server.ts
prisma/
  schema.prisma
  • README์—์„œ ๋ฌธ์„œ๊ฐ€ ๊ธธ์–ด์ง€๋Š” ๋Œ€์‹ , ์‹ค์ œ ๋™์ž‘์„ ๊ธฐ์ค€์œผ๋กœ ํŒŒ์ผ์„ ์ฝ์œผ๋ฉด ์ดํ•ด๊ฐ€ ๋น ๋ฆ…๋‹ˆ๋‹ค.
  • ๊ณต๊ฐœ API๋Š” routes์— ์„ ์–ธ๋˜์–ด ์žˆ๊ณ , ์‹ค์ œ ๋™์ž‘์€ modules์—์„œ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

2) ํด๋” ์—ญํ•  (ํ•œ ์ค„๋กœ ์š”์•ฝ)

  • src/server.ts
    • ์•ฑ์„ ์ƒ์„ฑํ•˜๊ณ , ํ”Œ๋Ÿฌ๊ทธ์ธ(CORS, Swagger), ๋ผ์šฐํŠธ ๋“ฑ๋ก, ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๋กœ๊น…์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
  • src/routes/*
    • HTTP ์š”์ฒญ์„ ๋ฐ›์•„ ๋ฌธ์„œํ™”(Swagger)ํ•˜๊ณ , Service๋ฅผ ํ˜ธ์ถœํ•ด ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ์ด๊ณณ์€ DB/API ์ง์ ‘ ์ ‘๊ทผ์„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • src/modules/<๋„๋ฉ”์ธ>/services/*
    • ํŒ€ ์กฐํšŒ, ํด๋ผ์šฐ๋“œ ์กฐํšŒ ๊ฐ™์€ ์—…๋ฌด ๊ทœ์น™์ด ๋ฐฐ์น˜๋  ์žฅ์†Œ์ž…๋‹ˆ๋‹ค.
    • ํ˜„์žฌ๋Š” Repository ํ˜ธ์ถœ๋งŒ ๋ž˜ํ•‘ํ•˜๊ณ , ํ–ฅํ›„ ์ •์ฑ…/๊ฒ€์ฆ ๋กœ์ง์„ ๋„ฃ์„ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.
  • src/modules/<๋„๋ฉ”์ธ>/repositories/*
    • ๋ฐ์ดํ„ฐ ์กฐํšŒ ๊ณ„์•ฝ(์ธํ„ฐํŽ˜์ด์Šค)์ž…๋‹ˆ๋‹ค.
    • Service๋Š” ์ด ๊ณ„์•ฝ๋งŒ ์•Œ๋ฉด ๋˜๊ณ , ์‹ค์ œ ๊ตฌํ˜„์ฒด๋Š” ๋ฐ”๋€Œ์–ด๋„ ์„œ๋น„์Šค๋Š” ์˜ํ–ฅ์ด ์ ์Šต๋‹ˆ๋‹ค.
  • src/modules/<๋„๋ฉ”์ธ>/datasources/*
    • mock์€ ํ˜„์žฌ ๋”๋ฏธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • prisma๋Š” ๋‚˜์ค‘์— ์‹ค์ œ DB ์กฐํšŒ๋กœ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ๋Š” ์ค€๋น„๋ถ€์ž…๋‹ˆ๋‹ค.
  • src/modules/team/notion/fetchers/*
    • Notion SDK ํ˜ธ์ถœ๋งŒ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
    • dataSources.query, blocks.children.list ๊ฐ™์€ I/O๋ฅผ ์ด ๊ณ„์ธต์— ๋‘ก๋‹ˆ๋‹ค.
    • CrewFetcher๋Š” page + profileImageUrl + description ๊ฐ™์€ raw source๋งŒ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ActivityFetcher๋Š” project/study datasource๋ฅผ ๊ฐ๊ฐ ์กฐํšŒํ•œ ๋’ค, repository๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋ณ‘ํ•ฉํ•  ์ˆ˜ ์žˆ๋„๋ก page ๊ธฐ๋ฐ˜ raw source๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ์ž„์› lookup์ฒ˜๋Ÿผ ๋ณ„๋„ ๋ณด์กฐ ๋ฐ์ดํ„ฐ์†Œ์Šค๋„ ์ „์šฉ fetcher๋กœ ๋ถ„๋ฆฌํ•ด ์กฐํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  • src/modules/team/notion/extractors/*
    • ์ด๋ฏธ ์กฐํšŒํ•œ page/block์—์„œ ํ•„์š”ํ•œ ๊ฐ’์„ ์ฝ๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜ ๊ณ„์ธต์ž…๋‹ˆ๋‹ค.
    • ๋„คํŠธ์›Œํฌ ํ˜ธ์ถœ ์—†์ด ์ž…๋ ฅ๊ฐ’๋งŒ ๋ฐ›์•„ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • src/modules/team/notion/parsers/*
    • Notion์˜ raw page๋ฅผ ํŒ€ ๋„๋ฉ”์ธ์—์„œ ์“ฐ๊ธฐ ์‰ฌ์šด ์ค‘๊ฐ„ ํ˜•ํƒœ๋กœ ํ•ด์„ํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ: activity page์˜ ์ƒํƒœ๊ฐ’, ์‹œ์ž‘ํ•™๊ธฐ, activity type ํŒ๋ณ„
  • src/modules/team/notion/assemblers/*
    • parser/fetcher ๊ฒฐ๊ณผ๋ฅผ ์ตœ์ข… REST ์‘๋‹ต ํ˜•ํƒœ๋กœ ์กฐ๋ฆฝํ•ฉ๋‹ˆ๋‹ค.
    • ์ด ๊ณ„์ธต์€ ์‘๋‹ต shape๋ฅผ ์•Œ์ง€๋งŒ, ์ง์ ‘ ์™ธ๋ถ€ API๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    • crew์˜ ๊ฒฝ์šฐ repository๊ฐ€ ์—ฌ๋Ÿฌ source์™€ supplement๋ฅผ aggregate๋กœ ๋ฌถ๊ณ , assembler๊ฐ€ ๊ทธ aggregate๋ฅผ ์‘๋‹ต DTO๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • activity/project๋„ parser๊ฐ€ page๋ฅผ ํ•ด์„ํ•˜๊ณ , repository๊ฐ€ mock supplement์™€ aggregate๋ฅผ ์กฐํ•ฉํ•œ ๋’ค assembler๊ฐ€ ์‘๋‹ต์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • prisma/schema.prisma
    • Prisma ์Šคํ‚ค๋งˆ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.
    • ํ˜„์žฌ๋Š” CrewProfileImageCache, TeamActivityMetadata ๊ฐ™์€ ์šด์˜ ๋ณด์กฐ ํ…Œ์ด๋ธ”์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
    • TeamActivityMetadata๋Š” team ํ™œ๋™์˜ ์•ˆ์ •์ ์ธ activityId์™€ ๊ด€๋ฆฌ์ž ๋ณด์ • ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ์šฉ๋„์ž…๋‹ˆ๋‹ค.
  • src/constants/*
    • ํ˜„์žฌ ๊ณต๊ฐœ API ์‘๋‹ต ํ˜•์‹(์˜คํƒˆ์ž ํ‚ค ํฌํ•จ)์„ ๋ณด์กดํ•˜๊ธฐ ์œ„ํ•œ ๊ณ ์ • ์˜ˆ์‹œ ๋ฐ์ดํ„ฐ/์Šคํ‚ค๋งˆ์ž…๋‹ˆ๋‹ค.

3) ์™œ team/cloud ๊ตฌ์กฐ๊ฐ€ ๋ถ„๋ฆฌ๋˜์—ˆ๋Š”๊ฐ€?

ํ˜„์žฌ ๊ณต๊ฐœ API๋Š” ๋ฐ”๋€Œ๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‚ด๋ถ€ ๊ตฌํ˜„์€ ๋ฐ”๋€Œ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ๋ฐ”๋กœ๊ฐ€๊ธฐ์— ํ•„์š”ํ•œ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.

  • ๊ณต๊ฐœ API ํ˜ธํ™˜์„ฑ์€ routes์™€ constants ์‘๋‹ต ์ƒ˜ํ”Œ ๊ธฐ์ค€์œผ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.
  • ์‹ค์ œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋Š” datasource๋งŒ ๋ฐ”๊พธ๋ฉด ๋˜๋„๋ก ๊ณ„์ธต์„ ๋ถ„๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.
  • USE_MOCK_DATA๋ฅผ ํ†ตํ•ด ๊ณต๊ฐœ ์‘๋‹ต ์œ ์ง€ ์ƒํƒœ์—์„œ ์ ์ง„์ ์œผ๋กœ ์ „ํ™˜ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

3-1) Team Notion ๋ฆฌํŒฉํ„ฐ๋ง ๋ฐฉํ–ฅ

ํ˜„์žฌ team ๋ชจ๋“ˆ์€ ์•„๋ž˜ ๋ฐฉํ–ฅ์œผ๋กœ ๊ตฌ์กฐ๋ฅผ ์ •๋ฆฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  • fetcher๋Š” Notion API๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  • fetcher๋Š” ์ตœ์ข… ์‘๋‹ต์ด ์•„๋‹ˆ๋ผ raw source๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • extractor๋Š” Notion page/block์—์„œ ํ•„์š”ํ•œ ๊ฐ’์„ ์ฝ์Šต๋‹ˆ๋‹ค.
  • parser๋Š” raw Notion ๊ฐ์ฒด๋ฅผ ๋„๋ฉ”์ธ ์นœํ™”์ ์ธ ๊ฐ’์œผ๋กœ ํ•ด์„ํ•ฉ๋‹ˆ๋‹ค.
  • assembler๋Š” ์ตœ์ข… REST ์‘๋‹ต์„ ์กฐ๋ฆฝํ•ฉ๋‹ˆ๋‹ค.
  • repository๋Š” ์—ฌ๋Ÿฌ fetch ๊ฒฐ๊ณผ๋ฅผ ์กฐํ•ฉํ•ด ํ•˜๋‚˜์˜ ์กฐํšŒ ํ๋ฆ„์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • repository๋Š” cross-source ๊ฐ’์ด๋‚˜ ์•„์ง ๋ฏธ์—ฐ๋™๋œ ๊ฐ’์˜ mock supplement๋„ ์ด ๋‹จ๊ณ„์—์„œ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • activity/project์˜ activityId, en, brief, description์€ TeamActivityMetadata ํ…Œ์ด๋ธ”์„ source of truth๋กœ ์‚ฌ์šฉํ•˜๊ณ , Notion์€ ํ™œ๋™ ์กด์žฌ ์—ฌ๋ถ€์™€ live ์ƒํƒœ ํ•„๋“œ ํ™•์ธ์šฉ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • crewLog๋Š” Crew Book ๊ณ„์ •(ํ”„๋กœํ•„) people -> ์ž„์› lookup datasource์˜ people ํ•„๋“œ ๋งค์นญ์œผ๋กœ role์„ ์กฐํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  • crewLog.department๋Š” Crew Book ์ž‘์„ฑ๊ธฐ์ˆ˜ -> ํ™œ๋™ํ•™๊ธฐ/๊ธฐ์ˆ˜ ๋งคํ•‘ datasource -> ํ•ด๋‹น ๊ธฐ์ˆ˜์˜ Crew Book ํŒ€ ํ•„๋“œ ํ๋ฆ„์œผ๋กœ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
  • lookup์— ์—†๋Š” ๊ธฐ์ˆ˜๋Š” ์ผ๋ฐ˜ ํ™œ๋™ํšŒ์› ์ด๋ ฅ์œผ๋กœ fallback ํ•ฉ๋‹ˆ๋‹ค.
  • ํ˜„์žฌ role ์ฝ”๋“œ๋Š” ํšŒ์žฅ -> CREW_ROLE/P, ๋ถ€ํšŒ์žฅ -> CREW_ROLE/VP, ์ด๋ฌด -> CREW_ROLE/EA, ์ผ๋ฐ˜ ํฌ๋ฃจ์› -> CREW_ROLE/CREW๋กœ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค.
  • ํ˜„์žฌ department ์ฝ”๋“œ๋Š” ์ž„์›์ง„ -> DEPARTMENT_TYPE/CLEVEL, ๊ฐœ๋ฐœํŒ€ -> DEPARTMENT_TYPE/DEV, ์ธํ”„๋ผ๊ฐœ๋ฐœํŒ€ -> DEPARTMENT_TYPE/INFRA_DEV, ์ธํ”„๋ผํŒ€ -> DEPARTMENT_TYPE/INFRA, ์šด์˜์ง€์›ํŒ€ -> DEPARTMENT_TYPE/GA, ๋””์ž์ธํŒ€ -> DEPARTMENT_TYPE/DESIGN์œผ๋กœ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด GET /team/crew๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ๋ฆ„์œผ๋กœ ์ฝ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

route/team.ts
  -> TeamQueryService
  -> TeamRealRepository
  -> CrewFetcher
  -> crew-page.extractor / notion-block.extractor
  -> repository aggregate composition
  -> crew-response.assembler

GET /team/activity, GET /team/project๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ ์กฐ๊ธˆ ๋” ์„ธ๋ถ„ํ™”๋ฉ๋‹ˆ๋‹ค.

route/team.ts
  -> TeamQueryService
  -> TeamRealRepository
  -> ActivityFetcher(raw sources from project datasource)
  -> ActivityFetcher(raw sources from study datasource)
  -> repository merge in memory
  -> repository aggregate composition
  -> activity-page.parser
  -> activity-response.assembler or project-response.assembler

ํ˜„์žฌ ์‹ค์ œ ํ˜ธ์ถœ์Šคํƒ์€ ์•„๋ž˜์ฒ˜๋Ÿผ ์ดํ•ดํ•˜๋ฉด ๊ฐ€์žฅ ์ •ํ™•ํ•ฉ๋‹ˆ๋‹ค.

  • GET /team/crew
    • route -> service -> TeamRealRepository -> CrewFetcher(raw sources) -> extractors -> repository aggregate composition -> crew-response.assembler
  • GET /team/activity
    • route -> service -> TeamRealRepository -> project/study ActivityFetcher(raw sources) -> repository merge in memory -> activity-page.parser -> repository aggregate composition -> activity-response.assembler
  • GET /team/project
    • route -> service -> TeamRealRepository -> project/study ActivityFetcher(raw sources) -> repository merge in memory -> activity-page.parser -> repository aggregate composition -> project-response.assembler

์ฆ‰ ํ˜„์žฌ activity list๋Š” project datasource์™€ study datasource๋ฅผ ๊ฐ๊ฐ ์ฝ์€ ๋’ค ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋ณ‘ํ•ฉํ•˜๊ณ , project list๋Š” ๊ทธ ๋ณ‘ํ•ฉ ๊ฒฐ๊ณผ ์ค‘ ACTIVITY_TYPE/PROJECT๋กœ ํŒ๋ณ„๋œ ํ•ญ๋ชฉ๋งŒ ์ถ”๋ ค ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

4) ๊ณต๊ฐœ API ๋ชฉ๋ก

Team

  • GET /team/crew
    • ์‘๋‹ต์—๋Š” total, keys, data๊ฐ€ ํ•จ๊ป˜ ๋‚ด๋ ค๊ฐ€๋ฉฐ, keys์—๋Š” ํ•ด๋‹น ์‘๋‹ต์—์„œ ์‹ค์ œ ์‚ฌ์šฉ๋œ crewLog.department / crewLog.type key-value ๋งคํ•‘์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
  • GET /team/department
    • ์ „์ฒด crewLog.department key-value ์‚ฌ์ „์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • GET /team/crewtype
    • ์ „์ฒด crewLog.type key-value ์‚ฌ์ „์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • GET /team/activity
  • PATCH /team/activity/:activity_id/metadata
    • enName, briefName, description์„ DB ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
    • ํ˜„์žฌ๋Š” ์ธ์ฆ/์ธ๊ฐ€๊ฐ€ ๋ถ™์ง€ ์•Š์€ ์ƒํƒœ์ด๋ฏ€๋กœ ์šด์˜ ์ ์šฉ ์ „ ๋ณดํ˜ธ ์žฅ์น˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • GET /team/crew/:crew_id
  • GET /team/project
  • GET /team/project/:project_id

Cloud

  • GET /cloud/brief
  • GET /cloud/use_project
  • GET /cloud/qna
  • GET /cloud/notice
  • GET /cloud/notice/:notice_id
  • GET /cloud/product
  • GET /cloud/product/:product_id

Health

  • GET /health

๋‚ด๋ถ€ ํ•™์Šต์šฉ(๊ฐœ๋ฐœ ์ „์šฉ)

  • GET /internal/example/architecture-check
  • NODE_ENV=development์ผ ๋•Œ๋งŒ ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

5) ์ฒ˜์Œ ์‹คํ–‰ํ•˜๊ธฐ (์ดˆ์‹ฌ์ž์šฉ)

  • Node.js: 20.x
  • npm ์„ค์น˜
npm install

๊ฐœ๋ฐœ ์‹คํ–‰

npm run dev

ํƒ€์ž… ์ฒดํฌ

npm run typecheck

๋นŒ๋“œ

npm run build

์‹คํ–‰

npm run start

๊ธฐ๋ณธ ํฌํŠธ: 8001

์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์—”๋“œํฌ์ธํŠธ
http://localhost:8001/docs
http://localhost:8001/openapi.json

6) ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ฐ€์ด๋“œ

๊ณตํ†ต ํ™˜๊ฒฝ

  • NODE_ENV
    • development๋ฉด ๋‚ด๋ถ€ ์˜ˆ์‹œ API๊ฐ€ ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  • CORS_ALLOW_ORIGINS
    • ์‰ผํ‘œ ๊ตฌ๋ถ„ ๋ฌธ์ž์—ด
  • CORS_ALLOW_METHODS
  • CORS_ALLOW_HEADERS
  • CORS_ALLOW_CREDENTIALS
  • USE_MOCK_DATA
    • true: mock datasource ์‚ฌ์šฉ(๊ธฐ๋ณธ)
    • false: prisma datasource ์‚ฌ์šฉ(ํ˜„์žฌ๋Š” ๋™์ผ ๋”๋ฏธ ๋ฐ˜ํ™˜)
  • DATABASE_URL
    • PostgreSQL ์—ฐ๊ฒฐ ๋ฌธ์ž์—ด
    • ํ˜„์žฌ๋Š” crew ํ”„๋กœํ•„ ์ด๋ฏธ์ง€ URL ์บ์‹œ์™€ team activity ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • NOTION_API_KEY
    • Notion API ํ˜ธ์ถœ์šฉ integration secret
  • NOTION_TEAM_DB_IDS
    • crew:<id>,activity:<id>,study:<id>,project:<id>,crew_role_lookup:<id>,crew_profile:<id> ํ˜•์‹์˜ key-value ๋ฌธ์ž์—ด
    • ํ˜„์žฌ ๊ตฌํ˜„ ๊ธฐ์ค€ ํ•„์ˆ˜๊ฐ’์€ crew, activity์ž…๋‹ˆ๋‹ค.
    • study๋ฅผ ๋„ฃ์œผ๋ฉด /team/activity ๋ณ‘ํ•ฉ ์‹œ ํ•ด๋‹น datasource๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ์—†์œผ๋ฉด ์ฝ”๋“œ์— ๋‚ด์žฅ๋œ ๊ธฐ๋ณธ study datasource ID๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • project๋Š” ํ–ฅํ›„ project detail ๊ตฌํ˜„์šฉ ์˜ˆ์•ฝ ํ‚ค๋กœ ๋ณด๊ณ  ์žˆ์œผ๋ฉฐ, ํ˜„ ์‹œ์ ์˜ project list ํ˜ธ์ถœ์—๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    • crew_role_lookup๋Š” crewLog ์ž„์› ์ •๋ณด lookup์šฉ ๋ณด์กฐ ๋ฐ์ดํ„ฐ์†Œ์Šค์ž…๋‹ˆ๋‹ค.
    • crew_profile์€ ํšŒ์›๋ชฉ๋ก์˜ univDepartment / univJoinedYear ๋ณด๊ฐ•์šฉ ๋ณด์กฐ ๋ฐ์ดํ„ฐ์†Œ์Šค์ž…๋‹ˆ๋‹ค. ์—†์œผ๋ฉด ์ฝ”๋“œ์— ๋‚ด์žฅ๋œ ๊ธฐ๋ณธ datasource ID๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์‹œ:

NODE_ENV=development \
USE_MOCK_DATA=true \
CORS_ALLOW_ORIGINS=http://localhost:3000,http://localhost:5173 \
CORS_ALLOW_METHODS=GET,POST,OPTIONS \
CORS_ALLOW_HEADERS=Content-Type,Authorization \
CORS_ALLOW_CREDENTIALS=true \
npm run dev

๋ชจ๋“  Origin ํ—ˆ์šฉ(๊ฐœ๋ฐœ ํŽธ์˜):

CORS_ALLOW_ORIGINS=* npm run dev

์‹œ์ž‘ ์‹œ ๋กœ๊ทธ๋กœ ๋‹ค์Œ์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

  • ํ—ˆ์šฉ๋œ env ํ‚ค ๋ชฉ๋ก
  • ์‹ค์ œ ์ ์šฉ๋œ env ๊ฐ’

7) Prisma(์ค€๋น„ ์ƒํƒœ)

ํ˜„์žฌ๋Š” ์ค€๋น„ ๋‹จ๊ณ„์ด๋ฏ€๋กœ ์ตœ์†Œ ์˜ˆ์‹œ ๋ชจ๋ธ๋งŒ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

npm run prisma:generate
npm run prisma:push
npm run prisma:migrate:dev
npm run prisma:studio

ํ”„๋กœํ•„ ์ด๋ฏธ์ง€ ์บ์‹œ๋ฅผ ์ˆ˜๋™์œผ๋กœ ํ•œ ๋ฒˆ ๋™๊ธฐํ™”ํ•˜๋ ค๋ฉด:

npm run team:profile-image:sync

USE_MOCK_DATA=false ์ด๊ณ  DATABASE_URL์ด ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฉด, ์„œ๋ฒ„๋Š” ์‹œ์ž‘ ํ›„ ์ฆ‰์‹œ ํ•œ ๋ฒˆ ๋™๊ธฐํ™”ํ•˜๊ณ  ์ดํ›„ 12์‹œ๊ฐ„๋งˆ๋‹ค ํ”„๋กœํ•„ ์ด๋ฏธ์ง€ URL ์บ์‹œ๋ฅผ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค.

7-1) ๊ด€๋ฆฌ์ž ์ฝ˜์†” / ๊ณต๊ฐœ API ์ œ์–ด

๊ด€๋ฆฌ์ž ์ฝ˜์†”์€ Notion ์ˆ˜์ง‘๊ฐ’๊ณผ ๊ด€๋ฆฌ์ž ์„ค์ •๊ฐ’์„ ๋ถ„๋ฆฌํ•ด์„œ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

Notion -> admin content sync -> *Source ํ…Œ์ด๋ธ”
๊ด€๋ฆฌ์ž ์ฝ˜์†” -> *AdminProfile / Visibility / Override ํ…Œ์ด๋ธ”
๊ณต๊ฐœ API -> DB read model -> response

์ ‘์†

http://localhost:8001/admin

์ดˆ๊ธฐ ๊ด€๋ฆฌ์ž ๊ณ„์ •์€ DB์— ๊ด€๋ฆฌ์ž ๊ณ„์ •์ด ํ•˜๋‚˜๋„ ์—†์„ ๋•Œ ์ž๋™ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

email: admin
password: admin

์šด์˜์—์„œ๋Š” ์ฒซ ๋กœ๊ทธ์ธ ์ดํ›„ ๋ฐ˜๋“œ์‹œ ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ADMIN_DEFAULT_EMAIL / ADMIN_DEFAULT_PASSWORD๋ฅผ ๋ณ„๋„ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜์„ธ์š”.

์ถ”๊ฐ€ ํ™˜๊ฒฝ๋ณ€์ˆ˜

  • ADMIN_DEFAULT_EMAIL
    • ๊ธฐ๋ณธ๊ฐ’: admin
  • ADMIN_DEFAULT_PASSWORD
    • ๊ธฐ๋ณธ๊ฐ’: admin
  • ADMIN_SESSION_SECRET
    • ๊ด€๋ฆฌ์ž Bearer token HMAC ์„œ๋ช…์šฉ secret
  • NOTION_TEAM_DB_IDS
    • ๊ธฐ์กด ํ‚ค์— ๋”ํ•ด blog:<id>๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์˜ˆ: crew:<id>,activity:<id>,project:<id>,blog:<id>

์ˆ˜๋™ Notion ์ฝ˜ํ…์ธ  ๋™๊ธฐํ™”

CLI:

npm run admin:content:sync

Admin API:

POST /admin/sync/notion
Authorization: Bearer <admin token>

๋™๊ธฐํ™” ๋Œ€์ƒ:

  • CrewSource, CrewTermTeamSource
  • ProjectSource
  • BlogPostSource

์ƒˆ๋กœ ์ˆ˜์ง‘๋œ ํฌ๋ฃจ/ํ”„๋กœ์ ํŠธ/๋ธ”๋กœ๊ทธ๋Š” ๊ธฐ๋ณธ ๋น„๊ณต๊ฐœ์ž…๋‹ˆ๋‹ค.

๊ด€๋ฆฌ์ž API ์š”์•ฝ

POST /admin/login
GET  /admin/me

GET   /admin/crews
GET   /admin/crews/:id
PATCH /admin/crews/:id
PUT   /admin/crews/:id/term-teams
PUT   /admin/crews/:id/projects
PUT   /admin/crews/:id/blogs

GET   /admin/projects
GET   /admin/projects/:id
PATCH /admin/projects/:id
PUT   /admin/projects/:id/periods
PUT   /admin/projects/:id/participants
PUT   /admin/projects/:id/featured-blogs

GET   /admin/blogs
POST  /admin/sync/notion

PUT /admin/crews/:id/term-teams๋Š” ๊ด€๋ฆฌ์ž ์„ค์ •๊ฐ’์„ DB์— ์ €์žฅํ•œ ๋’ค, Notion crew datasource์—์„œ ์ž‘์„ฑ๊ธฐ์ˆ˜์™€ ๊ณ„์ •(ํ”„๋กœํ•„) people id๊ฐ€ ์ผ์น˜ํ•˜๋Š” ํŽ˜์ด์ง€๋ฅผ ์ฐพ์•„ ํŒ€ select๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

๋ฐฐํฌ ์ˆœ์„œ

  1. npm run prisma:generate
  2. npm run prisma:migrate:deploy
  3. ์„œ๋ฒ„ ๊ธฐ๋™
  4. /admin ๋กœ๊ทธ์ธ
  5. POST /admin/sync/notion ๋˜๋Š” npm run admin:content:sync
  6. ๊ด€๋ฆฌ์ž ์ฝ˜์†”์—์„œ ๊ณต๊ฐœ ์—ฌ๋ถ€์™€ override ๊ฐ’์„ ์ €์žฅ

์šด์˜ manifest์—๋Š” backend presync migration Job์ด ์žˆ์œผ๋ฏ€๋กœ, ์ƒˆ migration์ด ๋จผ์ € ์ ์šฉ๋œ ๋’ค ์„œ๋ฒ„๊ฐ€ ์˜ฌ๋ผ์˜ค๋Š” ํ๋ฆ„์„ ์œ ์ง€ํ•˜์„ธ์š”.

8) ์‹ ๊ทœ API/๋กœ์ง ์ถ”๊ฐ€ ๋ฐฉ๋ฒ•

  1. repositories์—์„œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  2. datasources์— mock/prisma ๊ตฌํ˜„์ฒด๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  3. services์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  4. routes์—์„œ ์—”๋“œํฌ์ธํŠธ์™€ Swagger ์‘๋‹ต ํ˜•์‹์„ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
  5. server.ts์—์„œ ์‚ฌ์šฉํ•  datasource์™€ ์„œ๋น„์Šค๋ฅผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
  6. typecheck์™€ build๋กœ ํƒ€์ž…/์ปดํŒŒ์ผ๋งŒ ๋จผ์ € ํ†ต๊ณผ์‹œํ‚ต๋‹ˆ๋‹ค.

9) ์‹ค๋ฌด์—์„œ ๊ผญ ์ง€์ผœ์•ผ ํ•  ์ 

  • ๊ณต๊ฐœ API ์‘๋‹ต ํ‚ค๋Š” ๋ฌธ์„œ ๊ธฐ์ค€์œผ๋กœ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜์„ธ์š”.
    • ํ˜„์žฌ ์ฝ”๋“œ์—๋Š” ์˜คํƒˆ์ž ํ‚ค(์˜ˆ: attatchments, RECRIUTING, __________)๊ฐ€ ์‹ค์ œ ์‘๋‹ต ๊ทœ์น™์˜ ์ผ๋ถ€๋กœ ๋“ค์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋‚ด๋ถ€ ๋กœ์ง์„ ํ™•์žฅํ•  ๋•Œ๋Š” ๋ฐ”๋กœ datasource๋งŒ ๊ต์ฒดํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผ ๋ฒ”์œ„๋ฅผ ์ขํžˆ์„ธ์š”.
  • ์ƒˆ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•˜๋ ค๋ฉด ๋จผ์ € server.ts -> routes -> services -> repositories -> datasources ์ˆœ์œผ๋กœ ์ถ”์ ํ•˜๋ฉด ์ „์ฒด ํ๋ฆ„์ด ๋ณด์ž…๋‹ˆ๋‹ค.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages