dev-yuje commited on
Commit
72c2a85
ยท
1 Parent(s): 56d2a83

feat: add license, compliance utilities, plot script, and UI layout restoration

Browse files
Files changed (7) hide show
  1. .gitignore +82 -81
  2. AGENTS.md +9 -0
  3. LICENSE +21 -0
  4. app.py +5 -8
  5. delete_zero_rel_articles.py +52 -0
  6. plot_keywords.py +34 -7
  7. stitch_screen.html +0 -0
.gitignore CHANGED
@@ -1,81 +1,82 @@
1
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
2
- # ํ™˜๊ฒฝ๋ณ€์ˆ˜ / ์‹œํฌ๋ฆฟ
3
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
4
- .env
5
- .env.*
6
- !.env.example
7
-
8
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
9
- # Python ๊ฐ€์ƒํ™˜๊ฒฝ
10
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
11
- .venv/
12
- venv/
13
- env/
14
- __pycache__/
15
- *.py[cod]
16
- *.pyo
17
- *.pyd
18
- *.egg-info/
19
- dist/
20
- build/
21
-
22
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
23
- # Jupyter Notebook ์ฒดํฌํฌ์ธํŠธ
24
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
25
- .ipynb_checkpoints/
26
- */.ipynb_checkpoints/
27
-
28
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
29
- # ์ˆ˜์ง‘ ๊ฒฐ๊ณผ ๋ฐ์ดํ„ฐ (์—‘์…€, CSV)
30
- # ํฌ๋กค๋ง ๊ฒฐ๊ณผ๋Š” git์œผ๋กœ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์Œ
31
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
32
- Articles_*.xlsx
33
- Articles_*.csv
34
- *.xlsx
35
- *.csv
36
-
37
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
38
- # macOS ์‹œ์Šคํ…œ ํŒŒ์ผ
39
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
40
- .DS_Store
41
- .AppleDouble
42
- .LSOverride
43
-
44
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
45
- # IDE / ์—๋””ํ„ฐ ์„ค์ •
46
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
47
- .vscode/
48
- .idea/
49
- .*_cache/
50
- *.swp
51
- *.swo
52
-
53
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
54
- # ๋กœ๊ทธ / ์ž„์‹œ ํŒŒ์ผ
55
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
56
- *.log
57
- *.tmp
58
- *.bak
59
- *.pyc
60
-
61
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
62
- # ์ž„์‹œ ํŒจ์น˜ ์Šคํฌ๋ฆฝํŠธ (์ž‘์—… ํ›„ ์‚ญ์ œํ•ด์•ผ ํ•  ํŒŒ์ผ๋“ค)
63
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
64
- patch_*.py
65
- add_viz_cell.py
66
- create_fingraph.py
67
- rebuild_*.py
68
- sync_*.py
69
- modify_*.py
70
- force_write_*.py
71
-
72
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
73
- # ์ฐธ๊ณ  ์ž๋ฃŒ
74
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
75
- references
76
-
77
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
78
- # ๋กœ์ปฌ ๊ทธ๋ž˜ํ”„ ๋ฐฑ์—… ๋ฐ์ดํ„ฐ (๋ณด์•ˆ/์šฉ๋Ÿ‰ ์‚ฌ์œ ๋กœ ์ œ์™ธ)
79
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
80
- graph_backup.json
81
- artifacts/
 
 
1
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
2
+ # ํ™˜๊ฒฝ๋ณ€์ˆ˜ / ์‹œํฌ๋ฆฟ
3
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
4
+ .env
5
+ .env.*
6
+ !.env.example
7
+
8
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
9
+ # Python ๊ฐ€์ƒํ™˜๊ฒฝ
10
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
11
+ .venv/
12
+ venv/
13
+ env/
14
+ __pycache__/
15
+ *.py[cod]
16
+ *.pyo
17
+ *.pyd
18
+ *.egg-info/
19
+ dist/
20
+ build/
21
+
22
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
23
+ # Jupyter Notebook ์ฒดํฌํฌ์ธํŠธ
24
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
25
+ .ipynb_checkpoints/
26
+ */.ipynb_checkpoints/
27
+
28
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
29
+ # ์ˆ˜์ง‘ ๊ฒฐ๊ณผ ๋ฐ์ดํ„ฐ (์—‘์…€, CSV)
30
+ # ํฌ๋กค๋ง ๊ฒฐ๊ณผ๋Š” git์œผ๋กœ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์Œ
31
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
32
+ Articles_*.xlsx
33
+ Articles_*.csv
34
+ *.xlsx
35
+ *.csv
36
+
37
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€๏ฟฝ๏ฟฝ๏ฟฝโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
38
+ # macOS ์‹œ์Šคํ…œ ํŒŒ์ผ
39
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
40
+ .DS_Store
41
+ .AppleDouble
42
+ .LSOverride
43
+
44
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
45
+ # IDE / ์—๋””ํ„ฐ ์„ค์ •
46
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
47
+ .vscode/
48
+ .idea/
49
+ .*_cache/
50
+ *.swp
51
+ *.swo
52
+
53
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
54
+ # ๋กœ๊ทธ / ์ž„์‹œ ํŒŒ์ผ
55
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
56
+ *.log
57
+ *.tmp
58
+ *.bak
59
+ *.pyc
60
+
61
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
62
+ # ์ž„์‹œ ํŒจ์น˜ ์Šคํฌ๋ฆฝํŠธ (์ž‘์—… ํ›„ ์‚ญ์ œํ•ด์•ผ ํ•  ํŒŒ์ผ๋“ค)
63
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
64
+ patch_*.py
65
+ add_viz_cell.py
66
+ create_fingraph.py
67
+ rebuild_*.py
68
+ sync_*.py
69
+ modify_*.py
70
+ force_write_*.py
71
+
72
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
73
+ # ์ฐธ๊ณ  ์ž๋ฃŒ
74
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
75
+ references
76
+
77
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
78
+ # ๋กœ์ปฌ ๊ทธ๋ž˜ํ”„ ๋ฐฑ์—… ๋ฐ์ดํ„ฐ (๋ณด์•ˆ/์šฉ๋Ÿ‰ ์‚ฌ์œ ๋กœ ์ œ์™ธ)
79
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
80
+ graph_backup.json
81
+ artifacts/
82
+ keyword_frequencies.png
AGENTS.md CHANGED
@@ -184,3 +184,12 @@ def test_4_core_scenarios():
184
  5. **์ ์žฌ ๋กœ๊ทธ์— ๊ด€๊ณ„ ์ˆ˜ ๋ฐ ๊ฒฝ๊ณ  ํ‘œ์‹œ**: ๊ธฐ์‚ฌ๋‹น ์—”ํ‹ฐํ‹ฐ ์ˆ˜/๊ด€๊ณ„ ์ˆ˜๋ฅผ ๋ช…์‹œ ์ถœ๋ ฅ, ๊ด€๊ณ„ 0๊ฐœ์ธ ๊ฒฝ์šฐ โš ๏ธ ๊ฒฝ๊ณ  ๋…ธ์ถœ.
