Giter VIP home page Giter VIP logo

backend's Introduction

transcendence

  • ๐Ÿง‡transcendence๋Š” 42seoul ๊ณตํ†ต๊ณผ์ •์˜ ๋งˆ์ง€๋ง‰ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค.

  • ์‹ค์‹œ๊ฐ„ pingpong๊ฒŒ์ž„๊ณผ DM, ๊ทธ๋ฃน์ฑ„ํŒ…์„ ์ง€์›ํ•˜๋Š” ์›น์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค.

  • ๊ฐœ๋ฐœ ๊ธฐ๊ฐ„ : 23.09.16 ~ 24.12.20 (์•ฝ 3๊ฐœ์›”)

  • ๋ณธ ๋ ˆํฌ๋Š” BACKEND ๊ฐœ๋ฐœ์— ๊ด€ํ•œ ๋‚ด์šฉ์„ ์œ„์ฃผ๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

  • FRONTEND ๊ฐœ๋ฐœ์— ๊ด€ํ•ด ๊ถ๊ธˆํ•˜์‹œ๋‹ค๋ฉด? ft-transcendence-seoul

๐Ÿท๏ธ ๋ชฉ์ฐจ

4. [์ฃผ์š” API & ์†Œ์ผ“ ๋ช…์„ธ๐Ÿ“ƒ](#๐Ÿ“ƒ-์ฃผ์š” API & ์†Œ์ผ“ ๋ช…์„ธ)

6. [๊ธฐ๋Šฅ ์†Œ๊ฐœ ๐Ÿš€](#๐Ÿš€-๊ธฐ๋Šฅ ์†Œ๊ฐœ )

๐Ÿ’ป ๋ฐฐํฌ

์‚ฌ์ดํŠธ url: https://develop.d35lpok7005dz1.amplifyapp.com/

๐Ÿ™‹โ€โ™‚๏ธ ๊ฐœ๋ฐœํŒ€ & ์—ญํ•  ๋ถ„๋‹ด

eunjilee seonyun woojeong
@spew11 @sbsny @izone00
erd์„ค๊ณ„ / ์ธ์ฆ(OAuth2, TOTP) / ์œ ์ € , ์นœ๊ตฌ, ์ฐจ๋‹จ API, DM ์ฑ„๋„ ๊ด€๋ จ ๊ธฐ๋Šฅ API DM, ์ฑ„๋„ ๋ฉ”์„ธ์ง€, ๊ฒŒ์ž„, ์•Œ๋ฆผ ์‹ค์‹œ๊ฐ„ ์†Œ์ผ“ / ๋ฐฐํฌ

๐Ÿ”ง Stacks

๊ธฐ์ˆ  ์Šคํƒ

ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  ย  ย 

ํ˜‘์—…

ย  ย  ย  ย  ย  ย 

๐Ÿ“ƒ ์ฃผ์š” API & ์†Œ์ผ“ ๋ช…์„ธ |

image

๐Ÿ“ฑ erd ์„ค๊ณ„

alt text

๐Ÿš€ ๊ธฐ๋Šฅ ์†Œ๊ฐœ

  • ๐ŸŽฅ 42API์˜ OAUTH2.0์„ ํ†ตํ•œ ๋กœ๊ทธ์ธ์„ ์ง€์›ํ•˜๊ณ  qr์ฝ”๋“œ๋ฅผ ํ†ตํ•œ authencation 2์ฐจ ์ธ์ฆ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • ๐Ÿ‘‘ ๊ฐ ์œ ์ €๋“ค์€ ์นœ๊ตฌ๋‚˜ ์ฐจ๋‹จ ๋“ฑ์˜ ๊ด€๊ณ„๋ฅผ ๊ฐ€์งˆ์ˆ˜ ์žˆ๊ณ  ์นœ๊ตฌ๋ผ๋ฆฌ๋Š” ์„œ๋กœ DM์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  • ๐Ÿ“Š ์ฑ„๋„์„ ์ƒ์„ฑํ•˜๊ณ  ์ฑ„๋„์— ์ฐธ๊ฐ€ํ•ด ์—ฌ๋Ÿฌ๋ช…์˜ ์œ ์ €์™€ ๊ทธ๋ฃน ์ฑ„ํŒ…์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • โญ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ž์‹ ์˜ ๊ฒŒ์ž„ rating์— ๋”ฐ๋ฅธ ๊ฒŒ์ž„ ๋งค์นญ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  • โœ… ์›น์†Œ์ผ“์„ ํ†ตํ•ด ์‹ค์‹œ๊ฐ„์œผ๋กœ pingpong๊ฒฝ๊ธฐ๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๐Ÿ“š ๋‹ค๋ฅธ ์œ ์ € online ์ƒํƒœ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ  ์ „์ ๊ณผ ๋žญํฌ rating ์กฐํšŒ ๊ฐ€๋Šฅ

  • ๐Ÿ‘ ๊ฒŒ์ž„ ๋งค์นญ๊ณผ ์นœ๊ตฌ ์ดˆ๋Œ€, ๋ฉ”์„ธ์ง€์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์‹ค์‹œ๊ฐ„ ์•Œ๋ฆผ์œผ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

backend's People

Contributors

spew11 avatar izone00 avatar sbsny avatar developerryou avatar

Forkers

sbsny izone00 spew11

backend's Issues

Channel API ๊ด€๋ จ ๋ฒ„๊ทธ ๋ฐ ๊ถ๊ธˆ์ฆ ๋ฌธ์˜

๊ถ๊ธˆํ•œ ๊ฒƒ

์œ ํšจ์„ฑ ๊ฒ€์‚ฌ

  • ์ฑ„๋„ ์ƒ์„ฑ ์‹œ title, password์— ๋Œ€ํ•ด ๋ฐฑ์—”๋“œ์—์„œ ๋นˆ๋ฌธ์ž์—ด๊ณผ ๊ฐ™์€ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ(?)๋Š” ์•ˆ ํ•ด์ฃผ์‹œ๋‚˜์š”?

ํ”ผ๊ทธ๋งˆ์— ๊ตฌํ˜„ ์•ˆ ๋œ ๊ธฐ๋Šฅ์€ ์–ด๋””์„œ ์ˆ˜ํ–‰๋˜๋‚˜์š”?

  • channel์˜ title, type ์ˆ˜์ •
  • owner ์œ„์ž„

๋ฒ„๊ทธ

์„œ๋ฒ„ ์—๋Ÿฌ๐Ÿšจ

  • /channels api ๋ถ€์ฐฉํ•œ ์ƒํƒœ์—์„œ reload ์‹œ 500 ์—๋Ÿฌ(TypeError: getStaticPaths is not a function) ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ

  • done: ํ™•์‹คํžˆ ์ž˜ ์ž‘๋™ํ•˜๋Š” api
  • progress: ์•„์ง ์—ฌ๋Ÿฌ ๋ช…์˜ ์œ ์ €์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ๋ชป ํ•ด๋ณธ api
  • error: ๋ฌธ์ œ ์žˆ๋Š” api

API ์—๋Ÿฌ ์ฝ”๋“œ ์š”์•ฝ

  • mute API: 404 not found
  • ๋‚˜๋จธ์ง€ error API: 400 Bad request (์ฑ„๋„ ๋น„๋ฐ€๋ฒˆํ˜ธ ์š”๊ตฌ)

DM ๋ชจ๋“ˆ ๊ตฌํ˜„(์†Œ์ผ“)

  1. ์ด์ „ DM ์กฐํšŒ (๋…ธ์…˜์—๋Š” api๋กœ ๋˜์–ด ์žˆ์œผ๋‚˜ ์†Œ์ผ“์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š”๊ฒŒ ๋” ์ข‹์•„๋ณด์ธ๋‹ค.)
  2. DM ๋ณด๋‚ด๊ธฐ
  3. DM ๋ฐ›๊ธฐ
  4. DM ํ™•์ธ ์‹œ๊ฐ„ ๊ฐฑ์‹ 
  5. ํ™•์ธํ•˜์ง€์•Š์€ DM๊ฐฏ์ˆ˜ ์กฐํšŒ(๋นจ๊ฐ„ ์•„์ด์ฝ˜ ์•Œ๋ฆผ์„ ๋„์›Œ์ฃผ๊ธฐ ์œ„ํ•œ ์šฉ๋„)

๊ฒŒ์ž„ ๋ชจ๋“ˆ ๊ตฌํ˜„

  1. ๊ฒŒ์ž„ ๋งค์นญ ํ ๋“ฑ๋กํ•˜๊ธฐ ๋ฐ ์ทจ์†Œํ•˜๊ธฐ(API)
  2. ๊ฒŒ์ž„ ๋งค์นญ ํ ์žกํ˜€์„œ ์‹œ์ž‘(์†Œ์ผ“)
  3. ๊ฒŒ์ž„ ์ดˆ๋Œ€ํ•˜๊ธฐ(์ˆ˜๋ฝ์€ API๋กœ ํ•œ๋‹ค.)
  4. ์ธ๊ฒŒ์ž„ ์†Œ์ผ“(์ƒ๊ฐ ์ค‘)

์„ธ์…˜ ๋ฐ์ดํ„ฐ ํ˜•์‹ ์ˆ˜์ • ๋ฐ auth ๋ชจ๋“ˆ ๋ฒ„๊ทธ ์ˆ˜์ •

  1. ์„ธ์…˜์— ์œ ์ € email ๋Œ€์‹ ์— ์œ ์ € id๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ˆ˜์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
    2.๋น„์ •์ƒ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋Š” promise ๊ด€๋ จ ๋กœ์ง ์ˆ˜์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

mute ๊ธฐ๋Šฅ ๊ตฌํ˜„ -ing

entity๋Š” relation์—์„œ isMuted์™€ muteUntil(mute๋œ ์ดํ›„์— 5๋ถ„ ๊ฒฝ๊ณผ๋œ ์‹œ๊ฐ„) ์ด ๋‘ ๊ฐ€์ง€๋งŒ ์žˆ์œผ๋ฉด banUser ๋ฉ”์†Œ๋“œ๋ฅผ ์žฌํ™œ์šฉํ•ด์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ ๊ฐ™์•„์„œ ๊ตฌํ˜„ ์ค‘์— ์žˆ์Šต๋‹ˆ๋‹ค.

muteUser ๋ฉ”์†Œ๋“œ์—์„œ isMuted ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋‚˜์„œ socket์œผ๋กœ ์‹ค์‹œ๊ฐ„์œผ๋กœ mute๋๋‹ค๋Š” ์ƒํƒœ๋ฅผ ์ฑ„๋„์— ์ ‘์†๋œ ๋ชจ๋“  ์œ ์ €์—๊ฒŒ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๊ณ , ๋˜ ์ฑ„๋„์— ๋ฉ”์‹œ์ง€ ์ „์†ก์„ ๋‹ด๋‹นํ•˜๋Š” ๊ฒŒ์ดํŠธ์›จ์ด socket ๋ฉ”์†Œ๋“œ์—์„œ isUserMuted ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์œ ์ €์˜ mute ์ƒํƒœ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ™•์ธํ•˜์—ฌ mute๋œ ์ƒํƒœ๋กœ ํ™•์ธ๋œ๋‹ค๋ฉด return; ์ฒ˜๋ฆฌํ•ด์„œ ์œ ์ €์—๊ฒŒ ๋ฉ”์‹œ์ง€ ์ „์†ก์ด ๋˜์ง€ ์•Š๊ฒŒ๋” ๋งŒ๋“ค๊ณ , 5๋ถ„ ๊ฒฝ๊ณผ ํ›„ mute๊ฐ€ ํ•ด์ œ๋œ ์ƒํƒœ์ž„์„ ์ „๋‹ฌ ๋ฐ›์œผ๋ฉด ๋ฉ”์‹œ์ง€ ์ „์†ก ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

class Validation Pipe ์ถ”๊ฐ€

app๋ชจ๋“ˆ์— ์ „์—ญ์œผ๋กœ validationPipe๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค.
์ถ”๊ฐ€ํ•˜๊ฒŒ๋˜๋ฉด ์ธ์ž๋กœ ๋„˜๊ธฐ๋Š” ๊ฐ์ฒด๊ฐ€ ํƒ€์ž…์ด ๋งž๋Š”์ง€ ์„œ๋ฒ„๊ฐ€ ๋Œ์•„๊ฐˆ๋•Œ ์ฒดํฌํ•  ์ˆ˜ ์žˆ์–ด์š”.
์ž์„ธํ•œ ์„ค๋ช…์€ ๋งŒ๋‚˜์„œํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค

์ž๋™๋กœ๊ทธ์ธ ์˜ต์…˜ ๊ตฌํ˜„

ํด๋ผ์ด์–ธํŠธ์˜ ์ž๋™ ๋กœ๊ทธ์ธ ์˜ต์…˜ ์„ ํƒ ์—ฌ๋ถ€์— ๋งž๋Š” ์ฟ ํ‚ค(์„ธ์…˜์ฟ ํ‚ค/์˜์†์ฟ ํ‚ค)๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก ์ˆ˜์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์•Œ๋ฆผ(Notification) ๊ธฐ๋Šฅ ๊ตฌํ˜„

์•Œ๋ฆผ ์ข…๋ฅ˜: ๊ฒŒ์ž„์ดˆ๋Œ€, ์นœ๊ตฌ์ดˆ๋Œ€, ์ฑ„๋„์ดˆ๋Œ€

1. ํ™•์ธํ•˜์ง€ ์•Š์€ ์•Œ๋ฆผ ์กฐํšŒ(API, ์†Œ์ผ“ ๋‘˜๋‹ค ์ข‹์Œ)
2. ์•Œ๋ฆผ์— ๋Œ€ํ•œ ์ˆ˜๋ฝ, ๊ฑฐ์ ˆ(API, ์†Œ์ผ“ ๋‘˜๋‹ค ์ข‹์Œ)
3. ์•Œ๋ฆผ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ˆ˜์‹ 
4. ์•Œ๋ฆผ ๋ชจ๋‘ ์ง€์šฐ๊ธฐ(API, ์†Œ์ผ“ ๋‘˜๋‹ค ์ข‹์Œ)

Channel ๋ชจ๋“ˆ ๋ฆฌํŒฉํ† ๋ง

[Feature/#1-channel-๋ชจ๋“ˆ-๊ตฌํ˜„] branch์— push ์™„๋ฃŒ

๊ธฐ์กด controller์— ์žˆ๋˜ ๋ฉ”์†Œ๋“œ ์ด์™ธ์— inviteUser, join ๋ฉ”์†Œ๋“œ ์ถ”๊ฐ€.

โœ”invite API๋Š”
@post(':channel_id/invite/:user_id') // ๋’ค์— user_id ํ•„์š”.
// adminguard
inviteUser(
@getuser() requestingUser: User,
@param('channel_id', ChannelByIdPipe) channel: Channel,
@param('user_id', UserByIdPipe) invitedUser: User,
) {
return this.channelService.inviteUser(channel, invitedUser, requestingUser);
}
-> Kick๊ณผ Ban ๊ธฐ๋Šฅ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋’ค์— /:user_id๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋…ธ์…˜์—๋Š” /channels/{channel_id}/invite ์ด๋ ‡๊ฒŒ๋งŒ ์ •์˜๋จ.
Kick๊ณผ Ban ์˜ˆ์‹œ [@post(':channel_id/ban/:user_id')] invite๋„ ์ด์™€ ๋™์ผ.

โœ”@post(':channel_id')
join(@getuser() user: User, @param('channel_id', ParseIntPipe) channelId: number) {
return this.channelService.join(user, channelId);
}
์ปจํŠธ๋กค๋Ÿฌ์˜ join ๋ฉ”์†Œ๋“œ์—์„œ password๋ฅผ ์–ด๋–ค ์‹์œผ๋กœ ๋ฐ›์•„์•ผ ๋ ์ง€ ์ƒ์˜ ํ•„์š”.

< ใ…กใ…กใ…กใ…ก ๋‚จ์€ ๊ณผ์ œ ใ…กใ…กใ…กใ…ก>

  1. ์šฐ์ง„๋‹˜์ด ๊ณ„ํš ์ค‘์ธ transaction, mute, guard ๊ตฌํ˜„
  2. ๋ฐฉ๊ธˆ ์ „ pushํ•œ ์ฝ”๋“œ๋ฅผ ์ข€ ๋” ๋ณด์™„ํ•˜๊ณ  ์ผ์š”์ผ ํšŒ์˜ ๋•Œ๊นŒ์ง€ service์™€ chatgateway ์†Œ์ผ“๊ณผ์˜ ๋ณ‘ํ•ฉ

๋‚จ์€ ๊ณผ์ œ ์ด์™ธ์— ๋น ์ง„ ๋ถ€๋ถ„์ด๋‚˜ ์ˆ˜์ •ํ•  ์‚ฌํ•ญ ์žˆ์œผ๋ฉด comment์ฃผ์„ธ์š”!

์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€ ๋ฐ ํŒŒ์ผ ์—…๋กœ๋“œ API ์ถ”๊ฐ€

์ˆ˜์ •ํ•  ์‚ฌํ•ญ

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์œ ์ผํ‚ค ํ•„๋“œ ์ €์žฅ ์ „์— ์œ ์ผํ•œ์ง€ ํ™•์ธํ•˜๋Š” ๋กœ์ง ์ถ”๊ฐ€
  • ํŒŒ์ผ ์—…๋กœ๋“œ API ์ถ”๊ฐ€
  • ๊ทธ ์™ธ ์˜ˆ์™ธ์ฒ˜๋ฆฌ ์ถ”๊ฐ€

user๋ฐ user-relation๋ชจ๋“ˆ ๋กœ์ง ์ถ”๊ฐ€

  1. user-realtion ์ปจํŠธ๋กค๋Ÿฌ์— ์นœ๊ตฌ๋ฆฌ์ŠคํŠธ๋ฐ˜ํ™˜ํ•˜๋Š” API ์ถ”๊ฐ€
  2. user-relation ์—”ํ‹ฐํ‹ฐ์— updatedAt ํ•„๋“œ ์ถ”๊ฐ€
  3. notificateon ๋ชจ๋“ˆ ์‚ญ์ œ
  4. user์—”ํ‹ฐํ‹ฐ์˜ avatar๋ณ€์ˆ˜๋ฅผ enumํƒ€์ž…์œผ๋กœ ๋ณ€๊ฒฝ

Channel ์†Œ์ผ“ ๊ตฌํ˜„

1. ๋ฉ”์„ธ์ง€ ๋ณด๋‚ด๊ธฐ
2. ๋ฉ”์„ธ์ง€ ๋ฐ›๊ธฐ
3. ๊ฐ•ํ‡ด ๋‹นํ•˜๊ธฐ
4. ์นจ๋ฌต ๋‹นํ•˜๊ธฐ ๋ฐ ํ•ด์ง€
5. owner ๋˜๊ธฐ
6. admin ๋˜๊ธฐ ๋ฐ ํ•ด์ง€

users, user-relation ๋ชจ๋“ˆ ๊ด€๋ จ API ํ…Œ์ŠคํŠธ ๋ฐ ๋ฒ„๊ทธ ๊ฐœ์„ 

  1. 'findAllFriends()'๋ฅผ 'findAllFriendRelations()' ์œผ๋กœ ์นœ๊ตฌ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ฐจ๋‹จ์„ ์ œ์™ธํ•œ ๋ชจ๋“  ์ข…๋ฅ˜์˜ ์นœ๊ตฌ ๊ด€๊ณ„๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๋กœ์ง ์ˆ˜์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
  2. ์ •์ƒ์ ์œผ๋กœ ์ฒ˜๋ฆฌ ๋˜์ง€ ์•Š๋Š” promise ๊ฐ์ฒด ๊ด€๋ จ ๋กœ์ง์„ ํ•ด๊ฒฐํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
  3. ํ…Œ์ŠคํŠธ ๋ฐ ๋ฒ„๊ทธ ์ˆ˜์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.