Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
255 changes: 255 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
# ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๊ฐ„๋‹จํ•œ ์„ค๋ช…
## ๐Ÿ“ŒProject Overview

- HaRu๋Š” ์†Œ๊ทœ๋ชจ ํŒ€์„ ์œ„ํ•œ All-In-One ์šด์˜ ๊ด€๋ฆฌ ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค.,
- ๋ณด๋‹ค ํšจ์œจ์ ์ธ ํŒ€ ์šด์˜์„ ์œ„ํ•œ ๊ณ ๋ฏผ์—์„œ ์‹œ์ž‘๋œ HaRu๋Š”, ๊ฐ์ž์˜ ์ž๋ฆฌ์—์„œ ์น˜์—ดํ•˜๊ฒŒ ์›€์ง์ด๋Š” ์†Œ๊ทœ๋ชจ ํŒ€๋“ค์˜ ํ•˜๋ฃจ๋ฅผ ๋•๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.,
- ํšŒ์˜ ์ง„ํ–‰ ๋ณด์กฐ, SNS ์ด๋ฒคํŠธ ์ง„ํ–‰ ๊ด€๋ฆฌ, ํŒ€ ๋ถ„์œ„๊ธฐ ์ฒดํฌ๊นŒ์ง€.HaRu๋Š” ๋ชจ๋“  ํŒ€์ด ๋” ๊ฐ€์น˜ ์žˆ๋Š” ์ˆœ๊ฐ„์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•์Šต๋‹ˆ๋‹ค.,

## ๐Ÿš€HaRu Key Features,

- **AI ํšŒ์˜ ์ง„ํ–‰ ๋งค๋‹ˆ์ €**,
- ์‹ค์‹œ๊ฐ„ STT ๋ณ€ํ™˜,
- HaRu AI ํšŒ์˜ ์ง„ํ–‰ ์งˆ๋ฌธ ์ถ”์ฒœ,
- ํšŒ์˜๋ก ์ž๋™ ์ƒ์„ฑ,
- **SNS ์ด๋ฒคํŠธ ์–ด์‹œ์Šคํ„ดํŠธ**,
- Instagram ๊ณ„์ • ์—ฐ๋™,
- ์ด๋ฒคํŠธ URL ๋“ฑ๋ก,
- ์ด๋ฒคํŠธ ์ฐธ์—ฌ์ž ๋ฐ ๋‹น์ฒจ์ž ๋ฆฌ์ŠคํŠธ ์ถ”์ถœ,
- **ํŒ€ ๋ถ„์œ„๊ธฐ ํŠธ๋ž˜์ปค**,
- ์„ค๋ฌธ์ง€ ์ž‘์„ฑ ๋ฐ ๋ฐฐํฌ,
- ํŒ€ ๋ถ„์œ„๊ธฐ ๋ฆฌํฌํŠธ ์ž๋™ ์ƒ์„ฑ,
- ์šด์˜์ž ๋งž์ถค HaRu ์ธ์‚ฌ์ดํŠธ ์ œ๊ณต,

## โš’๏ธTechnical Overview,

- **FrontEnd**: Next.js ยท React ยท TypeScript ยท Tailwind CSS ยท Storybook ยท Vercel,
- **BackEnd**: Spring ยท FastAPI ยท Docker ยท MySQL ยท AWS(EC2, S3, RDS) ยท Redis
---

---

---

# ์‚ฌ์šฉํ•œ ๋ธŒ๋žœ์น˜ ์ „๋žต ๋ฐ ๊ธฐ์ˆ  ์Šคํƒ, ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ๋“ฑ

## ๋ธŒ๋žœ์น˜ ์ „๋žต

<img width="800" height="1038" alt="Untitled" src="https://github.com/user-attachments/assets/f3b578c9-bda0-4bc6-b676-fb4c8f15dc43" />