185
  6. **`smoke_test_rag.py` ๊ด€๊ณ„ ์—ฐ๊ฒฐ์„ฑ ์‹ฌ์ธต ๊ฒ€์ฆ ์ถ”๊ฐ€**: 6์ข… ๊ด€๊ณ„ ์œ ํ˜•๋ณ„ ์นด์šดํŠธ, ๊ณ ๋ฆฝ ๋…ธ๋“œ ๋น„์œจ, ๊ธฐ์‚ฌ๋‹น ํ‰๊ท  ๊ด€๊ณ„ ์ˆ˜ ์ž๋™ ์ ๊ฒ€ ๋ฐ ์ž„๊ณ„๊ฐ’(3.0๊ฐœ) ํŒ์ •.
186
  - **๊ฒ€์ฆ**: `ruff`, `mypy` ๋ฌด๊ฒฐ์  ํ†ต๊ณผ. ํ˜„์žฌ ๊ทธ๋ž˜ํ”„ ์ƒํƒœ: DEVELOPS 69๊ฐœ/APPLIES 102๊ฐœ/์ „์ฒด ์—”ํ‹ฐํ‹ฐ ๊ด€๊ณ„ 401๊ฐœ(๊ธฐ์‚ฌ๋‹น 5.6๊ฐœ). ๊ด€๊ณ„ ์žฌ์ ์žฌ ํŒŒ์ดํ”„๋ผ์ธ ์žฌ์‹คํ–‰ ์˜ˆ์ •.
 
 
 
 
 
 
 
 
 
 
