Skip to content

Commit bbfc8e8

Browse files
committed
Merge branch 'main' into claude/news-summary-bot-01MrWatfwa82rpEQQ2sbR2SX
2 parents 2b2c27c + 8d32e70 commit bbfc8e8

349 files changed

Lines changed: 60981 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
APP_NAME=JasoS
2+
DEBUG=true
3+
DATABASE_URL=sqlite:///./data/db/jasos.db
4+
OLLAMA_BASE_URL=http://localhost:11434
5+
OLLAMA_MODEL=ollama run qwen3-next:80b
6+
OPENAI_API_KEY= AIzaSyCA40zt0u8oYIAwSwfqzCE28o0INhP0YTc
7+
HOST=127.0.0.1
8+
PORT=8000

.gitignore

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
share/python-wheels/
20+
*.egg-info/
21+
.installed.cfg
22+
*.egg
23+
MANIFEST
24+
25+
# Virtual Environment
26+
.venv/
27+
venv/
28+
ENV/
29+
env/
30+
31+
# Environment Variables
32+
.env
33+
.env.*
34+
!.env.example
35+
36+
# Node/Frontend
37+
node_modules/
38+
dist/
39+
.DS_Store
40+
coverage/
41+
.next/
42+
.svelte-kit/
43+
build/
44+
45+
# IDEs
46+
.vscode/
47+
.idea/
48+
49+
# Custom
50+
# RAG/ (Integrated into main repo)
51+
52+
# Data & Uploads
53+
data/
54+
!data/learning/styles/README.md
55+
uploads/
56+
57+
# OS
58+
.DS_Store
59+
Thumbs.db
60+
.vercel