- ์œ„ git flow๋ฅผ ๋”ฐ๋ฆ„
- release๋ธŒ๋žœ์น˜๋Š” ์ œ์™ธ
- dev ๋ธŒ๋žœ์น˜ ์™ผํŽธ์— feature๋ธŒ๋žœ์น˜๋ง๊ณ  refactor, fix๋ธŒ๋žœ์น˜๋„ ์กด์žฌ
<img width="820" height="437" alt="Untitled (1)" src="https://github.com/user-attachments/assets/62985d01-810f-41e6-b35b-3690dee4cb35" />


- ๋ธŒ๋žœ์น˜
- `main` - ๋ฐฐํฌ์šฉ ๋ธŒ๋žœ์น˜
- `dev` - ๊ฐœ๋ฐœ์šฉ ๋ธŒ๋žœ์น˜
- `feat/*` - ๊ฐœ๋ฐœ ํ”ผ์ณ๋ณ„ ๋ธŒ๋žœ์น˜ (์ƒˆ ๊ธฐ๋Šฅ)
- `fix/*` - ๋ฒ„๊ทธ ์ˆ˜์ • ํ”ผ์ณ๋ณ„ ๋ธŒ๋žœ์น˜ (๋ฒ„๊ทธ ์ˆ˜์ •)
- `refactor/*` - ๋ฆฌํŒฉํ† ๋ง ๋ธŒ๋žœ์น˜
- ์ด์Šˆ๋งˆ๋‹ค ๋ธŒ๋žœ์น˜ ์ƒ์„ฑํ•˜๊ณ  ์ปค๋ฐ‹ ex) feat/#10-login
- ์ด์Šˆ ํ•ด๊ฒฐ๋˜๋ฉด ์ด์Šˆ closeํ•˜๊ณ  ํ•ด๋‹น ๋ธŒ๋žœ์น˜ ์‚ญ์ œ
- **main, dev๋กœ ๋‚˜๋ˆ„๊ณ , ๊ฐœ๋ฐœ ๋œ ๊ฒƒ์€ dev์— merge. main์— merge๋˜๋ฉด CI/CD**

### ๋ธŒ๋žœ์น˜๋ช… ์ปจ๋ฒค์…˜

- {ํƒœ๊ทธ}/#{์ด์Šˆ๋ฒˆํ˜ธ}-{์ž‘์—…๋‚ด์šฉ}
- ์ž‘์—…๋‚ด์šฉ : `kebab-case` , ๋„์›Œ์“ฐ๊ธฐ๋Š” "-"๋กœ ๊ตฌ๋ถ„
- kebab-case: ๋ชจ๋‘ ์†Œ๋ฌธ์ž๋กœ ํ‘œํ˜„ํ•˜๋ฉฐ, ๋‹จ์–ด์™€ ๋‹จ์–ด ์‚ฌ์ด์—๋Š” ํ•˜์ดํ”ˆ(-)๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ex) feat/#0-project-init


---

## ์„œ๋ฒ„ ์•„ํ‚คํ…์ฒ˜
<img width="1377" height="780" alt="HaRu drawio_1" src="https://github.com/user-attachments/assets/f8131cbf-0dcc-4348-929d-839d87466dc7" />


## ๊ธฐ์ˆ  ์Šคํƒ
<img width="491" height="321" alt="แ„Œแ…ฆแ„†แ…ฉแ†จ แ„‹แ…ฅแ†นแ„‚แ…ณแ†ซ แ„ƒแ…กแ„‹แ…ตแ„‹แ…ฅแ„€แ…ณแ„…แ…ขแ†ท drawio (1) (1)" src="https://github.com/user-attachments/assets/cdb2e7e2-cbe0-4d92-a216-10d068aa905d" />


| Programming Languages | Java (17) / Python |
| --- | --- |
| Frameworks | SpringBoot / FastAPI |
| Version Control | Git |
| Cloud Services | AWS Route53 / EC2 / RDS(MySQL) / S3 / Docker |
| Database & Caches | MySQL / Redis |
| Deployment Tools | Nginx (ํ”„๋ก์‹œ ์„œ๋ฒ„) |
| Extra Library | Swagger / WebSockets / elevenlabs |

---

## ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

### DDD