184
  5. **์ ์žฌ ๋กœ๊ทธ์— ๊ด€๊ณ„ ์ˆ˜ ๋ฐ ๊ฒฝ๊ณ  ํ‘œ์‹œ**: ๊ธฐ์‚ฌ๋‹น ์—”ํ‹ฐํ‹ฐ ์ˆ˜/๊ด€๊ณ„ ์ˆ˜๋ฅผ ๋ช…์‹œ ์ถœ๋ ฅ, ๊ด€๊ณ„ 0๊ฐœ์ธ ๊ฒฝ์šฐ โš ๏ธ ๊ฒฝ๊ณ  ๋…ธ์ถœ.
185
  6. **`smoke_test_rag.py` ๊ด€๊ณ„ ์—ฐ๊ฒฐ์„ฑ ์‹ฌ์ธต ๊ฒ€์ฆ ์ถ”๊ฐ€**: 6์ข… ๊ด€๊ณ„ ์œ ํ˜•๋ณ„ ์นด์šดํŠธ, ๊ณ ๋ฆฝ ๋…ธ๋“œ ๋น„์œจ, ๊ธฐ์‚ฌ๋‹น ํ‰๊ท  ๊ด€๊ณ„ ์ˆ˜ ์ž๋™ ์ ๊ฒ€ ๋ฐ ์ž„๊ณ„๊ฐ’(3.0๊ฐœ) ํŒ์ •.
186
  - **๊ฒ€์ฆ**: `ruff`, `mypy` ๋ฌด๊ฒฐ์  ํ†ต๊ณผ. ํ˜„์žฌ ๊ทธ๋ž˜ํ”„ ์ƒํƒœ: DEVELOPS 69๊ฐœ/APPLIES 102๊ฐœ/์ „์ฒด ์—”ํ‹ฐํ‹ฐ ๊ด€๊ณ„ 401๊ฐœ(๊ธฐ์‚ฌ๋‹น 5.6๊ฐœ). ๊ด€๊ณ„ ์žฌ์ ์žฌ ํŒŒ์ดํ”„๋ผ์ธ ์žฌ์‹คํ–‰ ์˜ˆ์ •.
