NOTI๋ AI ๊ธฐ์ ๊ณผ Spring Boot ๋ฐฑ์๋์ Android ์ฑ์ผ๋ก ๊ตฌ์ฑ๋ ์์ฑ ๊ธฐ๋ก ๋ฐ ์์ฝ ์๋น์ค์ ๋๋ค.
๐ฏ ํต์ฌ ๊ฐ์น
- ๋ น์์ ์งํํ๋ฉด ์๋์ผ๋ก ํ ์คํธ ๋ณํ ๋ฐ ์์ฝ ์ ๊ณต
- AI ๊ธฐ๋ฐ ๋ํํ ์ง์์๋ต์ผ๋ก ํ์ ๋ด์ฉ ๊ฒ์ ๋ฐ ๋ถ์
์ด ์๋น์ค๋ ํ์ ํ ๋ฌธ์ ์ ๋ฆฌ์ ์ด๋ ค์์ ๊ฒช๋ ์ง์ฅ์ธ๋ค์ ์ํด ์ค๊ณ๋์์ต๋๋ค. ์ ๋ก๋๋ ์์ฑ์ ๊ธฐ๋ฐ์ผ๋ก ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ์๋ ์์ฑํ๊ณ , AI ์์ฝ๋ณธ๊น์ง ํจ๊ป ์ ๊ณตํ์ฌ
[์ฌ๊ธฐ์ ๋ฐ๋ชจ ์์์ด๋ ์คํฌ๋ฆฐ์ท์ด ์ถ๊ฐํ๊ธฐ]
- ์ค์๊ฐ ์์ฑ ๋ น์: ์ฑ ๋ด์์ ์ง์ ํ์ ๋ น์ ๊ฐ๋ฅ
- STT ๋ณํ: ๋ น์ ํ์ผ์ Text๋ก ์ ํํ๋ Speech-to-Text ๊ธฐ๋ฅ
- ์ค๋งํธ ์์ฝ: AI ๊ธฐ๋ฐ ํ์ ๋ด์ฉ ์๋ ์์ฝ
- ๋ํํ ์ฑ๋ด: ํ์ ๋ด์ฉ ๊ธฐ๋ฐ ์ง์์๋ต ์์คํ
- ์ง๊ด์ ์ธ Android UI: ์ฌ์ฉํ๊ธฐ ์ฌ์ด ๋ชจ๋ฐ์ผ ์ธํฐํ์ด์ค
- ํด๋ผ์ฐ๋ ์ ์ฅ: ์๋ฒ ๊ธฐ๋ฐ ๋ฐ์ดํฐ ๋ณด๊ด ํน์ ์ฌ์ฉ์์ ๊ธฐ๊ธฐ ๋ก์ปฌ์ ๋ณด๊ด ๊ฐ๋ฅ
- ํ์ผ ๊ด๋ฆฌ: ์์ฑ ํ์ผ ์ด๋ฆ ์์ , ์ญ์ ๊ธฐ๋ฅ
- ์ฌ์ฉ์ ์ธ์ฆ: JWT ๊ธฐ๋ฐ ๋ณด์ ์์คํ
NotiApp/
โโโ ๐ฑ android/ # Android ์ ํ๋ฆฌ์ผ์ด์
โ โโโ app/src/main/
โ โ โโโ java/com/example/notiapp/
โ โ โ โโโ ๐ DashBoardActivity.kt # ๋ฉ์ธ ๋์๋ณด๋
โ โ โ โโโ ๐๏ธ RecordActivity.kt # ๋
น์ ๊ธฐ๋ฅ
โ โ โ โโโ ๐ฌ ChatbotActivity.kt # AI ์ฑ๋ด
โ โ โ โโโ ๐ SignInActivity.kt # ๋ก๊ทธ์ธ
โ โ โ โโโ ๐ RecordingDetailActivity.kt # ๋
น์ ์์ธ
โ โ โโโ res/ # ๋ฆฌ์์ค ํ์ผ
โ โโโ build.gradle.kts # Android ๋น๋ ์ค์
โ
โโโ ๐ฅ๏ธ noty/ # Spring Boot ๋ฐฑ์๋
โ โโโ src/main/java/com/expert/project/noty/
โ โ โโโ ๐๏ธ controller/ # REST API ์ปจํธ๋กค๋ฌ
โ โ โ โโโ ai/ # AI ๊ด๋ จ API
โ โ โ โโโ auth/ # ์ธ์ฆ API
โ โ โ โโโ file/ # ํ์ผ ๊ด๋ฆฌ API
โ โ โโโ ๐ง service/ # ๋น์ฆ๋์ค ๋ก์ง
โ โ โ โโโ ai/ # AI ์๋น์ค
โ โ โ โโโ auth/ # ์ธ์ฆ ์๋น์ค
โ โ โ โโโ file/ # ํ์ผ ์๋น์ค
โ โ โโโ ๐ entity/ # ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํฐํฐ
โ โ โโโ ๐๏ธ repository/ # ๋ฐ์ดํฐ ์ ๊ทผ ๊ณ์ธต
โ โ โโโ โ๏ธ config/ # ์ค์ ํ์ผ
โ โโโ build.gradle # ๋ฐฑ์๋ ๋น๋ ์ค์
โ
โโโ ๐ document/ # ํ๋ก์ ํธ ๋ฌธ์
โโโ agile/ # ์ ์์ผ ๊ฐ๋ฐ ๋ฌธ์
โโโ ํ๋์ผ์ง ๋ฐ ์ฃผ์ฐจ๋ณ ์คํฌ๋ผ/ # ๊ฐ๋ฐ ์ผ์ง
graph TB
A[๐ฑ Android ์ฑ<br/>Kotlin + Material Design]
A --> B[๐ Spring Boot ๋ฐฑ์๋<br/>Java 17 + JWT ๋ณด์]
B --> C[๐๏ธ MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค<br/>์ฌ์ฉ์ ๋ฐ์ดํฐ + ํ์ผ]
B --> D[๐ง AI ์๋น์ค]
D --> E[๐ค Google Speech-to-Text]
D --> F[๐ก Google Gemini AI]
%% ํด๋์ค ์ ์
classDef client fill:#ccf5e1,stroke:#00bf63,stroke-width:2px;
classDef backend fill:#e6f9f0,stroke:#009e53,stroke-width:2px;
classDef database fill:#fff5cc,stroke:#c9a000,stroke-width:2px;
classDef ai fill:#f5e6ff,stroke:#9c4dcc,stroke-width:2px;
classDef external fill:#f2f2f2,stroke:#666666,stroke-width:2px;
%% ํด๋์ค ์ ์ฉ
class A client;
class B backend;
class C database;
class D ai;
class E,F external;
graph TB
A[๐ SplashActivity<br/>์ฑ ์์ ํ๋ฉด] --> B[๐ SignInActivity<br/>๋ก๊ทธ์ธ]
B --> C[๐ DashBoardActivity<br/>๋ฉ์ธ ๋์๋ณด๋]
B --> D[โ๏ธ SignUpActivity<br/>ํ์๊ฐ์
]
D --> B
C --> E[๐๏ธ RecordActivity<br/>์์ฑ ๋
น์]
C --> F[๐ RecordingDetailActivity<br/>๋
น์ ์์ธ๋ณด๊ธฐ]
C --> G[๐ค UserInfoActivity<br/>์ฌ์ฉ์ ์ ๋ณด]
F --> H[๐ฌ ChatbotActivity<br/>AI ์ฑ๋ด ๋ํ]
%% ํด๋์ค ์ ์
classDef auth fill:#ccf5e1,stroke:#00bf63,stroke-width:2px;
classDef dashboard fill:#e6f9f0,stroke:#009e53,stroke-width:2px;
classDef record fill:#fff5cc,stroke:#c9a000,stroke-width:2px;
classDef user fill:#f2f2f2,stroke:#666666,stroke-width:2px;
classDef ai fill:#ffdfdf,stroke:#bf4040,stroke-width:2px;
%% ํด๋์ค ์ ์ฉ
class A,B,D auth;
class C dashboard;
class E,F record;
class G user;
class H ai;
graph TB
A[๐ฑ Android ํด๋ผ์ด์ธํธ] --> B[๐๏ธ REST Controllers]
B --> C[๐ AuthController<br/>์ธ์ฆ ์๋น์ค]
B --> D[๐ FileController<br/>ํ์ผ ์
๋ก๋]
B --> E[๐ง AI Controllers<br/>STT/Chat/Summary]
C --> F[๐๏ธ UserRepository]
D --> G[๐๏ธ AudioFileRepository]
E --> H[๐๏ธ SummationRepository]
E --> I[๐๏ธ ChatSessionRepository]
F --> J[๐๏ธ MySQL Database]
G --> J
H --> J
I --> J
E --> K[๐ค Google STT API]
E --> L[๐ง Gemini AI API]
%% ํด๋์ค ์ ์
classDef client fill:#ccf5e1,stroke:#00bf63,stroke-width:2px;
classDef controller fill:#e6f9f0,stroke:#009e53,stroke-width:2px;
classDef repository fill:#fff5cc,stroke:#c9a000,stroke-width:2px;
classDef database fill:#ffdfdf,stroke:#bf4040,stroke-width:2px;
classDef external fill:#f2f2f2,stroke:#666666,stroke-width:2px;
%% ํด๋์ค ์ ์ฉ
class A client;
class B,C,D,E controller;
class F,G,H,I repository;
class J database;
class K,L external;
# ํ์ ์ํํธ์จ์ด ์ค์น
- Java 17 ์ด์
- Android Studio (์ต์ ๋ฒ์ )
- MySQL 8.0
- Git# ํ๋ก์ ํธ ํด๋ก
git clone [repository-url]
cd NotiApp/noty
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์ (application.properties ํ์ผ ์์ )
# MySQL ์ฐ๊ฒฐ ์ ๋ณด, API ํค ๋ฑ ํ๊ฒฝ๋ณ์ ์ค์
# ์ ํ๋ฆฌ์ผ์ด์
์คํ
./gradlew bootRun
# ๋๋ IDE์์ NotyApplication.java ์คํ# Android Studio์์ android/ ํด๋ ์ด๊ธฐ
cd NotiApp/android
# Gradle ๋๊ธฐํ ํ ๋น๋
# Run 'app' ๋๋ Shift + F10
# ์๋ฎฌ๋ ์ดํฐ ๋๋ ์ค์ ๋๋ฐ์ด์ค์์ ์คํ# noty/src/main/resources/application.properties
# ๋ค์ ํญ๋ชฉ๋ค์ ์ค์ ๊ฐ์ผ๋ก ์ค์ :
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ
spring.datasource.url=jdbc:mysql://localhost:3306/noti_db
spring.datasource.username=your_username
spring.datasource.password=your_password
# Google API ํค
google.api.key=your_google_api_key
# JWT ์ํฌ๋ฆฟ
jwt.secret=your_jwt_secret| Method | Endpoint | ์ค๋ช |
|---|---|---|
| POST | /auth/register |
ํ์๊ฐ์ |
| POST | /auth/login |
๋ก๊ทธ์ธ |
| PUT | /auth/modify |
์ฌ์ฉ์ ์ ๋ณด ์์ |
| GET | /auth/user-info |
์ฌ์ฉ์ ์ ๋ณด ์กฐํ |
| Method | Endpoint | ์ค๋ช |
|---|---|---|
| POST | /file/upload |
์์ฑ ํ์ผ ์ ๋ก๋ |
| GET | /file/list |
ํ์ผ ๋ชฉ๋ก ์กฐํ |
| GET | /file/{fileId} |
ํ์ผ ์ ๋ณด ์กฐํ |
| PUT | /file/{fileId}/name |
ํ์ผ๋ช ์์ |
| DELETE | /file/{fileId} |
ํ์ผ ์ญ์ |
| Method | Endpoint | ์ค๋ช |
|---|---|---|
| POST | /ai/stt |
์์ฑ์ ํ ์คํธ๋ก ๋ณํ |
| POST | /ai/summary |
ํ ์คํธ ์์ฝ |
| POST | /ai/chat |
AI ์ฑ๋ด ๋ํ |
| GET | /ai/sessions |
์ฑ๋ด ์ธ์ ๋ชฉ๋ก |
| POST | /ai/sessions |
์ ์ฑ๋ด ์ธ์ ์์ฑ |
{
"success": true,
"message": "์ฑ๊ณต์ ์ผ๋ก ์ฒ๋ฆฌ๋์์ต๋๋ค",
"data": {
"fileId": "uuid-string",
"fileName": "meeting_record.mp3",
"transcription": "ํ์ ๋ด์ฉ ํ
์คํธ...",
"summary": "ํ์ ์์ฝ ๋ด์ฉ..."
}
}-- ์ฌ์ฉ์ ์ ๋ณด
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
email VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- ์ค๋์ค ํ์ผ ์ ๋ณด
CREATE TABLE audio_files (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
original_filename VARCHAR(255),
stored_filename VARCHAR(255),
file_path VARCHAR(500),
file_size BIGINT,
upload_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
-- ์ฑ๋ด ์ธ์
CREATE TABLE chatbot_sessions (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
audio_file_id BIGINT,
session_name VARCHAR(255),
status VARCHAR(20) DEFAULT 'ACTIVE',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (audio_file_id) REFERENCES audio_files(id)
);
-- ์ฑํ
๋ํ ๊ธฐ๋ก
CREATE TABLE chat_conversations (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
session_id BIGINT NOT NULL,
user_message TEXT,
ai_response TEXT,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (session_id) REFERENCES chatbot_sessions(id)
);# Google API ์ค์
GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account-key.json
GOOGLE_API_KEY=your_google_api_key
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์
DB_URL=jdbc:mysql://localhost:3306/noti_db
DB_USERNAME=your_username
DB_PASSWORD=your_password
# JWT ์ค์
JWT_SECRET=your_jwt_secret_key
JWT_EXPIRATION=86400000
# ์๋ฒ ์ค์
SERVER_PORT=8080# ๋ฐฑ์๋ ํ
์คํธ
cd noty
./gradlew test
# Android ํ
์คํธ
cd android
./gradlew test
./gradlew connectedAndroidTest # ๊ธฐ๊ธฐ ์ฐ๊ฒฐ๋ ์ํ์์ ์คํ- ์ด์ ๋ฑ๋ก: ๋ฒ๊ทธ ๋ฆฌํฌํธ๋ ๊ธฐ๋ฅ ์ ์์ GitHub Issues์ ๋ฑ๋ก
- ํฌํฌ & ๋ธ๋์น: ๋ ํฌ์งํ ๋ฆฌ๋ฅผ ํฌํฌํ๊ณ ์ ๋ธ๋์น ์์ฑ
- ๊ฐ๋ฐ: ์ฝ๋ ์ปจ๋ฒค์ ์ ์ค์ํ์ฌ ๊ฐ๋ฐ
- ํ ์คํธ: ๋ณ๊ฒฝ์ฌํญ์ ๋ํ ํ ์คํธ ์ผ์ด์ค ์์ฑ ๋ฐ ์คํ
- Pull Request: ์์ธํ ์ค๋ช ๊ณผ ํจ๊ป PR ์์ฑ
- Java/Kotlin: Google Java Style Guide ์ค์
- ์ปค๋ฐ ๋ฉ์์ง:
feat:,fix:,docs:๋ฑ์ ์ ๋์ฌ ์ฌ์ฉ - ๋ธ๋์น ๋ช
๋ช
:
feature/๊ธฐ๋ฅ๋ช,bugfix/์ด์๋ฒํธํ์
- ํ๋ก ํธ์๋: Android ๋ค์ดํฐ๋ธ ๊ฐ๋ฐ
- ๋ฐฑ์๋: Spring Boot REST API ๊ฐ๋ฐ
- AI/ML: ์์ฑ ์ธ์ ๋ฐ ์์ฐ์ด ์ฒ๋ฆฌ
- UI/UX: ์ฌ์ฉ์ ๊ฒฝํ ๋์์ธ
์ด ํ๋ก์ ํธ๋ Apache License 2.0 ํ์ ๋ฐฐํฌ๋ฉ๋๋ค.
์์ ๋กญ๊ฒ ์ฌ์ฉ, ์์ , ๋ฐฐํฌํ ์ ์์ผ๋ฉฐ ์์ ์ ๋ชฉ์ ์ผ๋ก๋ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค. ๋ผ์ด์ ์ค๋ ๊ธฐ์ฌ์๋ก๋ถํฐ ์ฌ์ฉ์์๊ฒ ํนํ๊ถ์ ๋ช ์์ ์ผ๋ก ๋ถ์ฌํฉ๋๋ค.
์ ์ฒด ๋ผ์ด์ ์ค ๋ด์ฉ์ LICENSE ํ์ผ์ ์ฐธ์กฐํ์ธ์.