### ๊ณ„์ธต ๊ตฌ์กฐ
<img width="404" height="399" alt="image (1)" src="https://github.com/user-attachments/assets/f4ca8234-b010-43e6-a824-208b65c96f3c" />


<aside>
๐Ÿ“ข

**๊ทœ์น™**

1. ์œ„์˜ ๊ณ„์ธต์—์„œ ์•„๋ž˜ ๊ณ„์ธต์—๋Š” ์ ‘๊ทผ ๊ฐ€๋Šฅ / ์•„๋ž˜ ๊ณ„์ธต์—์„œ ์œ„ ๊ณ„์ธต ์ ‘๊ทผ ๋ถˆ๊ฐ€๋Šฅ!
2. ํ•œ ๊ณ„์ธต์˜ ๊ด€์‹ฌ์‚ฌ์™€ ๊ด€๋ จ๋œ ๊ทธ ์–ด๋–ค ๊ฒƒ๋„ ๋‹ค๋ฅธ ๊ณ„์ธต์— ๋ฐฐ์น˜๋˜์–ด์„œ๋Š” ์•ˆ๋จ!
- ๊ฐ๊ฐ์˜ ๋„๋ฉ”์ธ์€ ์„œ๋กœ ์ฒ ์ €ํžˆ ๋ถ„๋ฆฌ๋˜์–ด์•ผ ํ•จ.
- ๊ฐ๊ฐ์˜ Layer๋Š” ํ•˜๋‚˜์˜ ๊ด€์‹ฌ์‚ฌ์—๋งŒ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก.
</aside>

<aside>

- ๋„๋ฉ”์ธ ์ข…๋ฅ˜
1. User - ํšŒ์›
2. Workspace - ์›Œํฌ์ŠคํŽ˜์ด์Šค
3. Meeting - ํšŒ์˜๋ก
4. SnsEvent - SNS ์ด๋ฒคํŠธ
5. MoodTracker - ๋ถ„์œ„๊ธฐ ํŠธ๋ž˜์ปค
</aside>

<aside>

- ๋„๋ฉ”์ธ ๋ณ„ ํฌํ•จ๋˜๋Š” ํŒจํ‚ค์ง€
1. domain (Entity)
- ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์ง์ ‘์ ์œผ๋กœ ๋งคํ•‘๋˜๋Š” ํด๋ž˜์Šค
- ๊ฐ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์–ด๋– ํ•œ ํ˜•ํƒœ, ํƒ€์ž…์œผ๋กœ ์ •์˜๋˜๋Š”์ง€ ์ •๋ฆฌ
- ex) User
2. DTO
- ํ†ต์‹  ์‹œ์˜ ์š”์ฒญ, ์‘๋‹ต ํ˜•ํƒœ๋ฅผ ์ •์˜
- ex) UserRequestDTO, UserResponseDTO
- Request, Response ํ•˜๋‚˜์”ฉ
- ๊ฐ ๋‚ด๋ถ€์— static class ์‚ฌ์šฉ
3. controller
- ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ์š”์ฒญ(DTO)์„ ์ง์ ‘ ์ „๋‹ฌ๋ฐ›๋Š” ํด๋ž˜์Šค
- Api Path๊ฐ€ ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉ๋จ
- ์„œ๋น„์Šค๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ์ตœ์ข…์ ์œผ๋กœ ๊ฐ’(DTO)์„ ๋ฐ˜ํ™˜ํ•จ
- ex) UserController
4. service
- ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํด๋ž˜์Šค
- Controller์—์„œ ๋ฐ›์€ DTO๋ฅผ ์ด์šฉํ•˜์—ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ˆ˜ํ–‰
- Repository๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…์„ ์ˆ˜ํ–‰
- ๊ฒฐ๊ณผ๋ฅผ DTO ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜
- ex) UserService
5. repository
- ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์ƒํ˜ธ์ž‘์šฉ
- CRUD ์ž‘์—… ์ˆ˜ํ–‰
- JPA๊ฐ€ ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉ๋จ
- ex) UserRepository
6. converter
- DTO โ†” Entity ๋ณ€ํ™˜์„ ๋‹ด๋‹น
- Controller, Service์—์„œ ์›ํ•˜๋Š” ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•  ๋•Œ ํ˜ธ์ถœํ•˜์—ฌ ์‚ฌ์šฉ
</aside>