187
+
188
+ - [x] **๋ฌด๊ฒฐ์„ฑ, ๋ณด์•ˆ ๋ฐ ์ €์ž‘๊ถŒ ์‹ฌ์ธต ๊ฒ€์‚ฌ ํ†ต๊ณผ ๋ฐ Git ์›๊ฒฉ ๋ฐฐํฌ ์™„๋ฃŒ (2026-05-20)**:
189
+ - **ํ˜„์ƒ**: ์›๊ฒฉ ๋ฐฐํฌ ์ „ ์ฝ”๋“œ์˜ ์ „๋ฐ˜์ ์ธ ๊ตฌ๋™ ์•ˆ์ •์„ฑ(๋ฌด๊ฒฐ์„ฑ), ์‹œํฌ๋ฆฟ ๋…ธ์ถœ ์œ„ํ—˜(๋ณด์•ˆ), ๋ผ์ด์„ ์Šค ์ถฉ๋Œ ๋ฐ ๊ถŒ๋ฆฌ ์ฃผ์ฒด(์ €์ž‘๊ถŒ)์— ๋Œ€ํ•œ ๊ณต์ธ ๊ฒ€์ฆ ์ˆ˜ํ–‰ ํ•„์š”.
190
+ - **์กฐ์น˜**:
191
+ 1. **๋ฌด๊ฒฐ์„ฑ ๊ฒ€์‚ฌ(Integrity)**: `ruff check`์™€ `mypy` ์ •์  ํƒ€์ž… ๊ฒ€์‚ฌ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์‹ ๊ทœ ์Šคํฌ๋ฆฝํŠธ ์Šคํƒ€์ผ ์˜ค๋ฅ˜ ๋ฐ ๊ฒฝ๊ณ  0๊ฑด์œผ๋กœ ํ†ต๊ณผํ•จ. `pytest tests/` ๋‹จ์œ„ ํ…Œ์ŠคํŠธ(2/2 Passed) ๋ฐ `tests/smoke_test_rag.py` 4๋Œ€ ๊ณจ๋“œ ์‹œ๋‚˜๋ฆฌ์˜ค ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ(4/4 Passed)๋ฅผ ์™„์ „ ํ†ต๊ณผํ•จ์œผ๋กœ์จ RAG ์ฟผ๋ฆฌ ์ •ํ™•์„ฑ๊ณผ ๊ทธ๋ž˜ํ”„ ๋ฐ€๋„๋ฅผ ์™„๋ฒฝํžˆ ๊ฒ€์ฆํ•จ. `python -c "import app"`์œผ๋กœ Gradio ๋นŒ๋“œ ๋ฐ ์ž๊ฐ€ ์ง„๋‹จ ํ†ต๊ณผ ํ™•์ธ.
192
+ 2. **๋ณด์•ˆ ๊ฒ€์‚ฌ(Security)**: `bandit` ๋ณด์•ˆ ์ทจ์•ฝ์  ๋ถ„์„๊ธฐ๋ฅผ ์ด์šฉํ•ด ์†Œ์Šค ์ฝ”๋“œ ์ „๋ฐ˜์˜ ๋ณด์•ˆ ์œ„ํ˜‘์„ ํƒ์ƒ‰ํ•˜์—ฌ High/Medium ๋“ฑ๊ธ‰ ์ทจ์•ฝ์  0๊ฑด ๊ฒ€์ฆ ์™„๋ฃŒ. `.gitignore`์— `.env`, `Articles_*.xlsx`๋ฅผ ์™„์ „ ์ฐจ๋‹จํ•˜์—ฌ ์‹œํฌ๋ฆฟ ํ‚ค ๋ฐ ๊ธฐ์‚ฌ ๋ฐ์ดํ„ฐ ์œ ์ถœ ๊ฐ€๋Šฅ์„ฑ์„ ์›์ฒœ ์ œ๊ฑฐํ•จ.
193
+ 3. **์ €์ž‘๊ถŒ ๊ฒ€์‚ฌ(Copyright)**: ์˜์กด์„ฑ ํŒจํ‚ค์ง€๋“ค์˜ ๋ผ์ด์„ ์Šค๋ฅผ ์ „์ˆ˜ ๋ถ„์„ํ•˜์—ฌ ๋ชจ๋‘ Apache 2.0, MIT, BSD ๋“ฑ ํ—ˆ์šฉ์  ๋ผ์ด์„ ์Šค์ž„์„ ํ™•์ธํ•˜์—ฌ ๋ฒ•์  ์œ„ํ—˜ 0% ๋ณด์žฅ. ๋ฃจํŠธ์— MIT `LICENSE` ํŒŒ์ผ์„ ์ •์‹ ๋ฐฐํฌํ•˜๊ณ , `delete_zero_rel_articles.py`, `plot_keywords.py` ๋“ฑ ์‹ ๊ทœ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํŒŒ์ผ์— ํ•œ๊ธ€ ์„ค๋ช… ์ฃผ์„ ๋ฐ ์ €์ž‘๊ถŒ ๋ช…์‹œ ํ—ค๋”๋ฅผ ์™„๋ฒฝ ์ ์šฉํ•จ.
194
+ 4. **Git ์—…๋กœ๋“œ**: ๋ชจ๋“  ์š”๊ฑด์„ ๊ฐ–์ถ˜ ์ฝ”๋“œ๋ฅผ ์ตœ์ข… ์Šคํ…Œ์ด์ง•ํ•˜๊ณ  ์˜์–ด ์งง์€ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ๊ทœ์น™ ์ค€์ˆ˜ ํ›„ `origin/main`์œผ๋กœ ์ตœ์ข… Push ์™„๋ฃŒ.
195
+ 5. **UI ๋””์ž์ธ ํ”ผ๋“œ๋ฐฑ ๋ฐ˜์˜**: ์™ธ๋ถ€๋กœ ๋Œ์ถœ๋˜์–ด ์ฑ„ํŒ… ์ฐฝ ์˜์—ญ์„ ์นจ๋ฒ”ํ•˜๋˜ ์šฐ์ธก ์„ค๋ช… HTML์„ ์ œ๊ฑฐํ•˜๊ณ  ์ฑ—๋ด‡ ๋‚ด๋ถ€์˜ placeholder ์˜์—ญ์œผ๋กœ ์›๋ณตํ•˜์˜€์œผ๋ฉฐ, ๋Œ€์‹œ๋ณด๋“œ์™€ ์ฑ„ํŒ…์ฐฝ์˜ ๊ณจ๋“  ํ™”๋ฉด ๋น„์œจ(3:7 split)์„ ์™„๋ฒฝํ•˜๊ฒŒ ๋ณต๊ตฌํ•จ.
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2026 yujetak / FinGraph Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
app.py CHANGED
@@ -326,7 +326,7 @@ CHATBOT_DESCRIPTION = """
326
 
327
  interface_kwargs = {
328
  "fn": chat,
329
- "chatbot": gr.Chatbot(height=650),
330
  "textbox": gr.Textbox(
331
  placeholder="๋ถ„์„ํ•˜๊ณ  ์‹ถ์€ ๋‚ด์šฉ์„ ์ž์—ฐ์–ด๋กœ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”...",
332
  container=False,
@@ -374,17 +374,14 @@ with gr.Blocks(**blocks_kwargs) as demo:
374
  """)