API_REFERENCE.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# JasoS API Reference
2+
3+
JasoS 백엔드 서버가 제공하는 API 엔드포인트 명세입니다.
4+
서버 주소: `http://localhost:8000` (기본값)
5+
API 문서(Swagger UI): `http://localhost:8000/docs`
6+
7+
---
8+
9+
## 1. Learning (학습)
10+
11+
이미지를 분석하여 글쓰기 스타일을 학습합니다.
12+
13+
| Method | Endpoint | 설명 | Request Body | Response |
14+
|:---:|---|---|---|---|
15+
| `POST` | **/api/learning/images** | 이미지 업로드 및 스타일 학습 | `multipart/form-data`<br>- `images`: 파일들<br>- `style_name`: 스타일 명 | `ImageLearningResponse`<br>(추출된 특징, 스타일ID) |
16+
17+
## 2. Styles (스타일 관리)
18+
19+
학습된 스타일 프로필을 조회하고 관리합니다.
20+
21+
| Method | Endpoint | 설명 | Request Body | Response |
22+
|:---:|---|---|---|---|
23+
| `GET` | **/api/styles** | 모든 스타일 목록 조회 | - | `List[StyleProfile]` |
24+
| `POST` | **/api/styles** | 새 스타일 생성 (수동) | `StyleProfileCreate` | `StyleProfile` |
25+
| `GET` | **/api/styles/{id}** | 특정 스타일 상세 조회 | - | `StyleProfile` |
26+
| `PUT` | **/api/styles/{id}** | 스타일 정보 수정 | `StyleProfileUpdate` | `StyleProfile` |
27+
| `DELETE`| **/api/styles/{id}** | 스타일 삭제 | - | `{"message": "..."}` |
28+
| `GET` | **/api/styles/{id}/rules**| 스타일별 규칙 조회 | - | `List[ExplicitRule]` |
29+
| `POST` | **/api/styles/{id}/rules**| 스타일에 명시적 규칙 추가 | `ExplicitRuleCreate` | `ExplicitRule` |
30+
31+
## 3. Writing (글쓰기)
32+
33+
스타일을 적용하여 글을 생성하고 버전을 관리합니다.
34+
35+
| Method | Endpoint | 설명 | Request Body | Response |
36+
|:---:|---|---|---|---|
37+
| `POST` | **/api/writing/generate** | AI 글 생성 요청 | `WritingGenerateRequest`<br>{`prompt`: "...", `style_id`: 1} | `WritingGenerateResponse`<br>(생성된 텍스트, 세션ID) |
38+
| `GET` | **/api/writing/sessions/{id}**| 작성 세션(히스토리) 조회 | - | `WritingSession` |
39+
| `POST` | **/api/writing/sessions/{id}/versions** | 새 버전(수정본) 저장 | `VersionCreateRequest`<br>{`content`: "..."} | `VersionResponse` |
40+
41+
---
42+
43+
## 4. External Dependencies (필수 외부 API)
44+
45+
JasoS 실행을 위해 필요한 외부 서비스/설정입니다.
46+
47+
### 🔹 Local AI (Ollama) - 권장
48+
49+
로컬에서 무료로 AI 모델을 실행합니다. 데이터가 외부로 유출되지 않습니다.
50+
51+
- **설치**: [Ollama.ai](https://ollama.ai) 다운로드
52+
- **실행**: `ollama run llama3.2` (또는 `mistral`)
53+
- **설정**: `.env` 파일의 `OLLAMA_BASE_URL=http://localhost:11434`
54+
55+
### 🔹 Cloud AI (OpenAI) - 선택
56+
57+
더 높은 품질의 생성을 위해 OpenAI GPT 모델을 사용할 수 있습니다.
58+
59+
- **API Key 발급**: [OpenAI Platform](https://platform.openai.com)
60+
- **설정**: `.env` 파일의 `OPENAI_API_KEY=sk-...` 입력
61+
62+
---
63+
64+
## 5. Analysis (JD/기업 분석)
65+
66+
채용공고(JD)를 업로드하고 분석 결과를 조회합니다.
67+
68+
| Method | Endpoint | 설명 | Request Body | Response |
69+
|:---:|---|---|---|---|
70+
| `POST` | **/api/analysis/upload** | JD 파일(PDF/Img) 업로드 및 분석 시작 | `multipart/form-data`<br>- `file`: JD 파일 | `AnalysisSession`<br>(세션ID 포함) |
71+
| `GET` | **/api/analysis/{session_id}** | 분석 결과 조회 (기업정보/인재상) | - | `AnalysisSession` |
72+
| `POST` | **/api/analysis/chat** | JD 내용 기반 질의응답 | `ChatRequest`<br>{`session_id`: 1, `message`: "..."} | `ChatResponse` |

RAG/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*.xlsx
2+
*.parquet
3+
*.env
4+
.DS_Store
5+
__pycache__/
6+
*.pyc

RAG/RAG_chatbot_ppt.pdf

6.02 MB
Binary file not shown.

RAG/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# RAG 기반 AI 챗봇을 활용한 기업 데이터 분석 플랫폼
2+
3+
삼정KPMG Future Academy 2기 1차 프로젝트 3조
4+
5+
```python==3.11.10```
6+
7+
```pip install -r requirements.txt```
8+
9+
```streamlit run st.py```

RAG/calendar_app.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import streamlit as st
2+
from streamlit_calendar import calendar
3+
4+
class CalendarApp:
5+
def __init__(self):
6+
self.calendar_options = {
7+
"editable": True,
8+
"selectable": True,
9+
"headerToolbar": {
10+
"left": "prev,next today",
11+
"center": "title",
12+
"right": "dayGridMonth,listMonth",
13+
},
14+
"initialView": "dayGridMonth",
15+
}
16+
17+
self.calendar_events = []
18+
19+
# 색상 설정
20+
self.color_map = {
21+
"발표": "#FF6F61", # 부드러운 주황색
22+
"서류 시작": "#4FC3F7", # 밝은 하늘색
23+
"서류 마감": "#81C784", # 연한 초록색
24+
"시험일": "#BA68C8", # 연한 보라색
25+
"발표일": "#9575CD", # 은은한 보라색
26+
"면접": "#FFA726", # 오렌지색
27+
"시험 접수": "#B0BEC5" # 차분한 회색
28+
}
29+
30+
# 캘린더 데이터
31+
calendar_data = {
32+
"12월": {
33+
"1일": ["하나손해보험 서류 마감"],
34+
"2일": ["기업은행 면접"],
35+
"3일": ["국민은행 최종 발표", "신한은행 2차 면접 발표", "국민은행 동계 인턴십 서류 마감"],
36+
"4일": ["예금보험공사 인턴 서류 발표", "우리자산운용 서류 발표", "신협중앙회 서류 마감", "미래에셋증권 서류 마감"],
37+
"5일": ["우체국금융개발원 서류 마감", "우리자산운용 1차 면접", "재경관리사 시작", "회계관리 시작", "AT자격시험 시작"],
38+
"6일": ["농협은행 5급 최종 발표", "농협중앙회 5급 최종 발표", "농협손해보험 최종 발표", "신용보증재단중앙회 1차 면접 발표", "신용보증재단중앙회 1차면접 발표", "매경테스트 발표", "파생상품투자권 발표", "유자문인력 발표", "외환전문역 발표"],
39+
"7일": ["우리금융캐피탈 필기 시험", "전산세무회계 시험"],
40+
"8일": [],
41+
"9일": ["농협은행 6급 최종 발표", "교보증권 인턴 필기 시험", "우체국금융개발원 면접", "경기신용보증재단 서류 마감"],
42+
"10일": ["한국재정정보원 인턴 최종 발표", "신용보증재단중앙회 인턴 면접 발표", "수협중앙회 2차 면접", "재경관리사 마감", "회계관리 마감"],
43+
"11일": ["국민은행 동계인턴십 서류 발표", "예금보험공사 인턴 면접", "신용보증재단중앙회 2차 면접", "AT자격시험"],
44+
"12일": ["국민연금공단 최종 발표", "기업은행 동계인턴 서류 발표"],
45+
"13일": ["AFPK 발표", "국민은행 동계인턴십 면접"],
46+
"14일": ["경기신용보증재단 필기 시험"],
47+
"15일": ["교보증권 인턴 서류 마감"],
48+
"16일": ["예금보험공사 인턴 면접 발표", "신용보증재단중앙회 최종 발표", "우체국금융개발원 최종 발표", "테셋 마감"],
49+
"17일": ["유통관리사 2급 발표"],
50+
"18일": ["우리은행 체험형 인턴 서류 발표", "교보증권 인턴 실무 면접"],
51+
"19일": ["지역농협 최종 발표","국민은행 동계 인턴십 최종 발표", "펀드투자자문사 인력 발표"],
52+
"20일": ["수협중앙회 최종 발표"],
53+
"21일": ["재경관리사 시험", "AT자격 시험", "회계관리 시험"],
54+
"22일": [],
55+
"23일": ["우리은행 체험형 인턴 면접"],
56+
"24일": ["우리자산운용 최종 발표"],
57+
"25일": [],
58+
"26일": ["신협중앙회 서류 발표", "전산세무회계 발표"],
59+
"27일": ["재경관리사 발표", "회계관리 발표"],
60+
"28일": ["테셋 시험"]
61+
}
62+
}
63+
64+
# 이벤트로 변환
65+
for day, events in calendar_data["12월"].items():
66+
if events: # 이벤트가 있는 경우에만 추가
67+
date = f"2024-12-{int(day[:-1]):02d}" # "1일" -> "2024-12-01"
68+
for event in events:
69+
category = self.get_event_category(event)
70+
self.calendar_events.append(
71+
{
72+
"title": event,
73+
"start": date,
74+
"color": self.color_map[category],
75+
"category": category
76+
}
77+
)
78+
79+
def get_event_category(self, event):
80+
"""이벤트 제목에 따라 카테고리를 반환"""
81+
if "발표" in event and "면접" not in event and "서류" not in event:
82+
return "발표일"
83+
elif "면접" in event:
84+
return "면접"
85+
elif "발표" in event:
86+
return "발표"
87+
elif "서류 시작" in event:
88+
return "서류 시작"
89+
elif "서류 마감" in event:
90+
return "서류 마감"
91+
elif "시험" in event:
92+
return "시험일"
93+
else:
94+
return "시험 접수"
95+
96+
def render(self):
97+
st.subheader("📅 금융권 채용 & 자격증 캘린더")
98+
99+
# 셀렉트 박스 카테고리 선택
100+
categories = [
101+
"전체 보기", "발표", "면접", "서류 시작", "서류 마감",
102+
"시험일", "발표일", "시험 접수"
103+
]
104+
selected_category = st.selectbox("카테고리 선택", categories)
105+
106+
# 필터링된 이벤트
107+
if selected_category == "전체 보기":
108+
filtered_events = self.calendar_events # 모든 이벤트 표시
109+
else:
110+
filtered_events = [
111+
event for event in self.calendar_events
112+
if event["category"] == selected_category
113+
]
114+
115+
# 캘린더 출력
116+
calendar(events=filtered_events, options=self.calendar_options)
117+
118+
def show():
119+
app = CalendarApp()
120+
app.render()
121+
122+
if __name__ == "__main__":
123+
show()

0 commit comments

Comments
 (0)