---

<aside>

**๊ฐ๊ฐ์˜ ๋ ˆ์ด์–ด ๋ฐ ๊ตฌ์กฐ ์„ค๋ช…**

1. domain

์—”ํ‹ฐํ‹ฐ. ์™ธ๋ถ€ ๋ณ€๊ฒฝ์— ์˜ํ•ด ๋„๋ฉ”์ธ ๋‚ด๋ถ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์„ ๋ง‰์•„์•ผ ํ•จ.

2. infra

์™ธ๋ถ€์™€์˜ ํ†ต์‹  ๋‹ด๋‹น ๋กœ์ง.

ex) ์นด์นด์˜ค ์ธ์ฆ์„œ๋ฒ„ OAuth

3. global

๊ณตํ†ต๋œ ์‘๋‹ต์ฒ˜๋ฆฌ

</aside>

---

### ํŒจํ‚ค์ง€ ๊ตฌ์กฐ ์˜ˆ์‹œ

```markdown
โ””โ”€โ”€ src
โ”œโ”€โ”€ main
โ”‚ โ”œโ”€โ”€ java
โ”‚ โ”‚ โ””โ”€โ”€ com
โ”‚ โ”‚ โ””โ”€โ”€ haru
โ”‚ โ”‚ โ””โ”€โ”€ server
โ”‚ โ”‚ โ”œโ”€โ”€ ServerApplication.java
โ”‚ โ”‚ โ”œโ”€โ”€ domain
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ user
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ controller
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ service
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ repository
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ converter
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ dto
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ exception
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ handler
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ validator
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ annotation
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ entity
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ ...
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ moodTracker
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ controller
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ service
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ repository
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ converter
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ dto
โ”‚ โ”‚ โ”‚ โ”‚ **โ”œโ”€โ”€** exception
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ handler
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ validator
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ annotation
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ entity
โ”‚ โ”‚ โ”œโ”€โ”€ global
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ common
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ entity
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ BaseEntity.java
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ config
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ SwaggerConfig.java
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ properties
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ security
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ SecurityConfig.java
โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ apiPayload
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ code
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ Status
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ ErrorStatus
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ SuccessStatus
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ BaseCode.java
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ BaseErrorCode.java
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ ErrorReasonDTO.java
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ ReasonDTO.java
โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ exception
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ ExceptionAdvice.java
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ GeneralException.java
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ ApiResponse.java
โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ util
โ”‚ โ”‚ โ””โ”€โ”€ infra
โ”‚ โ””โ”€โ”€ resources
โ”‚ โ””โ”€โ”€ application.yml
โ”‚ โ””โ”€โ”€ application-secret.yml
```



---

---

---

# ํŒ€์› ์ •๋ณด