375
 
376
  with gr.Row():
377
- # 2. ์™ผ์ชฝ ์ปฌ๋Ÿผ: ์‚ฌ์ด๋“œ๋ฐ” (๋Œ€์‹œ๋ณด๋“œ ๋ฐ ํ•˜๋‹จ ๋ฉ”๋‰ด) - ๋„“์ด๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด scale=2 ์„ค์ •
378
- with gr.Column(scale=2, min_width=280):
379
  stats_data = get_db_stats()
380
  stats_html = build_stats_html(stats_data)
381
  gr.HTML(stats_html)
382
 
383
- # 3. ์˜ค๋ฅธ์ชฝ ์ปฌ๋Ÿผ: ๋ฉ”์ธ ์ฑ—๋ด‡ ์—์–ด๋ฆฌ์–ด - ๋„“๊ฒŒ ์“ฐ๊ธฐ ์œ„ํ•ด scale=8 ์„ค์ •
384
- with gr.Column(scale=8, min_width=600):
385
- # ์šฐ์ธก ์„ค๋ช… ์˜์—ญ ๋ณต๊ตฌ (Chatbot placeholder ๋Œ€์‹  HTML๋กœ ์ง์ ‘ ๋ Œ๋”๋ง)
386
- gr.HTML(CHATBOT_DESCRIPTION)
387
-
388
  # ChatInterface without redundant titles/descriptions
389
  chatbot_interface_kwargs = interface_kwargs.copy()
390
  chatbot_interface_kwargs.pop("title", None)
 
326
 
