Repository navigation
Expand file tree
/
Copy pathcontent.json
More file actions
2263 lines (2263 loc) · 110 KB
/
Copy pathcontent.json
File metadata and controls
2263 lines (2263 loc) · 110 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{
"meta": {
"updated_at": "2026-10-11",
"default_locale": "ko",
"locales": [
"ko",
"ja",
"en"
],
"site_title": {
"ko": "김승환 | 소프트웨어 개발자 · 백엔드",
"ja": "キム・スンファン | ソフトウェア開発者・バックエンド",
"en": "Seunghwan Kim | Software Engineer · Backend"
},
"description": {
"ko": "Java · Spring 백엔드 개발과 AWS 서비스 운영 경험을 프로젝트별 역할과 결과로 정리한 포트폴리오.",
"ja": "Java・Springバックエンド開発とAWSサービス運用の経験を、プロジェクトごとの役割と成果でまとめたポートフォリオ。",
"en": "A portfolio of Java and Spring backend development and AWS service operations, organized by role and result for each project."
},
"sections": {
"live": {
"ko": "서비스 운영 경험",
"ja": "サービス運用経験",
"en": "Service Operations"
},
"experience": {
"ko": "경력",
"ja": "経歴",
"en": "Experience"
},
"projects": {
"ko": "프로젝트",
"ja": "プロジェクト",
"en": "Projects"
},
"awards": {
"ko": "수상 · 선정",
"ja": "受賞・選定",
"en": "Awards & Selections"
},
"activities": {
"ko": "교육 · 활동 · 오픈소스",
"ja": "教育・活動・オープンソース",
"en": "Education, Activities & Open Source"
},
"skills": {
"ko": "기술 스택",
"ja": "技術スタック",
"en": "Technical Skills"
},
"education": {
"ko": "학력 · 자격",
"ja": "学歴・資格",
"en": "Education & Credentials"
},
"contact": {
"ko": "연락",
"ja": "連絡先",
"en": "Contact"
},
"repositories": {
"ko": "대표 저장소",
"ja": "主なリポジトリ",
"en": "Selected Repositories"
}
},
"category_labels": {
"all": {
"ko": "전체",
"ja": "すべて",
"en": "All"
},
"cloud": {
"ko": "클라우드 · 인프라",
"ja": "クラウド・インフラ",
"en": "Cloud & Infrastructure"
},
"embedded": {
"ko": "임베디드 · 온디바이스",
"ja": "組み込み・オンデバイス",
"en": "Embedded & On-device"
},
"backend": {
"ko": "백엔드 · 분산시스템",
"ja": "バックエンド・分散システム",
"en": "Backend & Distributed"
},
"ai-data": {
"ko": "AI · 데이터",
"ja": "AI・データ",
"en": "AI & Data"
}
},
"ui": {
"view_live": {
"ko": "운영 이력 보기",
"ja": "運用実績を見る",
"en": "View operating history"
},
"view_code": {
"ko": "코드 보기",
"ja": "コードを見る",
"en": "View code"
},
"view_demo": {
"ko": "시연 보기",
"ja": "デモを見る",
"en": "View demo"
},
"details": {
"ko": "상세 보기",
"ja": "詳細を見る",
"en": "View details"
},
"present": {
"ko": "현재",
"ja": "現在",
"en": "Present"
},
"live": {
"ko": "운영 일시 중단",
"ja": "運用を一時停止中",
"en": "Operations paused"
},
"fork": {
"ko": "포크 저장소",
"ja": "フォークリポジトリ",
"en": "Fork"
},
"original": {
"ko": "원본 저장소",
"ja": "オリジナルリポジトリ",
"en": "Original repository"
},
"close": {
"ko": "닫기",
"ja": "閉じる",
"en": "Close"
}
}
},
"profile": {
"name": {
"ko": "김승환",
"ja": "キム・スンファン",
"en": "Seunghwan Kim"
},
"romanized_name": "KIM, SEUNGHWAN",
"title": {
"ko": "소프트웨어 개발자 · 백엔드",
"ja": "ソフトウェア開発者・バックエンド",
"en": "Software Engineer · Backend"
},
"headline": {
"ko": "설계부터 운영까지 직접 책임지는 Java · Spring 개발자",
"ja": "設計から運用まで自ら責任を持つJava・Spring開発者",
"en": "A Java and Spring developer who owns services from design to operation"
},
"summary": {
"ko": "Java와 Spring Boot로 KISTI 업무시스템을 DB 설계부터 화면 연동까지 개발했고, 행사용 AI 서비스 MICEMore의 백엔드와 AWS 인프라를 혼자 맡아 2026년 10월 10일 포항 빵 축제까지 운영했습니다. MICEMore는 행사 종료 후 현재 운영을 일시 중단한 상태입니다. 고객 테스트 이슈 200건 이상을 처리하며 요구사항을 코드로 옮기는 법을 익혔고, 장애는 원인까지 추적해 다시 생기지 않는 구조로 고칩니다.",
"ja": "JavaとSpring BootでKISTIの業務システムをDB設計から画面連携まで開発し、イベント向けAIサービスMICEMoreのバックエンドとAWSインフラを一人で担当して、2026年10月10日の浦項パン祭りまで運用しました。MICEMoreはイベント終了後、現在運用を一時停止しています。顧客テストの課題200件以上に対応しながら要件をコードに落とし込む方法を身につけ、障害は原因まで追跡して再発しない構造に直します。",
"en": "I built a KISTI business system in Java and Spring Boot from database design to UI integration, and solely managed the backend and AWS infrastructure of MICEMore through the Pohang bread festival on October 10, 2026. MICEMore operations are currently paused following the event. Resolving more than 200 customer test issues taught me to turn requirements into code, and I trace failures to their cause and fix the structure so they do not recur."
},
"location": {
"ko": "대한민국 대전",
"ja": "韓国・大田",
"en": "Daejeon, South Korea"
},
"education_summary": {
"ko": "한동대학교 전자공학 · 컴퓨터공학 전공, 2026.02 졸업",
"ja": "韓東大学校 電子工学・コンピュータ工学専攻、2026年2月卒業",
"en": "B.S. studies in Electrical Engineering and Computer Science, Handong Global University, graduated February 2026"
}
},
"live_service": {
"id": "micemore",
"name": "MICEMore",
"status": {
"ko": "2026.10.10 행사 운영 · 현재 일시 중단",
"ja": "2026.10.10 イベント運用・現在一時停止中",
"en": "Operated at the Oct 10, 2026 event · Currently paused"
},
"tagline": {
"ko": "AI 기반 MICE 통합 인터랙션 서비스",
"ja": "AIベースのMICE統合インタラクションサービス",
"en": "AI-powered integrated interaction service for MICE events"
},
"role": {
"ko": "개발 팀장 · 개발 인력 1명",
"ja": "開発リーダー・開発担当1名",
"en": "Development Lead · Sole Developer"
},
"summary": {
"ko": "백엔드 전량과 AWS 인프라·배포를 단독 담당하고, 2026년 10월 10일 포항 빵 축제 현장에서 서비스를 운영했습니다. 행사 종료 후 운영 비용을 줄이기 위해 운영 환경을 정리했으며, 현재 서비스는 일시 중단한 상태입니다.",
"ja": "バックエンド全体とAWSインフラ・デプロイを単独で担当し、2026年10月10日の浦項パン祭りでサービスを運用しました。イベント終了後は運用コスト削減のため運用環境を撤去し、現在サービスを一時停止しています。",
"en": "Solely managed the complete backend, AWS infrastructure, and deployment, operating the service at the Pohang bread festival on October 10, 2026. After the event, I decommissioned the hosting infrastructure to reduce costs; the service is currently paused."
},
"evidence": [
{
"ko": "Terraform으로 인프라를 코드로 관리",
"ja": "Terraformでインフラをコードとして管理",
"en": "Infrastructure managed as code with Terraform"
},
{
"ko": "GitHub Actions에서 빌드·테스트 검증 후 배포",
"ja": "GitHub Actionsでビルド・テストを検証後にデプロイ",
"en": "Deployment through GitHub Actions after build and test validation"
},
{
"ko": "AWS 서울 리전에서 구축·배포하고 2026.10.10 포항 빵 축제 현장 운영에 적용",
"ja": "AWSソウルリージョンで構築・デプロイし、2026.10.10の浦項パン祭りで現場運用",
"en": "Built and deployed in the AWS Seoul Region, then used at the Pohang bread festival on October 10, 2026"
},
{
"ko": "장애 감지 시 AI가 원인 분석 초안을 작성하고, 사람이 검토해 PR로 반영. 자동 배포는 하지 않음",
"ja": "障害検知時はAIが原因分析のドラフトを作成し、人がレビューしてPRに反映。自動デプロイは行わない",
"en": "On incident detection an AI drafts the root-cause analysis; a person reviews it and applies it through a pull request. Nothing deploys automatically"
}
],
"technologies": [
"AWS",
"Terraform",
"GitHub Actions"
],
"architecture": {
"title": {
"ko": "행사 운영 당시 구성 보기",
"ja": "イベント運用時の構成を見る",
"en": "View the setup used during the event"
},
"caption": {
"ko": "공개용으로 일반화한 구성도입니다. 서브넷 구조, 탐지·알림 스택, 내부 식별자와 운영 자동화 경로는 포함하지 않습니다.",
"ja": "公開用に一般化した構成図です。サブネット構成、検知・通知スタック、内部識別子、運用自動化の経路は含みません。",
"en": "A generalized diagram prepared for publication. Subnet layout, the detection and alerting stack, internal identifiers, and automation paths are excluded."
},
"labels": {
"users": {
"ko": "이용자",
"ja": "利用者",
"en": "Users"
},
"app": {
"ko": "애플리케이션",
"ja": "アプリケーション",
"en": "Application"
},
"database": {
"ko": "데이터베이스",
"ja": "データベース",
"en": "Database"
},
"region": {
"ko": "AWS 서울 리전",
"ja": "AWSソウルリージョン",
"en": "AWS Seoul Region"
},
"zone_a": {
"ko": "가용영역 A",
"ja": "アベイラビリティゾーン A",
"en": "Availability Zone A"
},
"zone_b": {
"ko": "가용영역 B",
"ja": "アベイラビリティゾーン B",
"en": "Availability Zone B"
},
"balancer": {
"ko": "로드 밸런서",
"ja": "ロードバランサー",
"en": "Load balancer"
},
"pipeline": {
"ko": "빌드 · 테스트 검증",
"ja": "ビルド・テスト検証",
"en": "Build and test validation"
},
"provision": {
"ko": "인프라 프로비저닝",
"ja": "インフラのプロビジョニング",
"en": "Infrastructure provisioning"
}
}
}
},
"stats": [
{
"value": "261,934 → 246,980",
"label": {
"ko": "논문 수집 → 정제",
"ja": "論文収集 → 精製",
"en": "Papers collected → curated"
}
},
{
"value": "200+",
"label": {
"ko": "고객 테스트 이슈 처리",
"ja": "顧客テスト課題を対応",
"en": "Customer test issues resolved"
}
},
{
"value": "70",
"label": {
"ko": "GitHub 공개 저장소",
"ja": "GitHub公開リポジトリ",
"en": "Public GitHub repositories"
},
"source": "GitHub API"
}
],
"experience": [
{
"id": "micemore",
"period": {
"start": "2026-05",
"end": null,
"display": {
"ko": "2026.05 ~ 현재",
"ja": "2026.05〜現在",
"en": "May 2026 – Present"
}
},
"organization": {
"ko": "마이스모어 (MICEMore)",
"ja": "MICEMore(マイスモア)",
"en": "MICEMore"
},
"role": {
"ko": "창업팀 개발 팀장",
"ja": "創業チーム 開発リーダー",
"en": "Development Lead, Founding Team"
},
"summary": {
"ko": "백엔드 전량과 AWS 인프라·배포를 단독 담당. 2026.10.10 포항 빵 축제 현장 운영 후, 현재 서비스는 일시 중단.",
"ja": "バックエンド全体とAWSインフラ・デプロイを単独で担当。2026.10.10の浦項パン祭りで運用後、現在サービスは一時停止中。",
"en": "Solely managed the complete backend, AWS infrastructure, and deployment. Operated at the Pohang bread festival on October 10, 2026; the service is currently paused."
},
"links": []
},
{
"id": "pseudo-lab",
"period": {
"start": "2026-02",
"end": "2026-08",
"display": {
"ko": "2026.02 ~ 2026.08",
"ja": "2026.02〜2026.08",
"en": "February – August 2026"
}
},
"organization": {
"ko": "가짜연구소 (Pseudo Lab)",
"ja": "Pseudo Lab",
"en": "Pseudo Lab"
},
"role": {
"ko": "LLM for Science 오픈소스 연구",
"ja": "LLM for Science オープンソース研究",
"en": "LLM for Science Open-source Research"
},
"summary": {
"ko": "Semantic Scholar 논문 261,934건을 수집하고 3단계 검증을 거쳐 246,980건으로 정제.",
"ja": "Semantic Scholarの論文261,934件を収集し、3段階の検証を経て246,980件に精製。",
"en": "Collected 261,934 Semantic Scholar papers and curated them to 246,980 through a three-stage validation pipeline."
}
},
{
"id": "pusan-national-university",
"period": {
"start": "2026-01",
"end": "2026-02",
"display": {
"ko": "2026.01 ~ 2026.02",
"ja": "2026.01〜2026.02",
"en": "January 2026 – February 2026"
}
},
"organization": {
"ko": "부산대학교 정보화혁신본부",
"ja": "釜山大学校 情報化革新本部",
"en": "Pusan National University, Office of Information Innovation"
},
"role": {
"ko": "계약직 · 대학회계",
"ja": "契約職員・大学会計",
"en": "Contract Staff"
},
"summary": {
"ko": "학사 시스템 데이터 품질 개선, 산지니 AI 활용도 분석과 개선안 도출, AI 공모전 운영, 외부 솔루션 도입 검토.",
"ja": "学事システムのデータ品質改善、Sanjini AIの利用分析と改善案策定、AIコンテスト運営、外部ソリューション導入検討。",
"en": "Improved academic-system data quality, analyzed usage of the Sanjini AI service, proposed improvements, operated an AI contest, and evaluated external solutions."
}
},
{
"id": "hubiz-ict",
"period": {
"start": "2025-10",
"end": "2025-12",
"display": {
"ko": "2025.10 ~ 2025.12",
"ja": "2025.10〜2025.12",
"en": "October 2025 – December 2025"
}
},
"organization": {
"ko": "휴비즈아이씨티",
"ja": "Hubiz ICT",
"en": "Hubiz ICT"
},
"role": {
"ko": "풀스택 개발자 인턴",
"ja": "フルスタック開発インターン",
"en": "Full-stack Developer Intern"
},
"summary": {
"ko": "KISTI smartK2C 차세대 업무시스템 신규 개발. DB 설계부터 화면 연동까지 End-to-End 구현하고 고객 테스트 이슈 200건 이상 처리.",
"ja": "KISTI smartK2C次世代業務システムを新規開発。DB設計から画面連携までEnd-to-Endで実装し、顧客テスト課題200件以上に対応。",
"en": "Developed the next-generation KISTI smartK2C business system end to end, from database design to UI integration, and resolved more than 200 customer test issues."
}
},
{
"id": "likelion",
"period": {
"start": "2024-01",
"end": "2025-08",
"display": {
"ko": "2024.01 ~ 2025.08",
"ja": "2024.01〜2025.08",
"en": "January 2024 – August 2025"
}
},
"organization": {
"ko": "멋쟁이사자처럼 대학",
"ja": "LIKELION University",
"en": "LIKELION University"
},
"role": {
"ko": "13기 운영진 · 백엔드 멘토",
"ja": "第13期運営・バックエンドメンター",
"en": "13th Cohort Organizer & Backend Mentor"
},
"summary": {
"ko": "신입 기수 백엔드 교육과 해커톤 준비 지원.",
"ja": "新規メンバー向けバックエンド教育とハッカソン準備を支援。",
"en": "Taught backend development to new members and supported hackathon preparation."
}
}
],
"featured_projects": [
{
"id": "unibloom",
"categories": ["backend", "cloud"],
"name": {
"ko": "Unibloom — AI 기반 멀티클라우드 배포 시스템",
"ja": "Unibloom — AIによるマルチクラウドデプロイシステム",
"en": "Unibloom — AI-assisted Multicloud Deployment"
},
"period": {
"start": "2026-09",
"end": null,
"display": {
"ko": "2026.09 ~ 현재 · SoftBank 해커톤 2026",
"ja": "2026.09〜現在・SoftBank ハッカソン 2026",
"en": "September 2026 – Present · SoftBank Hackathon 2026"
}
},
"role": {
"ko": "6인 팀 · 백엔드 2인 중 배포 실행 제어·정합성 담당, 이후 서버 통합 검증",
"ja": "6名チーム・バックエンド2名のうちデプロイ制御と整合性を担当、その後サーバー統合検証",
"en": "6-person team · Deployment control and consistency within a two-person backend team; later server integration verification"
},
"summary": {
"ko": "SoftBank 해커톤 2026에서 개발한 팀 프로젝트입니다. 온프레미스·퍼블릭 클라우드 배포를 위한 승인·멱등성·state 락·응답 유실 복구를 구현하고, 웹·앱·인프라 사이 실행 계약을 정리했습니다.",
"ja": "SoftBank ハッカソン 2026で開発したチームプロジェクト。オンプレミスとパブリッククラウドへのデプロイに向け、承認・冪等性・stateロック・応答喪失時の復旧を実装し、Web・アプリ・インフラ間の実行契約を整理。",
"en": "A team project built for SoftBank Hackathon 2026. Implemented approvals, idempotency, state locks, and recovery from lost responses, and aligned execution contracts across web, native app, and infrastructure teams."
},
"highlights": [
{
"ko": "프로젝트: GitHub 저장소의 앱을 AI로 환경별 Terraform으로 구성하고, 사용자가 계획을 승인한 뒤 Jenkins가 배포하는 시스템입니다. 웹·네이티브 앱에서 같은 흐름을 제공합니다.",
"ja": "プロジェクト:GitHub上のアプリ向けにAIが環境別Terraformを生成し、人が計画を承認してからJenkinsがデプロイするシステム。Webとネイティブアプリで同じフローを提供。",
"en": "The product generates environment-specific Terraform for apps in GitHub repositories, then deploys through Jenkins after human plan approval. Web and native clients share the flow."
},
{
"ko": "팀 성과: 온프레미스 Docker·AWS ECS Fargate·GCP Cloud Run·Azure Container Apps의 4개 환경에서 동일 버전 배포와 헬스체크를 확인했습니다. 네 환경 재사용 배포에서 AI 호출 0회도 기록했습니다(#89 인프라 검증 기록).",
"ja": "チーム成果:オンプレミスDocker・AWS ECS Fargate・GCP Cloud Run・Azure Container Appsの4環境で同一バージョンとヘルスチェックを確認。再利用デプロイではAI呼び出し0回を記録(#89のインフラ検証記録)。",
"en": "Team outcome: the same version and successful health checks across on-prem Docker, AWS ECS Fargate, GCP Cloud Run, and Azure Container Apps; a reuse run recorded zero AI calls across all four environments (infrastructure evidence in #89)."
},
{
"ko": "개인 기여: ERD·도메인 설계, 배포 접수·승인·취소·재시도·롤백 규칙, Jenkins 명령·콜백, 멱등성·락·복구, 이벤트 저장·SSE 기반을 맡았습니다. 이후 동료의 API와 통합해 현재 배포·결과 조회와 Swagger 계약도 보완했습니다.",
"ja": "担当:ERD・ドメイン設計、デプロイ受付・承認・取消・再試行・ロールバック規則、Jenkins命令・コールバック、冪等性・ロック・復旧、イベント保存・SSE基盤。同僚のAPIとの統合後、現在のデプロイ・結果照会とSwagger契約も補完。",
"en": "My work: ERD and domain design; intake, approval, cancellation, retry, and rollback rules; Jenkins commands and callbacks; idempotency, locking, recovery, event storage, and SSE. Later integrated my colleague’s APIs and completed current-deployment/result projections and Swagger contracts."
},
{
"ko": "담당 경계: AI·Terraform 생성·검증·실행과 클라우드 구축은 인프라팀, 초기 인증·인가·관리·공개 API는 백엔드 동료가 담당했습니다. 서버는 Terraform을 직접 실행하지 않고 사용자 승인과 실행 결과의 연결을 관리합니다.",
"ja": "担当境界:AI・Terraformの生成・検証・実行とクラウド構築はインフラチーム、初期の認証・認可・管理・公開APIはバックエンドの同僚が担当。サーバーはTerraformを直接実行せず、ユーザー承認と実行結果を関連付けます。",
"en": "Ownership: infrastructure teammates built the cloud environments and AI/Terraform generation, validation, and execution; my backend colleague built the initial auth, management, and public APIs. The server controls the approval-to-execution relationship rather than running Terraform itself."
}
],
"sections": [
{
"title": {
"ko": "01. 협업 문제 해결 — 병렬 개발 중 달라진 계약과 역할 맞추기",
"ja": "01. 協業の課題 — 並行開発で変化する契約と担当の調整",
"en": "01. Collaboration — aligning contracts and ownership during parallel development"
},
"items": [
{
"ko": "문제: 웹·앱·인프라 개발이 ERD·API 합의보다 먼저 병렬로 진행됐고, CI/CD가 Jenkins로 바뀌면서 서버에서 계획했던 AI·실행 기능과 인프라 구현이 겹쳤습니다. 기존에는 백엔드가 인프라까지 맡았던 경험이 많아, 별도 인프라팀과의 경계를 다시 정하는 데 초기 이틀가량이 소요됐습니다.",
"ja": "課題:ERD・APIの合意前にWeb・アプリ・インフラが並行して開発を進め、CI/CDがJenkinsへ変わるとサーバー側で想定したAI・実行機能と重複しました。従来はバックエンドがインフラも担う経験が多く、専任チームとの境界整理に初期約2日を要しました。",
"en": "Problem: web, app, and infrastructure work progressed before the ERD and API agreements settled. Switching CI/CD to Jenkins created overlap with planned server-side AI and execution work. Having previously handled infrastructure within backend teams, we spent roughly two initial days clarifying the new boundaries."
},
{
"ko": "행동: 익숙하지 않은 Jenkins를 추측해서 연결하지 않고 인프라팀과 미팅해 Job 파라미터, queue→build 전환, 승인 위치와 결과 수신 방식을 함께 확인했습니다. PR·명세의 요청을 ERD와 계약에 반영하고, 미제공 항목은 따로 구분했습니다. 서버–인프라 협의는 #35로 모아 실행 식별자·plan·콜백·state·취소 조건을 추적했습니다.",
"ja": "対応:不慣れなJenkinsを推測で接続せず、インフラチームとのミーティングでJobパラメーター、queueからbuildへの遷移、承認位置、結果受信を確認。PR・仕様の要求をERDと契約へ反映し、未提供項目を区別。#35に実行ID・plan・コールバック・state・取消条件を集約しました。",
"en": "Action: met with infrastructure teammates to understand Jenkins Job parameters, queue-to-build transitions, approval ownership, and result delivery instead of guessing. Incorporated PR/spec requests into the ERD and contracts, explicitly separated unsupported fields, and tracked execution IDs, plans, callbacks, state, and cancellation in issue #35."
},
{
"ko": "합의: 서버는 사용자 의사·상태·승인, Jenkins는 실제 plan/apply 실행을 담당하도록 나눴습니다. 백엔드 내부도 상태를 쓰는 실행 서비스와 관리·조회 API로 분리했습니다. 조회 구현이 실행부를 계속 기다리지 않도록 읽기 전용 SQL 접근을 합의하되, 상태 변경은 실행 서비스로만 통과시켰습니다.",
"ja": "合意:サーバーはユーザーの意思・状態・承認、Jenkinsは実際のplan/applyを担当。バックエンドも状態を書き込む実行サービスと管理・照会APIに分離。照会実装が実行側を待ち続けないよう読み取り専用SQLを認め、状態変更は実行サービスに限定しました。",
"en": "Agreement: the server owns user intent, state, and approval; Jenkins owns actual plan/apply execution. Split backend ownership into execution writes and management/query APIs. Allowed read-only SQL projections to unblock query development while keeping state changes behind execution services."
},
{
"ko": "결과와 배움: 노션은 합의 기록, 서버 OpenAPI는 실제 API 계약의 기준으로 정리하고 웹·앱에 변경을 공유했습니다. 기능별 SPEC을 먼저 작성하고 통합 후 실제 응답까지 대조했습니다. 역할은 '백엔드/인프라'라는 이름보다 데이터 변경 주체·입출력·실패 처리까지 정해야 병렬 개발이 가능하다는 점을 배웠습니다.",
"ja": "結果と学び:Notionを合意記録、サーバーOpenAPIをAPI契約の基準とし、変更をWeb・アプリへ共有。機能別SPECを先に書き、統合後は実際の応答と照合しました。担当名だけでなく、データ更新主体・入出力・失敗処理まで決めることが並行開発の前提だと学びました。",
"en": "Outcome and lesson: kept Notion as the agreement record and server OpenAPI as the API contract, notifying web/app consumers of changes. Wrote feature specifications before implementation and checked actual responses after integration. Parallel development needs explicit write ownership, inputs, outputs, and failure behavior—not just labels such as backend or infrastructure."
}
]
},
{
"title": {"ko": "02. 배포 접수·멱등성 — 같은 요청으로 배포가 두 번 생기지 않도록", "ja": "02. 受付・冪等性 — 同じ要求による二重作成を防ぐ", "en": "02. Intake and idempotency — preventing duplicate deployment creation"},
"items": [
{
"ko": "배포 요청에서 권한과 프로젝트·선택 빌드·대상 관계를 검사하고, 실행 입력과 대상 설정을 스냅샷으로 고정했습니다. 배포 행·Jenkins 명령·이벤트·멱등 응답을 같은 트랜잭션에 저장해, 배포만 생성되고 실행 명령은 빠지는 부분 저장을 막았습니다.",
"ja": "権限とプロジェクト・選択ビルド・対象の関係を検証し、実行入力と対象設定をスナップショット化。デプロイ行・Jenkins命令・イベント・冪等応答を同一トランザクションに保存し、命令だけ欠ける部分保存を防止。",
"en": "Validated authorization and project/build/target relationships, then froze execution inputs and target settings as snapshots. Saved the deployment, Jenkins command, event, and idempotent response in one transaction to prevent partial persistence."
},
{
"ko": "Idempotency-Key를 사용자·프로젝트·작업·리소스 범위로 구분하고 정규화 JSON의 SHA-256으로 요청 내용을 비교했습니다. 같은 키·같은 내용은 기존 응답, 같은 키·다른 내용은 409입니다. 프로젝트 행을 FOR UPDATE로 먼저 잠가 동시 요청이 둘 다 신규 요청으로 처리되는 경쟁을 막았습니다.",
"ja": "Idempotency-Keyをユーザー・プロジェクト・操作・リソースでスコープ化し、正規化JSONのSHA-256で内容を比較。同じキー・同じ内容には保存済み応答、異なる内容には409。先にプロジェクト行をFOR UPDATEでロックし、同時要求の競合を防止。",
"en": "Scoped Idempotency-Key by actor, project, operation, and resource, comparing canonical JSON with SHA-256. Identical requests replay the saved response; changed payloads using the same key return 409. A project-row FOR UPDATE lock prevents concurrent requests from both being treated as new."
},
{
"ko": "PostgreSQL을 택한 이유는 JSONB만이 아닙니다. 배포 이력·명령·락·이벤트·멱등 응답을 같은 DB에서 원자적으로 기록할 수 있어, 초기 규모에서 별도 Redis 큐를 운영하지 않아도 됐습니다. 큐는 전달을 맡고 멱등성은 재요청 처리를 맡도록 구분했습니다.",
"ja": "PostgreSQLの選択理由はJSONBだけではありません。履歴・命令・ロック・イベント・冪等応答を同じDBで原子的に保存でき、初期規模では別のRedisキューを運用せずに済みました。キューの配送責務と冪等性の再要求処理は分離しています。",
"en": "PostgreSQL was not chosen just for JSONB: it lets history, commands, locks, events, and idempotent responses share atomic writes, avoiding a separate Redis queue at the initial scale. Command delivery and request idempotency remain distinct responsibilities."
}
]
},
{
"title": {"ko": "03. DB 작업 큐·복구 — 응답 유실을 실행 실패로 단정하지 않기", "ja": "03. DBキュー・復旧 — 応答喪失を実行失敗と決めつけない", "en": "03. Durable queue and recovery — a lost response is not a failed execution"},
"items": [
{
"ko": "jenkins_execution에 pending 명령을 저장하고 워커가 짧은 트랜잭션에서 선점해 dispatching으로 전환합니다. 명령 행에는 FOR UPDATE SKIP LOCKED를 사용하되 프로젝트·배포 잠금도 함께 적용합니다. Jenkins HTTP 호출은 커밋 이후에 수행해 외부 응답을 기다리는 동안 DB 락을 오래 잡지 않습니다.",
"ja": "jenkins_executionへpending命令を保存し、ワーカーが短いトランザクションで取得してdispatchingへ遷移。命令行のFOR UPDATE SKIP LOCKEDに加えプロジェクト・デプロイもロック。JenkinsへのHTTP呼び出しはコミット後に行い、外部応答待ちでDBロックを保持しません。",
"en": "Persisted pending commands in jenkins_execution; a worker claims them and sets dispatching in a short transaction. The command row uses FOR UPDATE SKIP LOCKED alongside project/deployment locks. Jenkins HTTP calls occur after commit, outside the database transaction."
},
{
"ko": "사용자 멱등 키, 서버 request_id, Jenkins queue_id와 build_number를 구분해 추적했습니다. 요청이 전달됐지만 응답만 사라질 수 있으므로 타임아웃은 unknown으로 기록하고, request_id로 기존 실행을 확인합니다. 서버 재시작 시 남은 dispatching도 unknown으로 전환하며, 검색 결과가 없다는 이유만으로 apply를 재전송하지 않습니다.",
"ja": "ユーザーの冪等キー、サーバーrequest_id、Jenkins queue_id・build_numberを分けて追跡。受付後に応答だけ失う可能性があるため、タイムアウトはunknownとして既存実行を検索。再起動後のdispatchingもunknownへ移し、検索で見つからないだけでapplyを再送しません。",
"en": "Tracked API idempotency keys, server request_id, Jenkins queue_id, and build_number separately. Timeouts become unknown because Jenkins may have accepted the request. Restart recovery also moves interrupted dispatching commands to unknown; an unsuccessful lookup alone never triggers an apply resubmission."
}
]
},
{
"title": {"ko": "04. 승인·state 락 — 확인한 계획과 실제 실행을 연결하기", "ja": "04. 承認・stateロック — 確認した計画と実行を結び付ける", "en": "04. Approval and state locks — binding reviewed plans to execution"},
"items": [
{
"ko": "승인은 배포 전체의 boolean이 아니라 대상별 특정 plan에 연결했습니다. 승인 대기 여부·plan/승인 기한·현재 plan·입력 해시·삭제 확인 문구를 검사하고, 승인 기록·state 락·apply 명령을 한 트랜잭션에 저장합니다. 큐에서 기다리는 동안 조건이 바뀔 수 있어 전송 직전에도 승인과 락 소유권을 재검사합니다.",
"ja": "承認をデプロイ全体のbooleanではなく対象別の特定planに関連付け。待機状態・有効期限・現在plan・入力ハッシュ・削除確認文を検証し、承認・stateロック・apply命令を同一トランザクションに保存。キュー待機中の変化に備え送信直前にも再検証します。",
"en": "Bound approvals to a specific plan per target rather than a deployment-wide boolean. Checked pending state, expiry, current plan, input hash, and destructive-change confirmation, saving approval, state lock, and apply command atomically. Rechecked approval and lock ownership immediately before dispatch."
},
{
"ko": "대상 ID가 달라도 같은 Terraform state를 가리킬 수 있어 실제 state_identity를 락 기준으로 삼았습니다. FOR UPDATE는 짧은 DB 트랜잭션을 보호하고, target_lock 행은 실행 중 소유권을 유지합니다. 충돌 시 409 TARGET_LOCKED로 승인도 롤백하고, 시간 초과만으로 해제하지 않으며 종료 근거가 있는 자기 실행의 락만 풉니다.",
"ja": "異なる対象IDが同じTerraform stateを参照できるため、実際のstate_identityをロック単位に採用。FOR UPDATEは短いDB処理を保護し、target_lock行は実行中の所有権を維持。競合は409で承認ごとロールバックし、時間経過だけでは解放せず終了根拠のある自分の実行分だけを解放します。",
"en": "Used physical state_identity rather than target ID because multiple targets can reference the same Terraform state. FOR UPDATE protects short transactions; target_lock rows retain ownership during execution. Conflicts return 409 and roll back approval. Locks require termination evidence and matching ownership to release—not merely a timeout."
}
]
},
{
"title": {"ko": "05. 콜백·현재 배포 — 중복·역순 결과가 상태를 덮어쓰지 않도록", "ja": "05. コールバック — 重複・逆順の結果による状態の上書きを防ぐ", "en": "05. Callbacks — preventing duplicate or out-of-order state corruption"},
"items": [
{
"ko": "Jenkins 인증과 본문 형식을 확인한 뒤 request·Job·build·대상 연결을 검증합니다. 같은 이벤트 ID·같은 내용은 중복, 같은 ID·다른 내용은 충돌로 처리합니다. 현재 실행 ID와 source_sequence로 오래된 상태를 구분하고, 완료 상태를 늦은 진행 이벤트가 되돌리지 못하게 했습니다. 도착 시각만으로 순서를 판단하지 않습니다.",
"ja": "Jenkins認証と本文形式に続きrequest・Job・build・対象の関連を検証。同じイベントID・同じ内容は重複、異なる内容は競合。現在の実行IDとsource_sequenceで古い状態を判定し、遅延イベントで完了状態が戻らないようにしました。到着時刻だけには依存しません。",
"en": "Validated Jenkins authentication, payload shape, and request/Job/build/target binding. The same event ID and payload is a duplicate; a changed payload is a conflict. Current execution IDs and source_sequence reject stale state updates and prevent completed targets from reverting to running; arrival time is not the ordering mechanism."
},
{
"ko": "Jenkins의 SUCCESS만으로 배포 성공을 확정하지 않고 대상별 plan ID·digest·입력 해시·이미지를 고정 입력과 대조합니다. 유효한 성공 결과를 저장할 때 현재 배포 포인터·연결 확인 시각·락 해제·이벤트도 연결했습니다. 대상 설정이나 락 소유권이 달라졌다면 과거 성공으로 현재 포인터를 덮지 않습니다.",
"ja": "JenkinsのSUCCESSだけでは成功を確定せず、対象別plan ID・digest・入力ハッシュ・イメージを固定入力と照合。有効な成功結果と現在デプロイ参照・接続確認時刻・ロック解放・イベントを連携。設定や所有権が変われば過去の成功で現在参照を上書きしません。",
"en": "A Jenkins SUCCESS alone does not finalize deployment success: per-target plan ID, digest, input hash, and images must match frozen inputs. Connected validated results to current-deployment pointers, connection timestamps, lock release, and events. Changed target settings or lock ownership prevent stale successes from replacing the current pointer."
},
{
"ko": "환경별 결과는 독립적으로 기록하고 전체 상태를 집계합니다. 전부 성공은 succeeded, 일부 성공 후 나머지가 실패·취소되면 partially_succeeded로 구분합니다. 스크립트·AI 호출 기록도 외부 식별자로 중복을 검사하고, 확인하지 못한 토큰·비용은 0으로 꾸미지 않고 NULL로 남겼습니다.",
"ja": "環境別結果を独立して記録し全体状態を集計。全成功はsucceeded、一部成功で他が失敗・取消ならpartially_succeeded。スクリプト・AI呼び出し記録も外部IDで重複検証し、不明なトークン・費用を0にせずNULLで保持します。",
"en": "Recorded targets independently and aggregated overall state: succeeded when all succeed, partially_succeeded when some succeed and the rest fail or cancel. Deduplicated script and AI-call records by external identity, preserving unknown tokens and costs as NULL rather than inventing zeros."
}
]
},
{
"title": {"ko": "06. SSE·취소·재시도·롤백 — 이름보다 동작을 명확히 하기", "ja": "06. SSE・取消・再試行・ロールバック — 動作の意味を明確にする", "en": "06. SSE, cancellation, retry, and rollback — making semantics explicit"},
"items": [
{
"ko": "업무 상태와 이벤트를 같은 트랜잭션에 저장하고 Spring MVC SseEmitter가 DB 이벤트를 웹·앱으로 전달합니다. 채널별 seq를 SSE id로 사용해 Last-Event-ID 이후를 재생합니다. 기본 1초 DB 조회와 15초 heartbeat를 구분하고, 재생 범위를 벗어나면 resync로 스냅샷 재조회를 안내합니다. heartbeat는 Jenkins·클라우드의 정상 동작 증명이 아닙니다.",
"ja": "業務状態とイベントを同一トランザクションで保存し、Spring MVC SseEmitterでWeb・アプリへ配信。チャネル別seqをSSE idにしLast-Event-ID以降を再生。1秒のDB照会と15秒のheartbeatを分け、範囲外はresyncで再同期を案内。heartbeatはJenkins・クラウドの健全性証明ではありません。",
"en": "Persisted state and events in one transaction and streamed stored events through Spring MVC SseEmitter. Channel-local seq becomes the SSE id for Last-Event-ID replay. Separated one-second DB polling from 15-second heartbeats, with resync for unavailable replay ranges. Heartbeats do not prove Jenkins or cloud health."
},
{
"ko": "취소는 실행 시점을 구분합니다. 제출 전 대기 명령은 조건을 확인해 취소하지만, 이미 제출됐거나 접수 여부가 불명확한 apply는 취소 의사만 기록하고 강제 중단·자동 롤백하지 않습니다. 202 응답은 요청 접수이지 인프라 원복 완료라는 뜻이 아닙니다.",
"ja": "取消は実行段階で区別。未送信の待機命令は条件確認後に取消しますが、送信済み・受付不明のapplyは意思だけを記録し、強制停止・自動ロールバックは行いません。202は受付であり、インフラ復元完了ではありません。",
"en": "Cancellation depends on execution stage. Eligible pending commands can be cancelled before submission; submitted or uncertain apply executions only record cancellation intent, without forced termination or automatic rollback. A 202 response means accepted, not infrastructure restored."
},
{
"ko": "실패 대상 재시도와 이전 성공 버전 롤백은 원래 이력을 고치지 않고 새 배포로 생성합니다. 롤백도 plan·승인을 거치며 DB 데이터 복구와 구분합니다. 단순 stale 재-plan은 새 승인을 요구하되 AI 생성·수정의 총 3회 예산인 attempt를 소비하지 않습니다.",
"ja": "失敗対象の再試行と過去の成功バージョンへのロールバックは、元の履歴を書き換えず新規デプロイとして作成。ロールバックもplan・承認を経てDBデータ復元とは区別。単純なstale再planは再承認を求めますが、AI生成・修正の計3回のattemptは消費しません。",
"en": "Retries of failed targets and rollbacks to a previous successful version create new deployments with lineage, preserving history. Rollbacks still require plan and approval and do not restore database data. A simple stale re-plan requires new approval without consuming the three-attempt AI generation/fix budget."
}
]
},
{
"title": {"ko": "07. 검증·기술적 한계 — 실제로 확인한 범위만 설명하기", "ja": "07. 検証・限界 — 実際に確認した範囲を示す", "en": "07. Verification and limits — stating what was actually demonstrated"},
"items": [
{
"ko": "코드 구조는 DDD 방식으로 기능별 domain·application·infrastructure를 나눴습니다. 도메인은 승인·상태 전이 규칙, application은 유스케이스·트랜잭션, infrastructure는 저장을 맡습니다. 큐·락·이벤트 순번은 JPA만 고집하지 않고 JDBC와 명시적 SQL로 구현했습니다.",
"ja": "DDDの考え方で機能別にdomain・application・infrastructureを分離。ドメインは承認・状態遷移、applicationはユースケースとトランザクション、infrastructureは永続化を担当。キュー・ロック・イベント採番はJPAだけに拘らずJDBCと明示的SQLで実装。",
"en": "Applied DDD-style domain/application/infrastructure boundaries per feature: domain rules for approval and transitions, application orchestration and transactions, and persistence implementations. Used explicit JDBC/SQL for queues, locks, and event sequencing rather than forcing everything through JPA."
},
{
"ko": "리뷰 사례: CI 빌드 2건의 동시 수신에서 source_version FK 검사의 project KEY SHARE와 이벤트 저장의 FOR UPDATE가 충돌하는 교착을 실DB로 재현했습니다. project → source_version → event 순서로 잠그도록 제안하고, 동료가 반영한 수정과 동시 수신 회귀 테스트를 재검증했습니다(#72).",
"ja": "レビュー事例:CIビルド2件の同時受信で、source_versionのFK検査によるproject KEY SHAREとイベント保存のFOR UPDATEが競合するデッドロックを実DBで再現。project → source_version → eventの順を提案し、同僚の修正と並行受信回帰テストを再検証(#72)。",
"en": "Review case: reproduced a real PostgreSQL deadlock between source_version FK checks holding project KEY SHARE and event writes requesting FOR UPDATE during two concurrent build reports. Proposed project → source_version → event lock ordering, then reverified my teammate’s fix and concurrency regression test (#72)."
},
{
"ko": "검증 기록: #85 시점에 PostgreSQL을 포함한 241개 테스트가 실패·건너뜀 없이 통과했습니다. 공개 22개·내부 2개 HTTP 경로와 OpenAPI 실제 응답을 대조했습니다. 이 서버 검증의 Jenkins 경계는 명시적 MOCK이며, 실제 4환경 배포 성공은 별도의 인프라팀 #89 기록입니다. 두 검증을 혼동하지 않았습니다.",
"ja": "検証記録:#85時点でPostgreSQLを含む241テストが失敗・スキップなしで成功。公開22・内部2のHTTP経路とOpenAPI・実応答を照合。このサーバー検証のJenkins境界は明示的MOCKで、実際の4環境デプロイは別途インフラチームの#89記録です。",
"en": "Evidence at #85: 241 tests including PostgreSQL passed with no failures or skips; checked 22 public and two internal HTTP routes against OpenAPI and actual responses. Jenkins boundaries were explicit MOCKs in that server verification. Actual four-environment deployment evidence is separately recorded by the infrastructure team in #89."
},
{
"ko": "한계: 외부 실행을 exactly-once로 보장한다고 주장하지 않습니다. 확인 불가능한 실행은 진행보다 중복 방지를 우선해 보류할 수 있습니다. 워커 복구는 단일 백엔드 전제이고, 다중 인스턴스 소유권 조정·SSE 폴링 확장·apply 강제 중단은 후속 과제입니다. 임의 저장소 연결만으로 모든 앱이 자동 배포되는 범용 서비스까지 구현한 것은 아닙니다.",
"ja": "限界:外部実行のexactly-onceは保証しません。不明な実行は進行より重複防止を優先して保留します。復旧は単一バックエンド前提で、複数インスタンスの所有権調整・SSEポーリングの拡張・apply強制停止は今後の課題。任意リポジトリの接続だけで全アプリを自動デプロイする汎用サービスではありません。",
"en": "Limits: no claim of exactly-once external execution; uncertain work may pause to avoid duplicates. Recovery assumes one backend instance. Multi-instance ownership, scaling SSE polling, and forced apply termination remain future work. This is not yet a universal service that deploys any arbitrary app merely by connecting its repository."
}
]
}
],
"technologies": ["Java 21", "Spring Boot 3.5", "PostgreSQL 17", "JPA", "JDBC", "Flyway", "Jenkins REST API", "SSE", "springdoc-openapi", "Gradle"],
"links": [
{"label": {"ko": "팀 저장소", "ja": "チームリポジトリ", "en": "Team repository"}, "url": "https://github.com/Softbank-Hackathon-2026-Team-Daisy/unibloom"},
{"label": {"ko": "배포 실행 구현 #40", "ja": "実行サービス実装 #40", "en": "Execution implementation #40"}, "url": "https://github.com/Softbank-Hackathon-2026-Team-Daisy/unibloom/pull/40"},
{"label": {"ko": "연동 계약 협의 #35", "ja": "連携契約の協議 #35", "en": "Integration agreement #35"}, "url": "https://github.com/Softbank-Hackathon-2026-Team-Daisy/unibloom/issues/35"},
{"label": {"ko": "교착 재현·리뷰 #72", "ja": "デッドロック再現・レビュー #72", "en": "Deadlock reproduction and review #72"}, "url": "https://github.com/Softbank-Hackathon-2026-Team-Daisy/unibloom/pull/72#pullrequestreview-5388676107"},
{"label": {"ko": "서버 통합 검증 #85", "ja": "サーバー統合検証 #85", "en": "Server integration verification #85"}, "url": "https://github.com/Softbank-Hackathon-2026-Team-Daisy/unibloom/pull/85"},
{"label": {"ko": "4환경 배포 기록 #89", "ja": "4環境デプロイ記録 #89", "en": "Four-environment deployment evidence #89"}, "url": "https://github.com/Softbank-Hackathon-2026-Team-Daisy/unibloom/issues/89"}
]
},
{
"id": "micemore",
"categories": [
"cloud",
"backend"
],
"name": {
"ko": "MICEMore — AI 기반 MICE 통합 인터랙션 서비스",
"ja": "MICEMore — AIベースのMICE統合インタラクションサービス",
"en": "MICEMore — AI-powered MICE Interaction Service"
},
"period": {
"start": "2026-05",
"end": null,
"display": {
"ko": "2026.05 ~ 현재",
"ja": "2026.05〜現在",
"en": "May 2026 – Present"
}
},
"role": {
"ko": "개발 팀장 · 개발 인력 1명",
"ja": "開発リーダー・開発担当1名",
"en": "Development Lead · Sole Developer"
},
"summary": {
"ko": "백엔드 전량과 AWS 인프라·배포를 단독 담당. 2026.10.10 포항 빵 축제 현장 운영 후, 현재 서비스는 일시 중단.",
"ja": "バックエンド全体とAWSインフラ・デプロイを単独で担当。2026.10.10の浦項パン祭りで運用後、現在サービスは一時停止中。",
"en": "Solely managed the complete backend, AWS infrastructure, and deployment. Operated at the Pohang bread festival on October 10, 2026; the service is currently paused."
},
"highlights": [
{
"ko": "Terraform으로 인프라를 코드로 관리하고, GitHub Actions에서 빌드·테스트 검증을 통과한 것만 두 개의 가용영역에 배포",
"ja": "Terraformでインフラをコードとして管理し、GitHub Actionsの検証を通過したものだけを2つのアベイラビリティゾーンへデプロイ",
"en": "Infrastructure as code with Terraform, deploying only what passes GitHub Actions validation across two availability zones"
},
{
"ko": "NFC 태깅 응답 경로를 AI 처리와 분리해, AI가 느려져도 태깅 자체는 지연되지 않도록 설계",
"ja": "NFCタギングの応答経路をAI処理から分離し、AIが遅延してもタギング自体は遅れない設計に",
"en": "Separated the NFC tap response path from AI processing so a slow model never delays the tap itself"
},
{
"ko": "AI 도슨트가 모델이 생성한 문장을 그대로 내보내지 않는 구조로 설계해 환각을 차단",
"ja": "AIドーセントがモデルの生成文をそのまま出さない構造にし、ハルシネーションを遮断",
"en": "Designed the AI docent so no model-written sentence reaches a visitor, removing hallucination as a failure mode"
},
{
"ko": "대화 상태를 저장하지 않는 설계로 다수 동시 응대를 수평 확장만으로 처리",
"ja": "対話状態を保持しない設計により、多数の同時応対を水平スケールのみで処理",
"en": "Kept the docent stateless, so many simultaneous visitors are handled by scaling out alone"
},
{
"ko": "한국어·영어·일본어를 지원하고, 번역문은 사람이 승인한 뒤에만 발행",
"ja": "韓国語・英語・日本語に対応し、翻訳文は人の承認を経てから公開",
"en": "Serves Korean, English and Japanese, with translations published only after a human approves them"
},
{
"ko": "개막 피크를 가정한 부하 테스트에서 720 rps를 5분간 유지해 214,900건을 처리하고 5xx 0건 확인, 쓰기 경로 p95 115ms",
"ja": "開幕ピークを想定した負荷試験で720 rpsを5分間維持し214,900件を処理、5xx 0件を確認。書き込み経路のp95は115ms",
"en": "Held 720 rps for five minutes in a peak-opening load test: 214,900 requests, zero 5xx, and a 115 ms p95 on the write path"
},
{
"ko": "같은 테스트에서 오토스케일 확장·축소가 실제로 동작함을 확인하고, 확장 완료까지 약 4분이 걸려 개막 순간의 급증에는 늦다는 한계를 기록",
"ja": "同テストでオートスケールの拡張・縮小が実際に動作することを確認し、拡張完了まで約4分かかり開幕直後の急増には間に合わない限界を記録",
"en": "Confirmed autoscaling out and back in during the same test, and recorded that scale-out takes about four minutes — too slow for the opening surge"
}
],
"technologies": [
"AWS",
"Terraform",
"GitHub Actions"
],
"links": []
},
{
"id": "vehicle-diagnostics-r300",
"categories": [
"embedded"
],
"name": {
"ko": "차량 부품 상태 진단 시스템 (R300)",
"ja": "車両部品状態診断システム(R300)",
"en": "Vehicle Component Condition Monitoring System (R300)"
},
"period": null,
"role": {
"ko": "팀 프로젝트 · STM32 수집·통신 담당",
"ja": "チームプロジェクト・STM32データ収集/通信担当",
"en": "Team Project · STM32 Data Acquisition & Communications"
},
"summary": {
"ko": "HAL과 RTOS 없이 STM32F411 레지스터를 직접 설정하고, 고속 센서 수집·통신과 2-MCU 안전 구조 구현.",
"ja": "HAL/RTOSを使わずSTM32F411のレジスタを直接設定し、高速センサー収集・通信と2-MCU安全構成を実装。",
"en": "Configured STM32F411 registers directly without HAL or an RTOS, implementing high-rate sensor acquisition, communications, and a two-MCU safety structure."
},
"highlights": [
{
"ko": "3축 진동과 전류를 초당 1,000샘플로 수집하고 timestamp·CRC·프레임 손실·재시작 복구 처리",
"ja": "3軸振動と電流を毎秒1,000サンプルで収集し、timestamp・CRC・フレーム損失・再起動復旧を処理",
"en": "Collected three-axis vibration and current at 1,000 samples/s with timestamps, CRC, frame-loss handling, and restart recovery"
},
{
"ko": "RCC·GPIO·TIM·EXTI·USART·NVIC 레지스터 직접 설정",
"ja": "RCC・GPIO・TIM・EXTI・USART・NVICレジスタを直接設定",
"en": "Direct register configuration for RCC, GPIO, TIM, EXTI, USART, and NVIC"
},
{
"ko": "USART2 수신 인터럽트는 32바이트 링 버퍼 적재만 수행하고 파싱은 메인 루프로 분리",
"ja": "USART2受信割り込みは32バイトリングバッファへの格納だけに限定し、解析をメインループへ分離",
"en": "Reduced the USART2 receive ISR to filling a 32-byte ring buffer and moved parsing to the main loop"
},
{
"ko": "ATmega128A의 active-low ARM/E-STOP·디바운스·heartbeat timeout·latch·watchdog로 2-MCU 안전 구조 설계",
"ja": "ATmega128Aのactive-low ARM/E-STOP、デバウンス、heartbeat timeout、latch、watchdogによる2-MCU安全構成を設計",
"en": "Designed a two-MCU safety structure using ATmega128A active-low ARM/E-STOP, debounce, heartbeat timeout, latch state, and watchdog"
}
],
"technologies": [
"STM32F411",
"ATmega128A",
"C",
"I2C",
"ADC",
"DMA",
"UART",
"PWM"
]
},
{
"id": "ugly-pick",
"categories": [
"cloud",
"backend",
"ai-data"
],
"name": {
"ko": "Ugly Pick — 못난이 농산물 가격 투명성 서비스",
"ja": "Ugly Pick — 規格外農産物の価格透明化サービス",
"en": "Ugly Pick — Price Transparency for Imperfect Produce"
},
"period": {
"start": "2025-03",
"end": "2025-08",
"display": {
"ko": "2025.03 ~ 2025.08",
"ja": "2025.03〜2025.08",
"en": "March 2025 – August 2025"
}
},
"role": {
"ko": "8인 팀 · 백엔드·인프라 전담 · 기여도 50%",
"ja": "8名チーム・バックエンド/インフラ担当・貢献度50%",
"en": "8-person Team · Backend & Infrastructure · 50% contribution"
},
"summary": {
"ko": "현장 검증으로 기획을 피벗하고, Spring Boot와 FastAPI 기반 데이터 수집·모델 서빙 백엔드 및 AWS 운영 환경 구축.",
"ja": "現場検証を基に企画をピボットし、Spring BootとFastAPIによるデータ収集・モデル配信バックエンドとAWS運用環境を構築。",
"en": "Pivoted the product through field validation and built Spring Boot and FastAPI data collection, model-serving backends, and an AWS production environment."
},
"highlights": [
{
"ko": "포항시 농업기술센터 담당자에게 직접 가설을 검증하고 가격 예측 서비스로 피벗",
"ja": "浦項市農業技術センター担当者への直接検証を基に価格予測サービスへピボット",
"en": "Validated assumptions directly with Pohang Agricultural Technology Center and pivoted to price forecasting"
},
{
"ko": "Spring Boot API·오케스트레이션과 FastAPI 데이터 파이프라인·모델 서빙을 분리",
"ja": "Spring BootのAPI/オーケストレーションとFastAPIのデータパイプライン/モデル配信を分離",
"en": "Separated Spring Boot API orchestration from FastAPI data pipelines and model serving"
},
{
"ko": "Nginx 504 병목을 레이어별로 추적해 추론 응답 60초에서 30초로 단축",
"ja": "Nginx 504のボトルネックをレイヤー別に追跡し、推論応答を60秒から30秒へ短縮",
"en": "Traced an Nginx 504 bottleneck layer by layer and reduced inference response time from 60 to 30 seconds"
},
{
"ko": "EBS 8GB Full로 인한 서버 다운을 50GB 확장·로그 로테이션으로 복구",
"ja": "EBS 8GBの容量枯渇による停止を50GBへの拡張とログローテーションで復旧",
"en": "Recovered from an EBS 8 GB disk-full outage by expanding to 50 GB and adding log rotation"
}
],
"technologies": [
"Spring Boot",
"FastAPI",
"MySQL",
"PyTorch",
"AWS",
"Docker",
"Nginx",
"GitHub Actions",
"KAMIS API"
],
"recognition": {
"ko": "한국농수산식품유통공사 사장상(우수상) · 56팀 중 8위",
"ja": "韓国農水産食品流通公社 社長賞(優秀賞)・56チーム中8位",
"en": "Korea Agro-Fisheries & Food Trade Corporation President's Award · 8th of 56 teams"
},
"links": [
{
"label": {
"ko": "데모",
"ja": "デモ",
"en": "Demo"
},
"url": "https://ugly-pick.netlify.app/"
},
{
"label": {
"ko": "데이터·서빙 저장소",
"ja": "データ/配信リポジトリ",
"en": "Data & serving repository"
},
"url": "https://github.com/7SH7/ugly_price_predict"
},
{
"label": {
"ko": "백엔드 저장소",
"ja": "バックエンドリポジトリ",
"en": "Backend repository"
},
"url": "https://github.com/7SH7/ugly_back"
}
]
},
{
"id": "llm-for-science",
"categories": [
"ai-data",
"backend"
],
"name": {
"ko": "LLM for Science — 논문 데이터 파이프라인",
"ja": "LLM for Science — 論文データパイプライン",
"en": "LLM for Science — Research Paper Data Pipeline"
},
"period": {
"start": "2026-02",
"end": "2026-08",
"display": {
"ko": "2026.02 ~ 2026.08",
"ja": "2026.02〜2026.08",
"en": "February – August 2026"
}
},
"role": {
"ko": "가짜연구소 오픈소스 연구",
"ja": "Pseudo Lab オープンソース研究",
"en": "Pseudo Lab Open-source Research"
},
"summary": {
"ko": "대규모 논문 수집을 재개 가능한 파이프라인으로 만들고 단계별 중복·분야 검증을 통해 데이터셋 정제.",
"ja": "大規模論文収集を再開可能なパイプラインとして構築し、段階的な重複・分野検証でデータセットを精製。",
"en": "Built a resumable large-scale paper collection pipeline and curated the dataset through staged duplicate and relevance validation."
},
"highlights": [
{
"ko": "39개 키워드×11개 분야로 Semantic Scholar 논문 261,934건 수집",
"ja": "39キーワード×11分野でSemantic Scholar論文261,934件を収集",
"en": "Collected 261,934 Semantic Scholar papers across 39 keywords and 11 fields"
},
{
"ko": "해시 정확 중복 2,701건·Jaccard 유사 중복 40건·무관 분야 12,213건 제거",
"ja": "ハッシュ完全重複2,701件・Jaccard類似重複40件・無関係分野12,213件を除外",
"en": "Removed 2,701 exact hash duplicates, 40 Jaccard near-duplicates, and 12,213 off-topic records"
},
{
"ko": "raw·processed 분리와 checkpoint로 중단 지점부터 재개",
"ja": "raw/processed分離とcheckpointにより中断地点から再開",
"en": "Separated raw and processed data and used checkpoints for restartable collection"
},
{
"ko": "Full-text 5,684·Abstract 12,163·Title 229,133으로 최종 분리",
"ja": "Full-text 5,684・Abstract 12,163・Title 229,133に最終分類",
"en": "Final split: 5,684 full text, 12,163 abstract, and 229,133 title-only records"
}
],
"technologies": [
"Python",
"Semantic Scholar API",
"Parquet",
"PyArrow"
],
"links": [
{
"label": {
"ko": "가짜연구소 프로젝트 목록",
"ja": "Pseudo Labプロジェクト一覧",
"en": "Pseudo Lab project listing"
},
"url": "https://pseudo-lab.com/events/pseudocon-2026"
}
]
}
],
"other_projects": [
{
"id": "forensicagent",
"categories": [
"ai-data",
"backend"
],
"name": {
"ko": "forensicagent — 포렌식 자동 분류 CLI 에이전트",
"ja": "forensicagent — フォレンジック自動分類CLIエージェント",
"en": "forensicagent — Forensic triage CLI agent"
},
"period": {
"start": "2026-08",
"end": "2026-09",
"display": {
"ko": "2026.08 ~ 2026.09",
"ja": "2026.08〜2026.09",
"en": "August – September 2026"
}
},
"role": {
"ko": "오픈소스 개인 프로젝트 · 설계·구현",
"ja": "オープンソース個人プロジェクト・設計/実装",
"en": "Open-source solo project · Design & implementation"
},
"summary": {
"ko": "증거를 식별해 어떤 도구를 어떤 순서로 돌릴지 정하고, 도구 출력에서 알려진 의심 패턴만 뽑아 리포트로 묶는 triage 단계를 자동화.",
"ja": "証拠を識別してどのツールをどの順で実行するかを決め、ツール出力から既知の疑わしいパターンのみを抽出してレポートにまとめるtriage工程を自動化。",
"en": "Automates the triage step: identify the evidence, decide which tools run in what order, and pull only known suspicious patterns from their output into a report."
},
"highlights": [
{
"ko": "Scanner → Selector → Executor → Analyzer → Reporter 5단계를 순수 함수와 데이터클래스로 분리해 어느 단계든 stub으로 교체해도 나머지가 깨지지 않게 구성",
"ja": "Scanner→Selector→Executor→Analyzer→Reporterの5段階を純粋関数とデータクラスで分離し、どの段階をstubに差し替えても他が壊れない構成に",
"en": "Split the pipeline into five stages of pure functions and dataclasses so any stage can be swapped for a stub without breaking the others"
},
{
"ko": "도구 선별을 결정론 필터 → RAG 재정렬 → LLM 우선순위 3단계로 나누고, RAG는 순서와 컨텍스트만 바꾸고 실행 자격은 바꾸지 못하도록 제한",
"ja": "ツール選別を決定論フィルタ→RAG再整列→LLM優先順位の3段階に分け、RAGは順序と文脈のみに影響し実行資格は変更できないよう制限",
"en": "Staged tool selection as deterministic filter, then RAG re-ranking, then LLM prioritization, with RAG able to change order and context but never eligibility"
},
{
"ko": "RAG 의존성이나 인덱스가 없으면 결정론 경로로 조용히 폴백하고, LLM 파싱 실패 시에도 앞 단계 결과를 그대로 사용해 파이프라인이 항상 동작",
"ja": "RAGの依存関係やインデックスが無ければ決定論経路へ静かにフォールバックし、LLMの解析失敗時も前段の結果をそのまま使用してパイプラインが常に動作",
"en": "Falls back silently to the deterministic path when RAG dependencies or the index are absent, and reuses the prior stage when LLM parsing fails, so the pipeline always runs"
},
{
"ko": "증거를 외부로 보내지 않도록 로컬 LLM을 사용하고, 도메인 지식은 모델이 아니라 도구 메타데이터 YAML에 두어 도구 추가 비용을 파일 하나로 축소",
"ja": "証拠を外部に送らないようローカルLLMを使用し、ドメイン知識はモデルではなくツールメタデータのYAMLに置くことでツール追加コストをファイル1つに",
"en": "Runs a local LLM so evidence never leaves the machine, and keeps domain knowledge in tool-metadata YAML rather than the model, reducing a new tool to one file"