| ์ด๋ฆ„ | ๋‹‰๋„ค์ž„ | ํŒŒํŠธ | ์†Œ์† | ์ „ํ™”๋ฒˆํ˜ธ | GitHub |
| --- | --- | --- | --- | --- | --- |
| ํ™ฉ์ง€์› | ๋ฒจ๋ผ | PM | ์ค‘์•™๋Œ€ํ•™๊ต ๊ฒฝ์˜ํ•™๋ถ€ | 010-4139-4130 | hwangjeewon |
| ์ด์ˆ˜ํ˜ธ | ์˜ | Designer | ํ•œ์–‘๋Œ€ํ•™๊ต ERICA ICTํ•™๋ถ€ ๋””์ž์ธํ…Œํฌ๋†€๋กœ์ง€ | 010-9455-9509 | Leesuho9509 |
| ๊น€์—ฌ์ง„ | ์กฐ์ด | Frontend Developer | ์ˆญ์‹ค๋Œ€ํ•™๊ต IT๋Œ€ํ•™ ๊ธ€๋กœ๋ฒŒ๋ฏธ๋””์–ดํ•™๋ถ€ | 010-5001-9456 | duwlsssss |
| ๋ฐ•์ˆ˜ํ˜„ | ๋…ธ์ฝ” | Frontend Developer | ๋ช…์ง€๋Œ€ํ•™๊ต ์ปดํ“จํ„ฐ๊ณตํ•™๊ณผ | 010-6631-1760 | strfunctionk |
| ์†๊ธฐํ›ˆ | ์ œํŠธ | Frontend Developer | ์ˆญ์‹ค๋Œ€ํ•™๊ต IT๋Œ€ํ•™ ๊ธ€๋กœ๋ฒŒ๋ฏธ๋””์–ดํ•™๋ถ€ | 010-3947-5847 | S-Gihun |
| ๋ฐ•๊ฒฝ์šด | ํ•˜๋Š˜ | Frontend Developer | ์ค‘์•™๋Œ€ํ•™๊ต ์†Œํ”„ํŠธ์›จ์–ด๋Œ€ํ•™ ์†Œํ”„ํŠธ์›จ์–ดํ•™๋ถ€ | 010-9344-8561 | kyeoungwoon |
| ์ž„๋™์žฌ | ํฌ์ธ  | Backend Developer | ์ค‘์•™๋Œ€ํ•™๊ต ์†Œํ”„ํŠธ์›จ์–ด๋Œ€ํ•™ ์†Œํ”„ํŠธ์›จ์–ดํ•™๋ถ€ | 010-8986-2425 | djlim2425 |
| ๊น€์ง„ํ˜ธ | ๋ฃจํ”ผ | Backend Developer | ์ค‘์•™๋Œ€ํ•™๊ต ์†Œํ”„ํŠธ์›จ์–ด๋Œ€ํ•™ ์†Œํ”„ํŠธ์›จ์–ดํ•™๋ถ€ | 010-8828-5091 | Jinho622 |
| ์ดํ˜ธ๊ทผ | ์šฐ๋”” | Backend Developer | ์ˆญ์‹ค๋Œ€ํ•™๊ต ์ปดํ“จํ„ฐํ•™๋ถ€ | 010-9842-4789 | 2ghrms |
| ์ด์„์ฃผ | ๋‹‰ | Backend Developer | ์ค‘์•™๋Œ€ํ•™๊ต ์†Œํ”„ํŠธ์›จ์–ด๋Œ€ํ•™ ์†Œํ”„ํŠธ์›จ์–ดํ•™๋ถ€ | 010-4067-2687 | hknhj |
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,19 @@ public ApiResponse<MeetingResponseDTO.TranscriptResponse> getMeetingTranscript(
}



