μ½ λ΄ν¬ ν μ₯μ΄λ©΄, ν΄μΈ λ°μ μ€λΉκ° λλ©λλ€.
"μ΄ μ½, κ·Έ λλΌμ κ°μ Έκ°λ λλμ?"
ν΄μΈμ¬νμ μ½μ κ°μ Έκ° λ μ΄λ€ μ±λΆμ΄ κ·μ λμμΈμ§, μ΄λ€ μλ₯λ₯Ό μ€λΉν΄μΌ νλμ§λ₯Ό μ λΆ μμ² λ°μ΄ν° κΈ°μ€μΌλ‘ νμ ν΄ μ£Όλ μ¬νμ μμ½ν λ°μ μ€λΉ μλΉμ€μ λ°±μλμ λλ€.
μ½ λ΄ν¬λ₯Ό 촬μνλ©΄ OCRλ‘ μ½μ μ½μ΄ μμ½μ² μμ½ν μ 보μ λ§€μΉνκ³ , μ¬ν κ΅κ°λ₯Ό κ³ λ₯΄λ©΄ μ±λΆλ³ μ νΈλ± νμ κ³Ό μ€λΉ μλ₯ 체ν¬λ¦¬μ€νΈλ₯Ό λ§λ€μ΄ μ€λλ€. μλ₯λ AWS S3μ 보κ΄νκ³ , νμ§μμ λ¬Έμ κ° μκΈ°λ©΄ μ¬μΈκ³΅κ΄ μ°λ½μ²μ νμ§μ΄ μ€λͺ λ¬ΈκΉμ§ μ 곡ν©λλ€.
- μΉ΄μΉ΄μ€ OAuth2 μμ λ‘κ·ΈμΈ
- λ‘κ·ΈμΈ μ±κ³΅ μ JWT λ°κΈ β μ΄ν λͺ¨λ μμ²μ
Authorization: Bearer <token>ν€λ μ¬μ© - λ΄ κ³μ μ 보 μ‘°ν
- μ½ λ΄ν¬ μ¬μ§ μ λ‘λ β CLOVA OCRλ‘ μ½νλͺ Β·μ©λ² μΆμΆ
- μΆμΆ κ²°κ³Όλ₯Ό μμ½μ² μμ½ν APIμ νλͺ©μ½λ κΈ°μ€μΌλ‘ λ§€μΉΒ·κ²μ¦
- μΈμμ΄ μ λ§€νλ©΄ μ νλͺ μΌλ‘ ν보 λͺ©λ‘ κ²μν΄ μ¬μ©μκ° μ§μ μ ν
- νμ λ μ½μ 볡μ½μΉ΄λλ‘ λ±λ‘ (μ‘°μ μΌμΒ·μ²λ°©μΌμΒ·1ν 볡μ©λΒ·λ³΅μ© νμ)
- μ¬ν(μΆλ°μ§Β·λμ°©μ§Β·κΈ°κ°) λ±λ‘ λ° κ°μ Έκ° μ½ μ ν
- μ±λΆλ³ μ νΈλ± νμ β λ°μ κ°λ₯ / μ€λΉ νμ / λ°μ λΆκ°
- μλ νλκ° μλ μ±λΆμ μμ§λμ κ³μ°ν΄ νλμ λΉκ΅
- νμ κ·Όκ±°(μμ² λ¬ΈμΒ·κΈ°μ€μΌ) λ° κ΅κ°λ³ λ°μ κ·μ μ‘°ν
- νμ κ²°κ³Όμ λ°λΌ νμν μλ₯Β·νλ νλͺ©μ μλ μμ±
- νλͺ©λ³ μλ£ μ²΄ν¬, μ λΆ κ³΅μ μ μ² νμ΄μ§ λ§ν¬ μ°κ²°
- μ λ‘λκ° νμν νλͺ©μ PDF μ²¨λΆ (μ΅λ 10MB, PDF μκ·Έλμ²κΉμ§ κ²μ¦)
- μ λ‘λν μλ₯λ₯Ό AWS S3μ μ μ₯ (DBμλ κ°μ²΄ ν€λ§ 보κ΄)
- μ‘°ν μλ§λ€ λ§λ£ μκ°μ΄ μλ presigned URLμ λ°κΈν΄ 미리보기·λ€μ΄λ‘λ μ 곡
- μ½νλ³ μλ₯ λͺ©λ‘ μ‘°ν, μλ₯ μμ
- μΈκ΅λΆ μ¬μΈκ³΅κ΄ API μ°λ β νμ§ λμ¬κ΄Β·μμ¬κ΄ μ°λ½μ² μ‘°ν
- λ³΅μ© μ€μΈ μ½μ νμ§μ΄ μ€λͺ λ¬ΈμΌλ‘ λ³ν (OpenAI) β νμ§ λ³μΒ·μ½κ΅Β·μΈκ΄μμ μ μ
μ΄ μλΉμ€μ ν΅μ¬μ μ λΆ μμ² λ¬Έμμμ λ½μλΈ κ·μ λ°μ΄ν°μ λλ€. λλΌλ§λ€ λ¬Έμ νμμ΄ λ¬λΌ, μ€νλΌμΈμμ μ κ·νλ TSVλ‘ μΆμΆν΄ λκ³ μ ν리μΌμ΄μ μ΄ μμν λ UPSERT λ°©μμΌλ‘ μ μ¬ν©λλ€.
π μ λΆ μμ² λ¬Έμ(PDF)
β μ€νλΌμΈ μΆμΆ (pdfplumber)
βΌ
π μ κ·ν TSV (μ±λΆλͺ
Β· λΆλ₯ Β· κΈμ§ μ¬λΆ Β· μλ νλ Β· κΈ°μ€μΌ)
β μ± κΈ°λ μ μλ μ μ¬ (UPSERT β id μ μ§, λͺ©λ‘ μ΄νλΆμ λΉνμ±)
βΌ
ποΈ ingredient_regulation / requirement_template
β
βΌ
βοΈ νμ μμ§ β μ νΈλ± + μ€λΉ μλ₯ 체ν¬λ¦¬μ€νΈ
| κ΅κ° | μμ² | λΆλ₯ μ²΄κ³ |
|---|---|---|
| π―π΅ μΌλ³Έ | νμλ Έλμ± λ§μ½λ¨μλΆ(NCD) κ·μ μ½λ¬Ό λͺ©λ‘ | N(λ§μ½) Β· P(ν₯μ μ μ±) Β· SRM(κ°μ±μ μλ£) |
μ κ΅κ° μΆκ°λ CountryRegulationSource Β· CountryRequirementSource ꡬν체 νλμ
TSV ν λ²μ λνλ©΄ λλλλ‘ μ€κ³λΌ μμ΅λλ€.
-
Language / Runtime: Java 21 (Temurin)
-
Framework: Spring Boot 4.1.0, Spring Web MVC, Spring Data JPA, Bean Validation
-
Database: MySQL (Hibernate / JPA)
-
Auth: Kakao OAuth2 Login, Spring Security, JWT (jjwt 0.12.3)
-
Storage: AWS S3 (AWS SDK for Java v2, Presigned URL)
-
External API: μμ½μ² μμ½νμ 보, μΈκ΅λΆ μ¬μΈκ³΅κ΄, CLOVA OCR, OpenAI
-
Docs: springdoc-openapi 3.0.3 (Swagger UI)
-
Build / Deploy: Gradle (Wrapper), Docker, GitHub Actions
-
Etc.: Lombok, JPA Auditing
π± Mobile / Web
β μΉ΄μΉ΄μ€ λ‘κ·ΈμΈ Β· JWT
βΌ
π Medipass Backend (Spring Boot)
β
βββΆ ποΈ MySQL λλ©μΈ λ°μ΄ν° Β· κ·μ λ§μ€ν°
βββΆ πͺ£ AWS S3 μλ₯ μλ³Έ (Presigned URL λ°κΈ)
β
βββ π· CLOVA OCR μ½ λ΄ν¬ μΈμ
βββ π₯ μμ½μ² API μμ½ν νλͺ© Β· μ±λΆ μ‘°ν
βββ ποΈ μΈκ΅λΆ API μ¬μΈκ³΅κ΄ μ°λ½μ²
βββ π€ OpenAI νμ§μ΄ μ€λͺ
λ¬Έ μμ±
- μΈλΆ APIλ λͺ¨λ
global/*/clientμλ μ μ© ν΄λΌμ΄μΈνΈλ‘ κ°μΈ, λλ©μΈ μ½λκ° μΈλΆ μ€νμ μ§μ λ¬Άμ΄μ§ μκ² νμ΅λλ€. - κ·μ νμ μ μΈλΆ νΈμΆ μμ΄ μ°λ¦¬ DBλ§μΌλ‘ μκ²°λμ΄, μΈλΆ API μ₯μ μ 무κ΄νκ² λμν©λλ€.
- μλ₯λ DBμ URLμ μ μ₯νμ§ μκ³ κ°μ²΄ ν€λ§ 보κ΄ν λ€ μ‘°ν μλ§λ€ λ§λ£ν URLμ λ°κΈν©λλ€.
src/main/java/com/medipass/server
ββ domain
β ββ user # μ¬μ©μ, μΉ΄μΉ΄μ€ OAuth2 λ‘κ·ΈμΈ
β ββ country # κ΅κ° λ§μ€ν°
β ββ medication # μ½ λ΄ν¬ μ€μΊ Β· μμ½μ² λ§€μΉ Β· 볡μ½μΉ΄λ
β ββ regulation # κ·μ μ±λΆ Β· μλ₯ ν
νλ¦Ώ Β· νμ μμ§
β β ββ source # κ΅κ°λ³ κ·μ /μλ₯ Source
β ββ trip # μ¬ν Β· μ¬νλ³ μ½ Β· 체ν¬λ¦¬μ€νΈ
β ββ document # μλ₯ μ
λ‘λ Β· μλ₯ν¨
β ββ emergency # μ¬μΈκ³΅κ΄ λ°μ΄ν°
β ββ sos # κΈ΄κΈ μ°λ½μ² Β· νμ§μ΄ μ€λͺ
λ¬Έ
ββ global
ββ config # Security, Web, CORS μ€μ
ββ jwt # JWT νν° Β· Provider Β· UserDetails
ββ oauth # μΉ΄μΉ΄μ€ OAuth2 νΈλ€λ¬
ββ s3 # S3 μ
λ‘λ Β· Presigned URL
ββ ocr # CLOVA OCR ν΄λΌμ΄μΈνΈ
ββ mfds # μμ½μ² API ν΄λΌμ΄μΈνΈ
ββ mofa # μΈκ΅λΆ API ν΄λΌμ΄μΈνΈ
ββ openai # OpenAI ν΄λΌμ΄μΈνΈ Β· ν둬ννΈ
ββ response # κ³΅ν΅ μλ΅ (ApiResponse / Success / Error)
ββ exception # μ μ μμΈ μ²λ¦¬
ββ filter # μμ² ID νν°
ββ entity # BaseEntity (JPA Auditing)
ββ init # μ΄κΈ° λ°μ΄ν° λ‘λ (κ΅κ° Β· κ·μ Β· μλ₯ ν
νλ¦Ώ)
Swagger UIμ OAuth2 λ‘κ·ΈμΈ κ²½λ‘λ₯Ό μ μΈν λͺ¨λ μλν¬μΈνΈλ μΈμ¦μ΄ νμν©λλ€.
| Method | Endpoint | μ€λͺ |
|---|---|---|
| GET | /me |
λ΄ κ³μ μ 보 μ‘°ν |
| Method | Endpoint | μ€λͺ |
|---|---|---|
| POST | /scans |
μ½ λ΄ν¬ μ΄λ―Έμ§ μΈμ (OCR) |
| GET | /candidates |
μ νλͺ μΌλ‘ μμ½μ² μμ½ν ν보 κ²μ |
| POST | / |
OCR νμΈ κ²°κ³Όλ‘ μμ½ν λ±λ‘ |
| GET | / |
볡μ½μΉ΄λ λͺ©λ‘ μ‘°ν |
| GET | /cards |
ν νλ©΄ 볡μ½μΉ΄λ μ‘°ν |
| GET | /{medicationId}/card |
볡μ½μΉ΄λ λ¨κ±΄ μμΈ μ‘°ν |
| GET | /{medicationId}/documents |
μ½νλ³ μλ₯ λͺ©λ‘ μ‘°ν |
| Method | Endpoint | μ€λͺ |
|---|---|---|
| POST | /analyze |
μ¬ν μ 보 λΆμ |
| POST | / |
μ¬ν λ±λ‘ |
| GET | /checklog |
μ¬ν λͺ©λ‘ (체ν¬λ‘κ·Έ) |
| GET | /medications |
μ¬νμ λ΄μ μ μλ μ½ λͺ©λ‘ |
| GET | /{tripId} |
μ¬ν μμΈ μ‘°ν |
| PATCH | /{tripId}/title |
μ¬ν μ λͺ© μμ |
| DELETE | /{tripId} |
μ¬ν μμ |
| Method | Endpoint | μ€λͺ |
|---|---|---|
| GET | /destination |
λμ°© κ΅κ° λ°μ κ·μ μ‘°ν |
| GET | /basis |
νμ κ·Όκ±° μ‘°ν |
| GET | /checklist |
μ€λΉ 체ν¬λ¦¬μ€νΈ μ‘°ν |
| PATCH | /checklist/{checklistItemId} |
체ν¬λ¦¬μ€νΈ μλ£ μν λ³κ²½ |
| POST | /checklist/{checklistItemId}/document |
체ν¬λ¦¬μ€νΈ μλ₯ μ λ‘λ |
| Method | Endpoint | μ€λͺ |
|---|---|---|
| GET | / |
μλ₯ν¨ λ©μΈ μ‘°ν |
| GET | /{documentId} |
μλ₯ 보기 (미리보기 URL λ°κΈ) |
| POST | /{documentId}/download |
μλ₯ λ€μ΄λ‘λ URL λ°κΈ |
| DELETE | /{documentId} |
μλ₯ μμ |
| Method | Endpoint | μ€λͺ |
|---|---|---|
| POST | /api/regulations/judge |
μ±λΆ κ·μ νμ |
| POST | /api/sos/contacts |
νμ§ μ¬μΈκ³΅κ΄ μ°λ½μ² μ‘°ν |
| POST | /api/sos/scripts |
νμ§μ΄ μ€λͺ λ¬Έ μμ± |
![]() μ μ’ μ§ |
![]() μ‘°μ€μ§ |
| Backend | Backend |
| @ThreeeJ | @yj-044 |