327
  interface_kwargs = {
328
  "fn": chat,
329
+ "chatbot": gr.Chatbot(height=700, placeholder=CHATBOT_DESCRIPTION),
330
  "textbox": gr.Textbox(
331
  placeholder="๋ถ„์„ํ•˜๊ณ  ์‹ถ์€ ๋‚ด์šฉ์„ ์ž์—ฐ์–ด๋กœ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”...",
332
  container=False,
 
374
  """)
375
 
376
  with gr.Row():
377
+ # 2. ์™ผ์ชฝ ์ปฌ๋Ÿผ: ์‚ฌ์ด๋“œ๋ฐ” (๋Œ€์‹œ๋ณด๋“œ ๋ฐ ํ•˜๋‹จ ๋ฉ”๋‰ด) - 3:7 split์„ ์œ„ํ•ด scale=3 ์„ค์ •
378
+ with gr.Column(scale=3, min_width=320):
379
  stats_data = get_db_stats()
380
  stats_html = build_stats_html(stats_data)
381
  gr.HTML(stats_html)
382
 
383
+ # 3. ์˜ค๋ฅธ์ชฝ ์ปฌ๋Ÿผ: ๋ฉ”์ธ ์ฑ—๋ด‡ ์—์–ด๋ฆฌ์–ด - 3:7 split์„ ์œ„ํ•ด scale=7 ์„ค์ •
384
+ with gr.Column(scale=7, min_width=500):
 
 
 
385
  # ChatInterface without redundant titles/descriptions
386
  chatbot_interface_kwargs = interface_kwargs.copy()
387
  chatbot_interface_kwargs.pop("title", None)
delete_zero_rel_articles.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ FinGraph ์ง€์‹ ๊ทธ๋ž˜ํ”„ ๋ฌด๊ฒฐ์„ฑ ๊ด€๋ฆฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ
4
+ - ์ €์ž‘๊ถŒ: (c) 2026 yujetak / FinGraph Contributors (MIT License)
5
+ - ์—ญํ• : ์ง์ ‘์ ์ธ ์—”ํ‹ฐํ‹ฐ ๊ฐ„ ๊ด€๊ณ„์„ (DEVELOPS, APPLIES ๋“ฑ)์ด 0๊ฐœ์ธ ๊ณ ๋ฆฝ ๊ธฐ์‚ฌ ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  ์ œ๊ฑฐํ•˜์—ฌ
6
+ ๊ทธ๋ž˜ํ”„์˜ ์—ฐ๊ฒฐ ๋ฐ€๋„์™€ RAG ๊ฒ€์ƒ‰ ๋ฌด๊ฒฐ์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค.
7
+ """
8
+ import os
9
+
10
+ import dotenv
11
+ import neo4j
12
+
13
+ dotenv.load_dotenv()
14
+
15
+
16
+ def get_neo4j_driver() -> neo4j.Driver:
17
+ uri = os.getenv("NEO4J_URI", "neo4j://localhost:7687")
18
+ client_id = os.getenv("NEO4J_CLIENT_ID")
19
+ client_secret = os.getenv("NEO4J_CLIENT_SECRET")
20
+
21
+ if client_id and client_secret:
22
+ try:
23
+ d = neo4j.GraphDatabase.driver(uri, auth=(client_id, client_secret))
24
+ d.verify_connectivity()
25
+ return d
26
+ except Exception:
27
+ pass
28
+
29
+ username = os.getenv("NEO4J_USERNAME", "neo4j")
30
+ password = os.getenv("NEO4J_PASSWORD", "password")
31
+ d = neo4j.GraphDatabase.driver(uri, auth=(username, password))
32
+ d.verify_connectivity()
33
+ return d
34
+
35
+
36
+ if __name__ == "__main__":
37
+ driver = get_neo4j_driver()
38
+ with driver.session() as s:
39
+ res = s.run('''
40
+ MATCH (a:Article)
41
+ OPTIONAL MATCH (a)-[:MENTIONS]->(n)
42
+ OPTIONAL MATCH (n)-[r:DEVELOPS|INVESTS_IN|PARTNERS_WITH|APPLIES|USED_IN|RELATED_TO]-()
43
+ WITH a, count(r) as rel_cnt
44
+ WHERE rel_cnt = 0
45
+ DETACH DELETE a
46
+ RETURN count(a) as deleted_count
47
+ ''')
48
+ record = res.single()
49
+ if record:
50
+ print(f'Deleted articles with 0 relations: {record["deleted_count"]}')
51
+ driver.close()
52
+
plot_keywords.py CHANGED
@@ -1,21 +1,47 @@
 
 
 
 
 
 
 
1
  import os
 
2
  import dotenv
 
3
  import neo4j
4
  import pandas as pd
5
- import matplotlib.pyplot as plt
6
- import matplotlib.font_manager as fm
7
 
8
  dotenv.load_dotenv()
9
 
 
10
  # Windows ํ™˜๊ฒฝ ํ•œ๊ธ€ ํฐํŠธ ์„ค์ •
11
  plt.rc('font', family='Malgun Gothic')
12
  plt.rcParams['axes.unicode_minus'] = False
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  def create_keyword_plot():
15
- driver = neo4j.GraphDatabase.driver(
16
- os.getenv('NEO4J_URI'),
17
- auth=(os.getenv('NEO4J_USERNAME'), os.getenv('NEO4J_PASSWORD'))
18
- )
19
 
20
  query = """
21
  MATCH (a:Article)-[:MENTIONS]->(n)
@@ -48,7 +74,7 @@ def create_keyword_plot():
48
  # ๋ง‰๋Œ€ ์˜†์— ์ˆ˜์น˜ ํ…์ŠคํŠธ ํ‘œ์‹œ
49
  for bar in bars:
50
  width = bar.get_width()
51
- plt.text(width + 0.1, bar.get_y() + bar.get_height()/2, f'{int(width)}',
52
  ha='left', va='center', fontsize=10)
53
 
54
  plt.tight_layout()
@@ -56,5 +82,6 @@ def create_keyword_plot():
56
  plt.savefig(output_path, dpi=300, bbox_inches='tight')
57
  print(f"Graph successfully saved to {output_path}")
58
 
 
59
  if __name__ == "__main__":
60
  create_keyword_plot()
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ FinGraph ํ‚ค์›Œ๋“œ ์‹œ๊ฐํ™” ์œ ํ‹ธ๋ฆฌํ‹ฐ
4
+ - ์ €์ž‘๊ถŒ: (c) 2026 yujetak / FinGraph Contributors (MIT License)
5
+ - ์—ญํ• : ์ˆ˜์ง‘๋œ ์ „์ฒด ๋‰ด์Šค ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋‚ด AI ๊ด€๋ จ ์ฃผ์š” ํ‚ค์›Œ๋“œ(๊ธฐ์—…/๊ธฐ์ˆ /์„œ๋น„์Šค)์˜ ์ถœํ˜„ ๋นˆ๋„๋ฅผ ๋ถ„์„ํ•˜์—ฌ
6
+ ์ขŒ์ธก ๋Œ€์‹œ๋ณด๋“œ ํ™”๋ฉด์— ์ ์žฌํ•  ๊ณ ํ’ˆ์งˆ ๋ง‰๋Œ€๊ทธ๋ž˜ํ”„ ์ด๋ฏธ์ง€(keyword_frequencies.png)๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
7
+ """
8
  import os
9
+
10
  import dotenv
11
+ import matplotlib.pyplot as plt
12
  import neo4j
13
  import pandas as pd
 
 
14
 
15
  dotenv.load_dotenv()
16
 
17
+
18
  # Windows ํ™˜๊ฒฝ ํ•œ๊ธ€ ํฐํŠธ ์„ค์ •
19
  plt.rc('font', family='Malgun Gothic')
20
  plt.rcParams['axes.unicode_minus'] = False
21
 
22
+
23
+ def get_neo4j_driver() -> neo4j.Driver:
24
+ uri = os.getenv("NEO4J_URI", "neo4j://localhost:7687")
25
+ client_id = os.getenv("NEO4J_CLIENT_ID")
26
+ client_secret = os.getenv("NEO4J_CLIENT_SECRET")
27
+
28
+ if client_id and client_secret:
29
+ try:
30
+ d = neo4j.GraphDatabase.driver(uri, auth=(client_id, client_secret))
31
+ d.verify_connectivity()
32
+ return d
33
+ except Exception:
34
+ pass
35
+
36
+ username = os.getenv("NEO4J_USERNAME", "neo4j")
37
+ password = os.getenv("NEO4J_PASSWORD", "password")
38
+ d = neo4j.GraphDatabase.driver(uri, auth=(username, password))
39
+ d.verify_connectivity()
40
+ return d
41
+
42
+
43
  def create_keyword_plot():
44
+ driver = get_neo4j_driver()
 
 
 
45
 
46
  query = """
47
  MATCH (a:Article)-[:MENTIONS]->(n)
 
74
  # ๋ง‰๋Œ€ ์˜†์— ์ˆ˜์น˜ ํ…์ŠคํŠธ ํ‘œ์‹œ
75
  for bar in bars:
76
  width = bar.get_width()
77
+ plt.text(width + 0.1, bar.get_y() + bar.get_height() / 2, f'{int(width)}',
78
  ha='left', va='center', fontsize=10)
79
 
80
  plt.tight_layout()
 
82
  plt.savefig(output_path, dpi=300, bbox_inches='tight')
83
  print(f"Graph successfully saved to {output_path}")
84
 
85
+
86
  if __name__ == "__main__":
87
  create_keyword_plot()
stitch_screen.html DELETED
File without changes