@Operation(summary = "ํšŒ์˜๋ก ์Œ์„ฑํŒŒ์ผ ์กฐํšŒAPI", description =
"# [v1.0 (2025-08-14)](https://www.notion.so/AI-24f5da7802c580bc882fe01607e01bbc)" +
"ํšŒ์˜๋ก์„ ๋‹ค์šด๋กœ๋“œํ•˜๋Š” API์ž…๋‹ˆ๋‹ค. URL์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค."
)
@GetMapping("{meetingId}/ai-proceeding/voice")
public ApiResponse<MeetingResponseDTO.proceedingVoiceLinkResponse> MeetingvoiceFile(
@PathVariable("meetingId") String meetingId
){
Long userId = SecurityUtil.getCurrentUserId();

MeetingResponseDTO.proceedingVoiceLinkResponse response = meetingQueryService.MeetingVoiceFile(userId, Long.parseLong(meetingId));

return ApiResponse.onSuccess(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ public static class proceedingDownLoadLinkResponse {
private String downloadLink;
}

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class proceedingVoiceLinkResponse {
private String voiceLink;
}

@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public interface MeetingQueryService {
MeetingResponseDTO.TranscriptResponse getTranscript(Long userId, Long meetingId);

MeetingResponseDTO.proceedingDownLoadLinkResponse downloadMeeting(Long userId, Long meetingId);

MeetingResponseDTO.proceedingVoiceLinkResponse MeetingVoiceFile(Long userId, Long meetingId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,31 @@ public MeetingResponseDTO.proceedingDownLoadLinkResponse downloadMeeting(Long us
.build();
}

@Override
public MeetingResponseDTO.proceedingVoiceLinkResponse MeetingVoiceFile(Long userId, Long meetingId){
User foundUser = userRepository.findById(userId)
.orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND));

Meeting foundMeeting = meetingRepository.findById(meetingId)
.orElseThrow(() -> new MeetingHandler(ErrorStatus.MEETING_NOT_FOUND));

Workspace foundWorkspace = meetingRepository.findWorkspaceByMeetingId(meetingId)
.orElseThrow(() -> new WorkspaceHandler(ErrorStatus.WORKSPACE_NOT_FOUND));

UserWorkspace foundUserWorkspace = userWorkspaceRepository.findByUserIdAndWorkspaceId(userId, foundWorkspace.getId())
.orElseThrow(() -> new UserWorkspaceHandler(ErrorStatus.USER_WORKSPACE_NOT_FOUND));

String audioFileKeyName = foundMeeting.getAudioFileKey();

if (audioFileKeyName == null || audioFileKeyName.isBlank()) {
throw new MeetingHandler(ErrorStatus.MEETING_PROCEEDING_NOT_FOUND);
}

String presignedUrl = amazonS3Manager.generatePresignedUrl(audioFileKeyName);

return MeetingResponseDTO.proceedingVoiceLinkResponse.builder()
.voiceLink(presignedUrl)
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
Expand All @@ -10,14 +11,17 @@

@Component
public class CustomOAuth2FailureHandler implements AuthenticationFailureHandler {

@Value("${google-login-frontend-url}")
String baseUrl;

@Override
public void onAuthenticationFailure(
HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception
) throws IOException {
String failureGoogleLoginUrl = "/auth/login/google/callback";
// ํ”„๋ก ํŠธ์—”๋“œ URL๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ (query param ์ „๋‹ฌ)
response.sendRedirect("http://localhost:3000" + failureGoogleLoginUrl + "?status=fail");
response.sendRedirect(baseUrl + "?status=fail");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public class CustomOAuth2SuccessHandler implements AuthenticationSuccessHandler
private int accessExpTime;
@Value("${jwt.refresh-expiration}")
private int refreshExpTime;
@Value("${google-login-frontend-url}")
String baseUrl;
private final UserCommandService userCommandService;

@Override
Expand All @@ -28,8 +30,6 @@ public void onAuthenticationSuccess(
Authentication authentication
) throws IOException {
StringBuilder redirectUrl = new StringBuilder();
String baseUrl = "http://localhost:3000"; // ํ”„๋ก ํŠธ์—”๋“œ URL
String successGoogleLoginUrl = "/auth/login/google/callback";
CustomOauth2UserDetails userDetails = (CustomOauth2UserDetails) authentication.getPrincipal();
// ํšŒ์›๊ฐ€์ž…์ด๋“  ๋กœ๊ทธ์ธ์ด๋“  ๋˜‘๊ฐ™์ด ํ”„๋ก ํŠธ์—”๋“œ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
Long userId = userDetails.getUser().getId();
Expand All @@ -38,7 +38,6 @@ public void onAuthenticationSuccess(
String refreshToken = userCommandService.generateAndSaveRefreshToken(key, refreshExpTime);
// ํ”„๋ก ํŠธ์—”๋“œ URL๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ (query param ์ „๋‹ฌ)
redirectUrl.append(baseUrl)
.append(successGoogleLoginUrl)
.append("?status=success")
.append("&userId=").append(userId)
.append("&profileImage=").append(userDetails.getUser().getProfileImage())
Expand Down
2 changes: 2 additions & 0 deletions src/test/resources/application-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ invite-url: invite-url

survey-url: survey-url

google-login-frontend-url: google-login-frontend-url

instagram:
client:
id: "dummy-client-id"
Expand Down