diff --git a/API_INTERFACE.md b/API_INTERFACE.md new file mode 100644 index 0000000..40af5a6 --- /dev/null +++ b/API_INTERFACE.md @@ -0,0 +1,366 @@ +# AI Agent Networking Lab (ANL) — REST API Interface Specification + +This document defines the RESTful API endpoints, request parameters, response schemas, and data structures provided by the ANL Go/Gin backend server. + +--- + +## 1. General API Conventions + +### 1.1 Base URL +- **Local Development**: `http://localhost:8080/api/v1` +- **Protocol**: HTTP/1.1 (JSON Content-Type: `application/json; charset=utf-8`) + +### 1.2 Standard Response Envelope + +All API endpoints strictly follow the uniform JSON response envelope structure. + +#### Success Response (`200 OK`) +```json +{ + "data": +} +``` + +#### Error Response (`4xx / 5xx`) +```json +{ + "error": { + "message": "Human-readable error description" + } +} +``` + +### 1.3 HTTP Status Codes +| Status Code | Description | +|---|---| +| `200 OK` | The request succeeded and returned the requested data. | +| `400 Bad Request` | Invalid query parameter (e.g., unsupported publication category). | +| `404 Not Found` | The requested resource was not found. | +| `500 Internal Server Error` | Unexpected server-side failure during database query or processing. | + +--- + +## 2. API Endpoints Specification + +### 2.1 System & Health + +#### `GET /api/v1/health` +Checks backend API service health and database availability. + +- **Response Payload**: +```json +{ + "data": { + "service": "anl-backend-api", + "status": "ok" + } +} +``` + +--- + +## 2.2 Home & Overview + +#### `GET /api/v1/research-projects` +Retrieves the list of all active research projects. + +- **Response Payload**: +```json +{ + "data": [ + { + "id": 1, + "slug": "iot-standards", + "title": "AIoT & AI-RAN", + "abstract": "AIoT & AI-RAN investigates agent-based IoT architectures in which autonomous AI agents are distributed across sensor, edge, and radio access layers. The project studies agent-to-agent coordination over high-performance transport (gRPC/QUIC) bridged with constrained edge protocols (MQTT/CoAP), targeting AI-RAN designs for distributed autonomous control.", + "keywords": [ + "AIoT", + "agent-based IoT", + "AI-RAN", + "constrained edge protocols", + "distributed autonomous control" + ], + "organization": "National Research Foundation of Korea (NRF)", + "standards_org": "NRF", + "period": "2026 ~ Present", + "funder": null, + "created_at": "2026-08-24T16:47:14Z", + "updated_at": "2026-08-24T16:47:14Z" + } + ] +} +``` + +#### `GET /api/v1/research-areas` +Retrieves the list of 14 core research areas ordered by `display_order`. + +- **Response Payload**: +```json +{ + "data": [ + { + "id": 1, + "name_en": "Quick UDP Internet Connection (QUIC)", + "name_kr": null, + "display_order": 1 + }, + { + "id": 2, + "name_en": "QUIC-based Mobility and Multi-Streaming Support", + "name_kr": null, + "display_order": 2 + } + ] +} +``` + +#### `GET /api/v1/stats/summary` +Retrieves aggregated top-level metrics for the homepage hero section. + +- **Response Payload**: +```json +{ + "data": { + "intl_publications": 68, + "standardization_docs": 44, + "patents": 75 + } +} +``` + +--- + +## 2.3 Members & Alumni + +#### `GET /api/v1/members` +Retrieves all 16 active members (including the professor and graduate researchers) ordered by `display_order`. + +- **Response Payload**: +```json +{ + "data": [ + { + "id": 1, + "name_ko": "고석주", + "name_en": "Seok-Joo Koh", + "degree": "Professor", + "affiliation": "School of Computer Science and Engineering", + "email": "sjkoh@knu.ac.kr", + "is_advisor": true, + "display_order": 1, + "created_at": "2026-08-24T16:47:14Z" + }, + { + "id": 2, + "name_ko": "김경호", + "name_en": "Kyeong-Ho Kim", + "degree": "PhDStudent", + "affiliation": null, + "email": null, + "is_advisor": false, + "display_order": 2, + "created_at": "2026-08-24T16:47:14Z" + } + ] +} +``` + +#### `GET /api/v1/alumni` +Retrieves all 60 alumni sorted chronologically by `graduated_at DESC`. + +- **Response Payload**: +```json +{ + "data": [ + { + "id": 1, + "name_ko": "도경진", + "name_en": "Gyeong-Jin Do", + "degree": "MS", + "graduated_at": "2024-02", + "major": "School of Electronic and Electrical Engineering", + "current_position": "LIG Nex1, Senior Researcher", + "created_at": "2026-08-24T16:47:14Z" + } + ] +} +``` + +--- + +## 2.4 Publications & Intellectual Property + +#### `GET /api/v1/publications` +Retrieves list of academic publications. Supports filtering by publication category. + +- **Query Parameters**: + - `category` (optional, string): Filter by category. Allowed values: `intl-journal-conf`, `domestic-journal-conf`. +- **Response Payload**: +```json +{ + "data": [ + { + "id": 1, + "category": "intl-journal-conf", + "title": "Globally Integrated Trust Authority (GITA) for Resource-Constrained Edge Devices in IoT and 6G", + "authors": "Seok-Joo Koh, ...", + "venue": "IEEE Transactions on Network and Service Management", + "volume": "Vol. 23, pp. 4490~4505, April 2026", + "published_at": "2026-04", + "kci": false, + "doi": "10.1109/TNSM.2026.10908861", + "is_highlight": true, + "created_at": "2026-08-24T16:47:14Z" + } + ] +} +``` + +#### `GET /api/v1/publications/highlights` +Retrieves the **5 designated top representative publications** (`WHERE is_highlight = 1`). + +- **Response Payload**: +```json +{ + "data": [ + { + "id": 1, + "category": "intl-journal-conf", + "title": "Globally Integrated Trust Authority (GITA) for Resource-Constrained Edge Devices in IoT and 6G", + "authors": "Seok-Joo Koh, ...", + "venue": "IEEE Transactions on Network and Service Management", + "volume": "Vol. 23, pp. 4490~4505, April 2026", + "published_at": "2026-04", + "kci": false, + "doi": "10.1109/TNSM.2026.10908861", + "is_highlight": true, + "created_at": "2026-08-24T16:47:14Z" + }, + { + "id": 2, + "category": "intl-journal-conf", + "title": "Application Level Trust Authority (APPLETA) for Resource-Constrained Edge Devices in IoT and 6G", + "authors": "Seok-Joo Koh, ...", + "venue": "IEEE Transactions on Consumer Electronics", + "volume": "Vol. 71, pp. 1120~1135, Jan. 2026", + "published_at": "2026-01", + "kci": false, + "doi": "10.1109/TCE.2025.3524673", + "is_highlight": true, + "created_at": "2026-08-24T16:47:14Z" + } + ] +} +``` + +#### `GET /api/v1/patents` +Retrieves all 75 registered and pending patents sorted by `published_at DESC`. + +- **Response Payload**: +```json +{ + "data": [ + { + "id": 1, + "title": "다중 인터페이스 기반 QUIC 핸드오버 지원 장치 및 방법", + "inventors": "고석주, 김경호", + "application_no": "10-2024-0012345", + "application_at": "2024-01-15", + "registration_no": "10-2567890", + "registration_at": "2025-05-20", + "country": "KR", + "published_at": "2025-05-20", + "created_at": "2026-08-24T16:47:14Z" + } + ] +} +``` + +--- + +## 2.5 Lectures & Curriculum + +#### `GET /api/v1/semesters` +Retrieves all 45 academic semesters with nested course lists, ordered by `year DESC` and `term` (Fall before Spring). + +- **Response Payload**: +```json +{ + "data": [ + { + "id": 1, + "year": 2026, + "term": "Spring", + "courses": [ + { + "id": 1, + "semester_id": 1, + "code": "COMP0411", + "name_en": "Computer Networks", + "name_kr": null, + "note": "Undergraduate Core", + "display_order": 1 + } + ] + }, + { + "id": 2, + "year": 2025, + "term": "Fall", + "courses": [ + { + "id": 2, + "semester_id": 2, + "code": "COMP0754", + "name_en": "Advanced Internet Protocol", + "name_kr": null, + "note": "Graduate Course", + "display_order": 1 + } + ] + } + ] +} +``` + +--- + +## 2.6 Standardization + +#### `GET /api/v1/standards-bodies` +Retrieves all 6 standardization bodies with 3-tier hierarchy (`Body → Project (WG) → Documents[]`). + +- **Response Payload**: +```json +{ + "data": [ + { + "id": 1, + "org": "IEC TC100", + "full_name": "International Electrotechnical Commission: Technical Committee 100", + "scope": "international", + "period": "2018 ~ Present", + "role": "Project Editor / Active Contributor", + "display_order": 1, + "projects": [ + { + "wg": "WG 12", + "name": "MCM: Multilateral and Collaborative Metaverse", + "documents": [ + { + "id": 1, + "body_id": 1, + "wg": "WG 12", + "project_name": "MCM: Multilateral and Collaborative Metaverse", + "title": "Conceptual model for multilateral and collaborative metaverse systems", + "doc_ref": "IEC 63430 ED1", + "status": "IS", + "published_at": "2026-03" + } + ] + } + ] + } + ] +} +``` diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000..263c066 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,102 @@ +# AI Agent Networking Lab (ANL) — System Architecture Specification + +## 1. System Overview + +AI Agent Networking Lab (ANL) 시스템은 연구실의 학술 실적(논문, 특허), 연구 과제, 구성원, 강의, 표준화 기고서 등의 데이터를 효율적으로 관리하고 제공하기 위한 **하이브리드 데이터 아키텍처(Decoupled Static-Export & Headless API Architecture)**로 설계되었습니다. + +Next.js 기반의 고성능 정적 웹사이트(SSG)와 Go/Gin 및 SQLite 기반의 독립형 헤드리스(Headless) 백엔드 API 서버를 분리하여, **완벽한 정적 빌드 성능(0 Dynamic Route)**과 **단일 진실 공급원(Single Source of Truth) 기반의 데이터 관리 편의성**을 동시에 달성합니다. + +--- + +## 2. High-Level Architecture Diagram + +```mermaid +graph TD + subgraph "Storage & Ingestion Layer" + SEED["Seed Data JSON
(backend/seed/data/*.json)"] -->|cmd/seed| SQLITE[("SQLite Database
(anl.db - WAL Mode)")] + SQLITE -->|cmd/export-content| TS_CONTENT["Static TypeScript Content
(refer_landing_page/content/*.ts)"] + end + + subgraph "Backend API Serving Layer (Go / Gin)" + API_MAIN["API Server Binary
(backend/cmd/api)"] --> ROUTER["Gin Engine & Router
(internal/router)"] + ROUTER --> HANDLERS["Domain Handlers
(internal/handlers)"] + HANDLERS --> REPO["Repository Layer
(internal/repository)"] + REPO -->|database/sql + modernc.org/sqlite| SQLITE + end + + subgraph "Frontend Presentation Layer (Next.js 14 SSG)" + TS_CONTENT --> NEXT_BUILD["Next.js Static Build Engine
(○ Static / ● SSG)"] + NEXT_BUILD --> SSG_PAGES["Static HTML Routes
(/, /members, /publications, etc.)"] + ADMIN["Future Admin Dashboard
(CRUD Client)"] -.->|REST API /api/v1| ROUTER + CLIENT_BROWSER["End Users / Browsers"] -->|Fast CDN / Nginx Serving| SSG_PAGES + end +``` + +--- + +## 3. Core Architectural Principles + +### 3.1 Single Source of Truth (SSOT) +- 모든 연구실 데이터(과제, 멤버, 논문, 특허, 강의, 표준화)는 **SQLite 데이터베이스(`anl.db`)**를 단일 원천으로 관리합니다. +- 데이터 갱신 시 `cmd/export-content` 도구를 통해 프론트엔드의 `content/*.ts` 파일로 동기화되어 코드와 데이터의 정합성을 보장합니다. + +### 3.2 Zero-CGO Pure Go & Portability +- SQLite 드라이버로 **`modernc.org/sqlite`**를 채택하여 CGO 의존성을 완전히 제거했습니다. +- C 컴파일러 없이도 단일 실행 바이너리(`bin/api`, `bin/seed`, `bin/export-content`)로 컴파일되며, macOS, Linux, Docker 컨테이너 등 어떤 환경에서도 즉시 구동됩니다. + +### 3.3 High-Performance Read Optimization (WAL Mode) +- 랜딩페이지 특성상 읽기(Read) 요청이 99% 이상이므로, SQLite 연결 시 **WAL(Write-Ahead Logging)** 모드와 `busy_timeout=5000`을 적용하여 동시 다발적인 읽기 트랜잭션에서 잠금 경합 없는 고속 처리를 보장합니다. + +### 3.4 Strict Static Build Compliance (DM-03 / AC-17) +- 프론트엔드 빌드 시 런타임 API 호출 의존성을 배제하여 Next.js 정적 사전 렌더링(`○ Static` / `● SSG`) 원칙을 100% 준수합니다. + +--- + +## 4. Layered Module Structure + +``` +backend/ +├── cmd/ +│ ├── api/main.go # Gin HTTP REST API 서버 엔드포인트 (:8080) +│ ├── seed/main.go # SQLite DDL 마이그레이션 및 JSON 시드 데이터 인제스트 도구 +│ └── export-content/main.go # SQLite DB 데이터를 프론트엔드 content/*.ts 파일로 내보내는 도구 +├── internal/ +│ ├── db/ +│ │ ├── db.go # SQLite 커넥션 풀 관리 및 PRAGMA 설정 (WAL, foreign_keys) +│ │ └── migrations/ # golang-migrate SQL DDL 스크립트 (000001_init.up.sql / down.sql) +│ ├── models/ # 도메인별 데이터 구조체 모델 +│ │ ├── home.go # ResearchProject, ResearchArea, StatsSummary +│ │ ├── members.go # Member, Alumnus +│ │ ├── publications.go # Publication, Patent +│ │ ├── lectures.go # Semester, Course +│ │ └── standardization.go # StandardsBody, StandardProject, StandardDocument +│ ├── repository/ # database/sql 기반 비즈니스 쿼리 계층 (N+1 방지 일괄 쿼리 최적화) +│ ├── handlers/ # Gin HTTP 요청 바인딩 및 JSON 응답 핸들러 +│ ├── router/ # API 라우트 등록, CORS 미들웨어 및 통합 테스트 +│ └── httpx/ # 표준 JSON 응답 봉투 ({ data: ... } / { error: ... }) +├── seed/data/ # 손실 없이 추출된 원본 JSON 데이터셋 +└── Makefile # 빌드, 테스트, 시드, 실행 자동화 타겟 +``` + +--- + +## 5. Data Flow Workflows + +### 5.1 Initial Seeding & Database Bootstrap +1. `make seed` 실행 +2. `cmd/seed`가 SQLite 데이터베이스 파일(`anl.db`)을 생성 +3. 임베디드된 마이그레이션 DDL(`000001_init.up.sql`)을 실행하여 11개 테이블과 인덱스 생성 +4. `seed/data/*.json` 파일들을 읽어 트랜잭션 내에서 일괄 삽입 +5. 각 테이블별 행(Row) 개수 및 5대 대표 논문(`is_highlight=1`) 정합성을 자동 검증 + +### 5.2 Content Export & Frontend Build +1. 데이터베이스 변경 후 `make export-content` 실행 +2. `cmd/export-content`가 SQLite에서 최신 데이터를 조회 +3. `refer_landing_page/content/*.ts` 파일들을 타입 안전한 TypeScript 상수로 덮어쓰기 생성 +4. Next.js 빌드(`npm run build`)를 통해 15개 정적 HTML 페이지가 100% SSG로 생성 + +### 5.3 Live REST API Serving +1. `make run` 또는 `./bin/api` 실행 (기본 포트 `:8080`) +2. 클라이언트가 `/api/v1/*` 엔드포인트로 HTTP GET 요청 +3. Gin 라우터가 요청을 파싱하고 적절한 도메인 핸들러로 전달 +4. 리포지토리 계층이 파라미터화된 SQL 쿼리로 SQLite 조회 후 일관된 JSON Envelope 형식으로 반환 diff --git a/DATA_TABLE.md b/DATA_TABLE.md new file mode 100644 index 0000000..4b66d84 --- /dev/null +++ b/DATA_TABLE.md @@ -0,0 +1,119 @@ +# AI Agent Networking Lab (ANL) — Backend Database Schema Specification + +This document defines the SQLite database schema and REST API entities to decouple data from the frontend landing page. + +--- + +## 1. `/home` (Home & Overview) + +### 1.1 `research_projects` (연구 과제) +- `id` (INTEGER, PK, AUTOINCREMENT) +- `slug` (TEXT, UNIQUE, NOT NULL) — e.g. `iot-standards`, `ccis`, `vlc-iot` +- `title` (TEXT, NOT NULL) — e.g. `AIoT & AI-RAN`, `MCM`, `MVQM` +- `abstract` (TEXT, NOT NULL) +- `keywords` (TEXT, JSON Array) — e.g. `["AIoT", "agent-based IoT", "AI-RAN"]` +- `organization` (TEXT) — e.g. `National Research Foundation of Korea (NRF)`, `IEC/TC 100/WG 12 supported by KEIT` +- `standards_org` (TEXT) — e.g. `NRF`, `IEC TC100` +- `period` (TEXT) — e.g. `2026 ~ Present` +- `funder` (TEXT, OPTIONAL) +- `created_at` (DATETIME) +- `updated_at` (DATETIME) + +### 1.2 `research_areas` (연구 분야) +- `id` (INTEGER, PK, AUTOINCREMENT) +- `name_en` (TEXT, NOT NULL) — e.g. `AI Agent Networking`, `QUIC & Transport Protocol` +- `name_kr` (TEXT) — e.g. `AI 에이전트 네트워킹` +- `display_order` (INTEGER, DEFAULT 0) + +--- + +## 2. `/members` (구성원 및 졸업생) + +### 2.1 `members` (현재 연구원) +- `id` (INTEGER, PK, AUTOINCREMENT) +- `name_ko` (TEXT, NOT NULL) — e.g. `고석주` +- `name_en` (TEXT, NOT NULL) — e.g. `Seok-Joo Koh` +- `degree` (TEXT, NOT NULL) — `Professor`, `PhD`, `PhDCandidate`, `PhDStudent`, `MSCandidate`, `MSStudent` +- `affiliation` (TEXT) — e.g. `School of Computer Science and Engineering` +- `email` (TEXT) +- `is_advisor` (BOOLEAN, DEFAULT FALSE) +- `display_order` (INTEGER, DEFAULT 0) +- `created_at` (DATETIME) + +### 2.2 `alumni` (졸업생) +- `id` (INTEGER, PK, AUTOINCREMENT) +- `name_ko` (TEXT, NOT NULL) +- `name_en` (TEXT, NOT NULL) +- `degree` (TEXT, NOT NULL) — `PhD`, `MS` +- `graduated_at` (TEXT, NOT NULL) — `YYYY-MM` (e.g. `2024-02`) +- `major` (TEXT) — e.g. `Computer Science and Engineering` +- `current_position` (TEXT) — e.g. `Samsung Electronics, Senior Researcher` +- `created_at` (DATETIME) + +--- + +## 3. `/publications` (연구 실적 & 지식재산권) + +### 3.1 `publications` (학술 논문) +- `id` (INTEGER, PK, AUTOINCREMENT) +- `category` (TEXT, NOT NULL) — `intl-journal-conf`, `domestic-journal-conf` +- `title` (TEXT, NOT NULL) +- `authors` (TEXT) — e.g. `Seok-Joo Koh, ...` +- `venue` (TEXT, NOT NULL) — e.g. `IEEE Transactions on Network and Service Management` +- `volume` (TEXT) — e.g. `Vol. 23, pp. 4490~4505, April 2026` +- `published_at` (TEXT, NOT NULL) — `YYYY-MM` or `YYYY-MM-DD` +- `kci` (BOOLEAN, DEFAULT FALSE) +- `doi` (TEXT) +- `is_highlight` (BOOLEAN, DEFAULT FALSE) — For Top Representative Highlights +- `created_at` (DATETIME) + +### 3.2 `patents` (특허) +- `id` (INTEGER, PK, AUTOINCREMENT) +- `title` (TEXT, NOT NULL) +- `inventors` (TEXT, NOT NULL) +- `application_no` (TEXT, NOT NULL) +- `application_at` (TEXT, NOT NULL) — `YYYY-MM-DD` +- `registration_no` (TEXT) +- `registration_at` (TEXT) — `YYYY-MM-DD` +- `country` (TEXT, NOT NULL) — e.g. `KR`, `US` +- `published_at` (TEXT, NOT NULL) +- `created_at` (DATETIME) + +--- + +## 4. `/lectures` (강의) + +### 4.1 `semesters` (학기) +- `id` (INTEGER, PK, AUTOINCREMENT) +- `year` (INTEGER, NOT NULL) — e.g. `2026` +- `term` (TEXT, NOT NULL) — `Spring`, `Fall` + +### 4.2 `courses` (개설 과목) +- `id` (INTEGER, PK, AUTOINCREMENT) +- `semester_id` (INTEGER, NOT NULL, FK -> semesters.id) +- `code` (TEXT, NOT NULL) — e.g. `COMP0411` +- `name_en` (TEXT, NOT NULL) — e.g. `Computer Networks` +- `name_kr` (TEXT) +- `note` (TEXT) — e.g. `Graduate Course` + +--- + +## 5. `/standardization` (국제 표준화) + +### 5.1 `standards_bodies` (표준화 기구) +- `id` (INTEGER, PK, AUTOINCREMENT) +- `org` (TEXT, NOT NULL) — e.g. `IEC TC100`, `ITU-T SG17` +- `full_name` (TEXT, NOT NULL) +- `scope` (TEXT, NOT NULL) — `international`, `domestic` +- `period` (TEXT, NOT NULL) — e.g. `2018 ~ Present` +- `role` (TEXT) — e.g. `Project Editor` + +### 5.2 `standard_documents` (표준 문서 및 기고서) +- `id` (INTEGER, PK, AUTOINCREMENT) +- `body_id` (INTEGER, NOT NULL, FK -> standards_bodies.id) +- `wg` (TEXT, NOT NULL) — e.g. `WG 12` +- `project_name` (TEXT, NOT NULL) +- `title` (TEXT, NOT NULL) +- `doc_ref` (TEXT, NOT NULL) — e.g. `IEC 63430 ED1` +- `status` (TEXT, NOT NULL) — `IS`, `TS`, `TR`, `CDV`, `WDTR`, `InProgress` +- `published_at` (TEXT) \ No newline at end of file diff --git a/backend/.env.example b/backend/.env.example new file mode 100644 index 0000000..9265df7 --- /dev/null +++ b/backend/.env.example @@ -0,0 +1,19 @@ +# ============================================================================== +# AI Agent Networking Lab (ANL) Backend API Server Configuration +# ============================================================================== + +# Server binding host and port +HOST=0.0.0.0 +PORT=8080 + +# SQLite database file path (Inside container: /app/data/anl.db) +DB_PATH=anl.db + +# Gin runtime mode: release | debug | test +GIN_MODE=release + +# Allowed CORS Origins (Comma separated, or * for all) +CORS_ALLOW_ORIGINS=* + +# Automatically run SQL schema migrations on startup (true | false) +AUTO_MIGRATE=true diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..fb277ef --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,12 @@ +# Binaries and build outputs +/bin/ + +# SQLite databases and WAL journal files +*.db +*.db-wal +*.db-shm + +# Environment files +.env +.env.* +!.env.example diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..f7280cd --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,63 @@ +# ============================================================================== +# Stage 1: Build the Go Binaries +# ============================================================================== +FROM golang:1.26-alpine AS builder + +WORKDIR /app + +# Install git and certificates +RUN apk add --no-cache git ca-certificates tzdata + +# Download dependencies +COPY go.mod go.sum ./ +RUN go mod download + +# Copy backend source code +COPY . . + +# Build pure-Go static binaries +RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /bin/api ./cmd/api && \ + CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /bin/seed ./cmd/seed && \ + CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /bin/export-content ./cmd/export-content + +# ============================================================================== +# Stage 2: Minimal Runtime Image +# ============================================================================== +FROM alpine:3.20 + +WORKDIR /app + +# Install ca-certificates and sqlite cli for maintenance +RUN apk add --no-cache ca-certificates tzdata sqlite curl && \ + addgroup -S appgroup && adduser -S appuser -G appgroup + +# Create persistent database storage directory +RUN mkdir -p /app/data && chown -R appuser:appgroup /app/data + +# Copy built binaries from builder +COPY --from=builder /bin/api /app/bin/api +COPY --from=builder /bin/seed /app/bin/seed +COPY --from=builder /bin/export-content /app/bin/export-content + +# Copy seed data +COPY --from=builder /app/seed /app/seed + +# Copy environment template +COPY --from=builder /app/.env.example /app/.env + +# Set environment defaults for container +ENV HOST=0.0.0.0 \ + PORT=8080 \ + DB_PATH=/app/data/anl.db \ + GIN_MODE=release \ + CORS_ALLOW_ORIGINS=* \ + AUTO_MIGRATE=true + +EXPOSE 8080 + +USER appuser + +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:8080/api/v1/health || exit 1 + +ENTRYPOINT ["/app/bin/api"] diff --git a/backend/Makefile b/backend/Makefile new file mode 100644 index 0000000..bc4cdb3 --- /dev/null +++ b/backend/Makefile @@ -0,0 +1,39 @@ +.PHONY: all build run seed export-content test fmt fmt-check vet clean + +BIN_DIR := bin +DB_PATH := anl.db + +all: fmt-check vet build test + +build: + @mkdir -p $(BIN_DIR) + @echo "Building api server..." + go build -o $(BIN_DIR)/api ./cmd/api + @echo "Building seeder..." + go build -o $(BIN_DIR)/seed ./cmd/seed + @echo "Building content exporter..." + go build -o $(BIN_DIR)/export-content ./cmd/export-content + +run: build + ./$(BIN_DIR)/api --db $(DB_PATH) + +seed: build + ./$(BIN_DIR)/seed --db $(DB_PATH) --seed-dir seed/data + +export-content: build + ./$(BIN_DIR)/export-content --db $(DB_PATH) --out-dir ../refer_landing_page/content + +fmt: + gofmt -w . + +fmt-check: + @test -z "$$(gofmt -l .)" || (echo "gofmt check failed on files:" && gofmt -l . && exit 1) + +vet: + go vet ./... + +test: fmt-check vet + go test -v ./... + +clean: + rm -rf $(BIN_DIR) *.db* diff --git a/backend/README.md b/backend/README.md new file mode 100644 index 0000000..d7e55c1 --- /dev/null +++ b/backend/README.md @@ -0,0 +1,129 @@ +# AI Agent Networking Lab (ANL) — Go/Gin/SQLite Backend API + +This module implements the standalone backend REST API server, SQLite database storage, seed ingestion pipeline, and static content exporter for the ANL landing page. + +--- + +## 🏛 Architecture Overview + +``` ++-------------------------------------------------------------+ +| SQLite (anl.db) | +| 11 Relational Tables (Projects, Members, Pubs, Lectures) | ++-------------------------------------------------------------+ + ▲ ▲ + │ (cmd/seed) │ (SQL query) + │ │ ++-------------------------------+ +-------------------------+ +| seed/data/*.json | | Gin REST API Server | +| (extracted from content/*.ts) | | (cmd/api, :8080) | ++-------------------------------+ +-------------------------+ + │ + +-------------------------+ + | Content Exporter | + | (cmd/export-content) | + +-------------------------+ + │ + ▼ + +-------------------------+ + | Next.js Static SSG | + | (refer_landing_page/) | + +-------------------------+ +``` + +--- + +## 🚀 Quick Start + +### 1. Build Binaries +```bash +make build +``` +Creates `bin/api`, `bin/seed`, and `bin/export-content`. + +### 2. Run Migrations & Seed Database +```bash +make seed +``` +Creates `anl.db`, executes SQL DDL migrations, inserts seed data, and verifies all 11 table row counts and the 5 designated highlights. + +### 3. Run Backend API Server +```bash +make run +# Or with options: +./bin/api --port 8080 --db anl.db +``` +Server starts at `http://localhost:8080/api/v1`. + +### 4. Run Unit & Integration Tests +```bash +make test +``` + +### 5. Export Content to Next.js Frontend +```bash +make export-content +``` +Regenerates `refer_landing_page/content/*.ts` from SQLite with typed `isHighlight` metadata. + +--- + +## 📡 REST API Endpoints (`/api/v1`) + +| Method | Path | Description | +|---|---|---| +| `GET` | `/api/v1/health` | Service health status check | +| `GET` | `/api/v1/research-projects` | 3 research project entities | +| `GET` | `/api/v1/research-areas` | 14 core research areas ordered by `display_order` | +| `GET` | `/api/v1/stats/summary` | Aggregated counts (`intl_publications`, `standardization_docs`, `patents`) | +| `GET` | `/api/v1/members` | 16 active members (with `is_advisor` flag) | +| `GET` | `/api/v1/alumni` | 60 alumni ordered chronologically | +| `GET` | `/api/v1/publications` | 148 publications (supports `?category=intl-journal-conf` or `domestic-journal-conf`) | +| `GET` | `/api/v1/publications/highlights` | 5 designated top representative publications (`WHERE is_highlight = 1`) | +| `GET` | `/api/v1/patents` | 75 intellectual property patents | +| `GET` | `/api/v1/semesters` | 45 semesters with nested courses, ordered by year DESC and term | +| `GET` | `/api/v1/standards-bodies` | 6 standards bodies with nested projects and documents (deterministic ordering) | + +--- + +## ⚙️ Environment Configuration (`.env`) + +Copy `.env.example` to `.env` to customize runtime settings: + +```bash +cp .env.example .env +``` + +| Variable | Default | Description | +|---|---|---| +| `HOST` | `0.0.0.0` | Binding host IP address | +| `PORT` | `8080` | Server listening port | +| `DB_PATH` | `anl.db` | SQLite database file path | +| `GIN_MODE` | `release` | Gin runtime mode (`release`, `debug`, `test`) | +| `CORS_ALLOW_ORIGINS` | `*` | Allowed CORS origins (e.g. `https://anl.knu.ac.kr`) | +| `AUTO_MIGRATE` | `true` | Apply database migrations automatically on startup | + +--- + +## 🐳 Docker & Containerization + +### Build & Run Container +```bash +docker build -t anl-backend-api . +docker run -p 8080:8080 -v anl-data:/app/data anl-backend-api +``` + +### Docker Compose +Run the full backend service with automated healthchecks and volume persistence from the repository root: + +```bash +docker compose up -d +``` + +--- + +## 📦 Database Schema & Specifications + +* **Architecture**: See [ARCHITECTURE.md](../ARCHITECTURE.md) +* **REST API Interfaces**: See [API_INTERFACE.md](../API_INTERFACE.md) +* **Database Schema Spec**: See [DATA_TABLE.md](../DATA_TABLE.md) and [000001_init.up.sql](internal/db/migrations/000001_init.up.sql) diff --git a/backend/cmd/api/main.go b/backend/cmd/api/main.go new file mode 100644 index 0000000..293fc0f --- /dev/null +++ b/backend/cmd/api/main.go @@ -0,0 +1,60 @@ +package main + +import ( + "flag" + "log" + + "git.godopu.com/lab/landing_page/backend/internal/config" + "git.godopu.com/lab/landing_page/backend/internal/db" + "git.godopu.com/lab/landing_page/backend/internal/router" + "github.com/gin-gonic/gin" +) + +func main() { + // Load environment variables & .env + cfg := config.Load() + + // Optional CLI flags override environment defaults + portFlag := flag.Int("port", 0, "Port for the Gin server to listen on (overrides PORT)") + hostFlag := flag.String("host", "", "Host for the Gin server to bind on (overrides HOST)") + dbPathFlag := flag.String("db", "", "Path to SQLite database file (overrides DB_PATH)") + ginModeFlag := flag.String("mode", "", "Gin mode: release, debug, test (overrides GIN_MODE)") + flag.Parse() + + if *portFlag > 0 { + cfg.Port = *portFlag + } + if *hostFlag != "" { + cfg.Host = *hostFlag + } + if *dbPathFlag != "" { + cfg.DBPath = *dbPathFlag + } + if *ginModeFlag != "" { + cfg.GinMode = *ginModeFlag + } + + gin.SetMode(cfg.GinMode) + + log.Printf("Connecting to SQLite database at %s...", cfg.DBPath) + database, err := db.Connect(cfg.DBPath) + if err != nil { + log.Fatalf("Failed to connect to database: %v", err) + } + defer database.Close() + + if cfg.AutoMigrate { + log.Println("Ensuring database schema migrations are applied...") + if err := db.RunMigrations(database); err != nil { + log.Fatalf("Migration failed: %v", err) + } + } + + r := router.SetupRouter(database, cfg.CORSAllowOrigins) + + addr := cfg.Address() + log.Printf("Starting ANL Backend API server on http://%s/api/v1 (mode: %s)...", addr, cfg.GinMode) + if err := r.Run(addr); err != nil { + log.Fatalf("Server failed to run: %v", err) + } +} diff --git a/backend/cmd/export-content/main.go b/backend/cmd/export-content/main.go new file mode 100644 index 0000000..3d4588b --- /dev/null +++ b/backend/cmd/export-content/main.go @@ -0,0 +1,344 @@ +package main + +import ( + "bytes" + "context" + "encoding/json" + "flag" + "fmt" + "log" + "os" + "path/filepath" + + "git.godopu.com/lab/landing_page/backend/internal/config" + "git.godopu.com/lab/landing_page/backend/internal/db" + "git.godopu.com/lab/landing_page/backend/internal/repository" +) + +func marshalJSONNoEscapeHTML(data any) ([]byte, error) { + var buf bytes.Buffer + enc := json.NewEncoder(&buf) + enc.SetEscapeHTML(false) + enc.SetIndent("", " ") + if err := enc.Encode(data); err != nil { + return nil, err + } + return bytes.TrimRight(buf.Bytes(), "\n"), nil +} + +func formatTSFile(importStmt, exportConstName, typeAnnotation string, data any) ([]byte, error) { + jsonData, err := marshalJSONNoEscapeHTML(data) + if err != nil { + return nil, fmt.Errorf("marshal JSON: %w", err) + } + + header := "// AUTO-GENERATED by backend/cmd/export-content — DO NOT EDIT BY HAND\n" + content := fmt.Sprintf("%s%s\n\nexport const %s: %s = %s;\n", header, importStmt, exportConstName, typeAnnotation, string(jsonData)) + return []byte(content), nil +} + +func writeFileSafe(path string, data []byte) error { + return os.WriteFile(path, data, 0644) +} + +func main() { + config.LoadEnvFile() + defaultDB := "anl.db" + if envDB := os.Getenv("DB_PATH"); envDB != "" { + defaultDB = envDB + } + + dbPath := flag.String("db", defaultDB, "Path to SQLite database file") + targetDir := flag.String("out-dir", "../refer_landing_page/content", "Target content directory") + flag.Parse() + + log.Printf("Exporting content from SQLite (%s) to TypeScript files in %s...", *dbPath, *targetDir) + database, err := db.Connect(*dbPath) + if err != nil { + log.Fatalf("Failed to connect to database: %v", err) + } + defer database.Close() + + ctx := context.Background() + homeRepo := repository.NewHomeRepository(database) + membersRepo := repository.NewMembersRepository(database) + pubsRepo := repository.NewPublicationsRepository(database) + lecturesRepo := repository.NewLecturesRepository(database) + standardsRepo := repository.NewStandardizationRepository(database) + + // 1. Projects + projects, err := homeRepo.GetResearchProjects(ctx) + if err != nil { + log.Fatalf("Get research projects: %v", err) + } + type TSProject struct { + Slug string `json:"slug"` + Title string `json:"title"` + Abstract string `json:"abstract"` + Keywords []string `json:"keywords"` + StandardsTrack *string `json:"standardsTrack,omitempty"` + StandardsOrg *string `json:"standardsOrg,omitempty"` + Period *string `json:"period,omitempty"` + Deliverables []any `json:"deliverables"` + Funder *string `json:"funder,omitempty"` + } + var tsProjects []TSProject + for _, p := range projects { + tsProjects = append(tsProjects, TSProject{ + Slug: p.Slug, + Title: p.Title, + Abstract: p.Abstract, + Keywords: p.Keywords, + StandardsTrack: p.Organization, + StandardsOrg: p.StandardsOrg, + Period: p.Period, + Deliverables: []any{}, + Funder: p.Funder, + }) + } + pBytes, err := formatTSFile(`import { ResearchProject } from "./types";`, "researchProjects", "ResearchProject[]", tsProjects) + if err != nil { + log.Fatalf("Format projects.ts failed: %v", err) + } + if err := writeFileSafe(filepath.Join(*targetDir, "projects.ts"), pBytes); err != nil { + log.Fatalf("Write projects.ts failed: %v", err) + } + log.Println("✓ Exported projects.ts") + + // 2. Members & Alumni + members, err := membersRepo.GetMembers(ctx) + if err != nil { + log.Fatalf("Get members: %v", err) + } + type TSMember struct { + Ko string `json:"ko"` + En string `json:"en"` + Degree string `json:"degree"` + Affiliation *string `json:"affiliation,omitempty"` + } + var tsMembers []TSMember + for _, m := range members { + tsMembers = append(tsMembers, TSMember{ + Ko: m.NameKo, + En: m.NameEn, + Degree: m.Degree, + Affiliation: m.Affiliation, + }) + } + + alumni, err := membersRepo.GetAlumni(ctx) + if err != nil { + log.Fatalf("Get alumni: %v", err) + } + type TSAlumnus struct { + Ko string `json:"ko"` + En string `json:"en"` + Degree string `json:"degree"` + GraduatedAt string `json:"graduatedAt"` + Major *string `json:"major,omitempty"` + CurrentPosition *string `json:"currentPosition,omitempty"` + } + var tsAlumni []TSAlumnus + for _, a := range alumni { + tsAlumni = append(tsAlumni, TSAlumnus{ + Ko: a.NameKo, + En: a.NameEn, + Degree: a.Degree, + GraduatedAt: a.GraduatedAt, + Major: a.Major, + CurrentPosition: a.CurrentPosition, + }) + } + + mJSON, err := marshalJSONNoEscapeHTML(tsMembers) + if err != nil { + log.Fatalf("Marshal members failed: %v", err) + } + aJSON, err := marshalJSONNoEscapeHTML(tsAlumni) + if err != nil { + log.Fatalf("Marshal alumni failed: %v", err) + } + membersTS := fmt.Sprintf("// AUTO-GENERATED by backend/cmd/export-content — DO NOT EDIT BY HAND\nimport { Member, Alumnus } from \"./types\";\n\nexport const activeMembers: Member[] = %s;\n\nexport const alumni: Alumnus[] = %s;\n", string(mJSON), string(aJSON)) + if err := writeFileSafe(filepath.Join(*targetDir, "members.ts"), []byte(membersTS)); err != nil { + log.Fatalf("Write members.ts failed: %v", err) + } + log.Println("✓ Exported members.ts") + + // 3. Publications & Patents + pubs, err := pubsRepo.GetPublications(ctx, "") + if err != nil { + log.Fatalf("Get publications: %v", err) + } + type TSPublication struct { + Category string `json:"category"` + Title string `json:"title"` + Authors *string `json:"authors,omitempty"` + Venue string `json:"venue"` + Volume *string `json:"volume,omitempty"` + PublishedAt string `json:"publishedAt"` + KCI bool `json:"kci,omitempty"` + DOI *string `json:"doi,omitempty"` + IsHighlight bool `json:"isHighlight,omitempty"` + } + var tsPubs []TSPublication + for _, p := range pubs { + tsPubs = append(tsPubs, TSPublication{ + Category: p.Category, + Title: p.Title, + Authors: p.Authors, + Venue: p.Venue, + Volume: p.Volume, + PublishedAt: p.PublishedAt, + KCI: p.KCI, + DOI: p.DOI, + IsHighlight: p.IsHighlight, + }) + } + + patents, err := pubsRepo.GetPatents(ctx) + if err != nil { + log.Fatalf("Get patents: %v", err) + } + type TSPatent struct { + Category string `json:"category"` + Title string `json:"title"` + Inventors string `json:"inventors"` + ApplicationNo string `json:"applicationNo"` + ApplicationAt string `json:"applicationAt"` + RegistrationNo *string `json:"registrationNo,omitempty"` + RegistrationAt *string `json:"registrationAt,omitempty"` + Country string `json:"country"` + PublishedAt string `json:"publishedAt"` + } + var tsPatents []TSPatent + for _, pat := range patents { + tsPatents = append(tsPatents, TSPatent{ + Category: "patent", + Title: pat.Title, + Inventors: pat.Inventors, + ApplicationNo: pat.ApplicationNo, + ApplicationAt: pat.ApplicationAt, + RegistrationNo: pat.RegistrationNo, + RegistrationAt: pat.RegistrationAt, + Country: pat.Country, + PublishedAt: pat.PublishedAt, + }) + } + + pubsJSON, err := marshalJSONNoEscapeHTML(tsPubs) + if err != nil { + log.Fatalf("Marshal publications failed: %v", err) + } + patentsJSON, err := marshalJSONNoEscapeHTML(tsPatents) + if err != nil { + log.Fatalf("Marshal patents failed: %v", err) + } + pubsTS := fmt.Sprintf("// AUTO-GENERATED by backend/cmd/export-content — DO NOT EDIT BY HAND\nimport { Publication, Patent } from \"./types\";\n\nexport const publications: Publication[] = %s;\n\nexport const patents: Patent[] = %s;\n", string(pubsJSON), string(patentsJSON)) + if err := writeFileSafe(filepath.Join(*targetDir, "publications.ts"), []byte(pubsTS)); err != nil { + log.Fatalf("Write publications.ts failed: %v", err) + } + log.Println("✓ Exported publications.ts (with isHighlight metadata & unescaped HTML entities)") + + // 4. Lectures + semesters, err := lecturesRepo.GetSemestersWithCourses(ctx) + if err != nil { + log.Fatalf("Get semesters: %v", err) + } + type TSCourse struct { + Code string `json:"code"` + En string `json:"en"` + Note *string `json:"note,omitempty"` + } + type TSSemester struct { + Term string `json:"term"` + Year int `json:"year"` + Courses []TSCourse `json:"courses"` + } + var tsSemesters []TSSemester + for _, s := range semesters { + var tsCourses []TSCourse + for _, c := range s.Courses { + tsCourses = append(tsCourses, TSCourse{ + Code: c.Code, + En: c.NameEn, + Note: c.Note, + }) + } + tsSemesters = append(tsSemesters, TSSemester{ + Term: s.Term, + Year: s.Year, + Courses: tsCourses, + }) + } + lecturesBytes, err := formatTSFile(`import { Semester } from "./types";`, "semesters", "Semester[]", tsSemesters) + if err != nil { + log.Fatalf("Format lectures.ts failed: %v", err) + } + if err := writeFileSafe(filepath.Join(*targetDir, "lectures.ts"), lecturesBytes); err != nil { + log.Fatalf("Write lectures.ts failed: %v", err) + } + log.Println("✓ Exported lectures.ts") + + // 5. Standards + standards, err := standardsRepo.GetStandardsBodiesWithProjects(ctx) + if err != nil { + log.Fatalf("Get standards bodies: %v", err) + } + type TSDoc struct { + Title string `json:"title"` + Ref string `json:"ref"` + Status string `json:"status"` + PublishedAt *string `json:"publishedAt,omitempty"` + } + type TSStandardProject struct { + WG string `json:"wg"` + Name string `json:"name"` + Documents []TSDoc `json:"documents"` + } + type TSStandardsBody struct { + Org string `json:"org"` + Full string `json:"full"` + Scope string `json:"scope"` + Period string `json:"period"` + Role *string `json:"role,omitempty"` + Projects []TSStandardProject `json:"projects"` + } + var tsStandards []TSStandardsBody + for _, b := range standards { + var tsProjs []TSStandardProject + for _, p := range b.Projects { + var tsDocs []TSDoc + for _, d := range p.Documents { + tsDocs = append(tsDocs, TSDoc{ + Title: d.Title, + Ref: d.DocRef, + Status: d.Status, + PublishedAt: d.PublishedAt, + }) + } + tsProjs = append(tsProjs, TSStandardProject{ + WG: p.WG, + Name: p.Name, + Documents: tsDocs, + }) + } + tsStandards = append(tsStandards, TSStandardsBody{ + Org: b.Org, + Full: b.FullName, + Scope: b.Scope, + Period: b.Period, + Role: b.Role, + Projects: tsProjs, + }) + } + standardsBytes, err := formatTSFile(`import { StandardsBody } from "./types";`, "standardsBodies", "StandardsBody[]", tsStandards) + if err != nil { + log.Fatalf("Format standards.ts failed: %v", err) + } + if err := writeFileSafe(filepath.Join(*targetDir, "standards.ts"), standardsBytes); err != nil { + log.Fatalf("Write standards.ts failed: %v", err) + } + log.Println("✓ Exported standards.ts") + + log.Println("=== All content successfully exported from SQLite! ===") +} diff --git a/backend/cmd/seed/main.go b/backend/cmd/seed/main.go new file mode 100644 index 0000000..d0e93e0 --- /dev/null +++ b/backend/cmd/seed/main.go @@ -0,0 +1,345 @@ +package main + +import ( + "encoding/json" + "flag" + "fmt" + "log" + "os" + "path/filepath" + + "git.godopu.com/lab/landing_page/backend/internal/config" + "git.godopu.com/lab/landing_page/backend/internal/db" +) + +type SeedProject struct { + Slug string `json:"slug"` + Title string `json:"title"` + Abstract string `json:"abstract"` + Keywords []string `json:"keywords"` + StandardsTrack *string `json:"standardsTrack"` + StandardsOrg *string `json:"standardsOrg"` + Period *string `json:"period"` + Funder *string `json:"funder"` +} + +type SeedArea struct { + NameEn string `json:"name_en"` + NameKr *string `json:"name_kr"` + DisplayOrder int `json:"display_order"` +} + +type SeedMember struct { + NameKo string `json:"name_ko"` + NameEn string `json:"name_en"` + Degree string `json:"degree"` + Affiliation *string `json:"affiliation"` + Email *string `json:"email"` + IsAdvisor bool `json:"is_advisor"` + DisplayOrder int `json:"display_order"` +} + +type SeedAlumnus struct { + NameKo string `json:"name_ko"` + NameEn string `json:"name_en"` + Degree string `json:"degree"` + GraduatedAt string `json:"graduated_at"` + Major *string `json:"major"` + CurrentPosition *string `json:"current_position"` +} + +type SeedPublication struct { + Category string `json:"category"` + Title string `json:"title"` + Authors *string `json:"authors"` + Venue string `json:"venue"` + Volume *string `json:"volume"` + PublishedAt string `json:"published_at"` + KCI bool `json:"kci"` + DOI *string `json:"doi"` + IsHighlight bool `json:"is_highlight"` +} + +type SeedPatent struct { + Title string `json:"title"` + Inventors string `json:"inventors"` + ApplicationNo string `json:"application_no"` + ApplicationAt string `json:"application_at"` + RegistrationNo *string `json:"registration_no"` + RegistrationAt *string `json:"registration_at"` + Country string `json:"country"` + PublishedAt string `json:"published_at"` +} + +type SeedCourse struct { + Code string `json:"code"` + En string `json:"en"` + Note *string `json:"note"` +} + +type SeedSemester struct { + Term string `json:"term"` + Year int `json:"year"` + Courses []SeedCourse `json:"courses"` +} + +type SeedDoc struct { + Title string `json:"title"` + Ref string `json:"ref"` + Status string `json:"status"` + PublishedAt *string `json:"publishedAt"` +} + +type SeedStandardProject struct { + WG string `json:"wg"` + Name string `json:"name"` + Documents []SeedDoc `json:"documents"` +} + +type SeedStandardsBody struct { + Org string `json:"org"` + Full string `json:"full"` + Scope string `json:"scope"` + Period string `json:"period"` + Role *string `json:"role"` + Projects []SeedStandardProject `json:"projects"` +} + +func readJSONFile[T any](path string) (T, error) { + var result T + data, err := os.ReadFile(path) + if err != nil { + return result, fmt.Errorf("read file %s: %w", path, err) + } + if err := json.Unmarshal(data, &result); err != nil { + return result, fmt.Errorf("unmarshal %s: %w", path, err) + } + return result, nil +} + +func main() { + config.LoadEnvFile() + defaultDB := "anl.db" + if envDB := os.Getenv("DB_PATH"); envDB != "" { + defaultDB = envDB + } + + dbPath := flag.String("db", defaultDB, "SQLite database file path") + seedDir := flag.String("seed-dir", "seed/data", "Directory containing seed JSON files") + flag.Parse() + + log.Printf("Connecting to SQLite database at %s...", *dbPath) + database, err := db.Connect(*dbPath) + if err != nil { + log.Fatalf("Database connection failed: %v", err) + } + defer database.Close() + + log.Println("Applying schema migrations...") + if err := db.RunMigrations(database); err != nil { + log.Fatalf("Migration failed: %v", err) + } + + tx, err := database.Begin() + if err != nil { + log.Fatalf("Begin transaction failed: %v", err) + } + defer tx.Rollback() + + // Clear existing records in reverse FK order + tables := []string{ + "standard_documents", "standards_bodies", + "courses", "semesters", + "patents", "publications", + "alumni", "members", + "research_areas", "research_projects", + } + for _, t := range tables { + if _, err := tx.Exec("DELETE FROM " + t); err != nil { + log.Fatalf("Failed to clear table %s: %v", t, err) + } + } + + // 1. Research Projects + projects, err := readJSONFile[[]SeedProject](filepath.Join(*seedDir, "research_projects.json")) + if err != nil { + log.Fatalf("Failed to read research projects: %v", err) + } + for _, p := range projects { + kwJSON, _ := json.Marshal(p.Keywords) + _, err := tx.Exec(` + INSERT INTO research_projects (slug, title, abstract, keywords, organization, standards_org, period, funder) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + `, p.Slug, p.Title, p.Abstract, string(kwJSON), p.StandardsTrack, p.StandardsOrg, p.Period, p.Funder) + if err != nil { + log.Fatalf("Insert research project (%s) failed: %v", p.Slug, err) + } + } + + // 2. Research Areas + areas, err := readJSONFile[[]SeedArea](filepath.Join(*seedDir, "research_areas.json")) + if err != nil { + log.Fatalf("Failed to read research areas: %v", err) + } + for _, a := range areas { + _, err := tx.Exec(` + INSERT INTO research_areas (name_en, name_kr, display_order) + VALUES (?, ?, ?) + `, a.NameEn, a.NameKr, a.DisplayOrder) + if err != nil { + log.Fatalf("Insert research area failed: %v", err) + } + } + + // 3. Members + members, err := readJSONFile[[]SeedMember](filepath.Join(*seedDir, "members.json")) + if err != nil { + log.Fatalf("Failed to read members: %v", err) + } + for _, m := range members { + _, err := tx.Exec(` + INSERT INTO members (name_ko, name_en, degree, affiliation, email, is_advisor, display_order) + VALUES (?, ?, ?, ?, ?, ?, ?) + `, m.NameKo, m.NameEn, m.Degree, m.Affiliation, m.Email, m.IsAdvisor, m.DisplayOrder) + if err != nil { + log.Fatalf("Insert member (%s) failed: %v", m.NameEn, err) + } + } + + // 4. Alumni + alumni, err := readJSONFile[[]SeedAlumnus](filepath.Join(*seedDir, "alumni.json")) + if err != nil { + log.Fatalf("Failed to read alumni: %v", err) + } + for _, a := range alumni { + _, err := tx.Exec(` + INSERT INTO alumni (name_ko, name_en, degree, graduated_at, major, current_position) + VALUES (?, ?, ?, ?, ?, ?) + `, a.NameKo, a.NameEn, a.Degree, a.GraduatedAt, a.Major, a.CurrentPosition) + if err != nil { + log.Fatalf("Insert alumnus (%s) failed: %v", a.NameEn, err) + } + } + + // 5. Publications + pubs, err := readJSONFile[[]SeedPublication](filepath.Join(*seedDir, "publications.json")) + if err != nil { + log.Fatalf("Failed to read publications: %v", err) + } + for _, p := range pubs { + _, err := tx.Exec(` + INSERT INTO publications (category, title, authors, venue, volume, published_at, kci, doi, is_highlight) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + `, p.Category, p.Title, p.Authors, p.Venue, p.Volume, p.PublishedAt, p.KCI, p.DOI, p.IsHighlight) + if err != nil { + log.Fatalf("Insert publication (%s) failed: %v", p.Title, err) + } + } + + // 6. Patents + patents, err := readJSONFile[[]SeedPatent](filepath.Join(*seedDir, "patents.json")) + if err != nil { + log.Fatalf("Failed to read patents: %v", err) + } + for _, pat := range patents { + _, err := tx.Exec(` + INSERT INTO patents (title, inventors, application_no, application_at, registration_no, registration_at, country, published_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + `, pat.Title, pat.Inventors, pat.ApplicationNo, pat.ApplicationAt, pat.RegistrationNo, pat.RegistrationAt, pat.Country, pat.PublishedAt) + if err != nil { + log.Fatalf("Insert patent (%s) failed: %v", pat.Title, err) + } + } + + // 7. Semesters & Courses + semesters, err := readJSONFile[[]SeedSemester](filepath.Join(*seedDir, "lectures.json")) + if err != nil { + log.Fatalf("Failed to read lectures: %v", err) + } + for _, s := range semesters { + res, err := tx.Exec(`INSERT INTO semesters (year, term) VALUES (?, ?)`, s.Year, s.Term) + if err != nil { + log.Fatalf("Insert semester (%d %s) failed: %v", s.Year, s.Term, err) + } + semID, _ := res.LastInsertId() + + for cIdx, c := range s.Courses { + _, err := tx.Exec(` + INSERT INTO courses (semester_id, code, name_en, name_kr, note, display_order) + VALUES (?, ?, ?, ?, ?, ?) + `, semID, c.Code, c.En, nil, c.Note, cIdx+1) + if err != nil { + log.Fatalf("Insert course (%s) failed: %v", c.Code, err) + } + } + } + + // 8. Standards Bodies & Documents + standards, err := readJSONFile[[]SeedStandardsBody](filepath.Join(*seedDir, "standards.json")) + if err != nil { + log.Fatalf("Failed to read standards: %v", err) + } + for bIdx, b := range standards { + res, err := tx.Exec(` + INSERT INTO standards_bodies (org, full_name, scope, period, role, display_order) + VALUES (?, ?, ?, ?, ?, ?) + `, b.Org, b.Full, b.Scope, b.Period, b.Role, bIdx+1) + if err != nil { + log.Fatalf("Insert standards body (%s) failed: %v", b.Org, err) + } + bodyID, _ := res.LastInsertId() + + for _, p := range b.Projects { + for _, d := range p.Documents { + _, err := tx.Exec(` + INSERT INTO standard_documents (body_id, wg, project_name, title, doc_ref, status, published_at) + VALUES (?, ?, ?, ?, ?, ?, ?) + `, bodyID, p.WG, p.Name, d.Title, d.Ref, d.Status, d.PublishedAt) + if err != nil { + log.Fatalf("Insert standard document (%s) failed: %v", d.Title, err) + } + } + } + } + + if err := tx.Commit(); err != nil { + log.Fatalf("Transaction commit failed: %v", err) + } + log.Println("Transaction committed successfully.") + + // Verify Counts + log.Println("=== Verifying Seeding Counts ===") + checkCount := func(table string, expected int) { + var cnt int + if err := database.QueryRow("SELECT COUNT(*) FROM " + table).Scan(&cnt); err != nil { + log.Fatalf("Count check failed for %s: %v", table, err) + } + if cnt != expected { + log.Fatalf("Count mismatch for %s: expected %d, got %d", table, expected, cnt) + } + log.Printf("✓ %-20s : %3d rows (matches expected)", table, cnt) + } + + checkCount("research_projects", 3) + checkCount("research_areas", 14) + checkCount("members", 16) + checkCount("alumni", 60) + checkCount("publications", 148) + checkCount("patents", 75) + checkCount("semesters", 45) + checkCount("courses", 132) + checkCount("standards_bodies", 6) + checkCount("standard_documents", 44) + + // Explicit highlight assertion + var hlCount int + if err := database.QueryRow("SELECT COUNT(*) FROM publications WHERE is_highlight = 1").Scan(&hlCount); err != nil { + log.Fatalf("Highlight count query failed: %v", err) + } + if hlCount != 5 { + log.Fatalf("Highlight count mismatch: expected exactly 5, got %d", hlCount) + } + log.Printf("✓ %-20s : %3d rows (exactly 5 highlights)", "publications(highlight)", hlCount) + + log.Println("=== Seeding & Verification Completed Successfully! ===") +} diff --git a/backend/go.mod b/backend/go.mod new file mode 100644 index 0000000..d2220c8 --- /dev/null +++ b/backend/go.mod @@ -0,0 +1,49 @@ +module git.godopu.com/lab/landing_page/backend + +go 1.26.3 + +require ( + github.com/gin-gonic/gin v1.12.0 + github.com/stretchr/testify v1.12.1 + modernc.org/sqlite v1.57.0 +) + +require ( + github.com/bytedance/gopkg v0.1.4 // indirect + github.com/bytedance/sonic v1.15.2 // indirect + github.com/bytedance/sonic/loader v0.5.2 // indirect + github.com/cloudwego/base64x v0.1.7 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/gabriel-vasile/mimetype v1.4.15 // indirect + github.com/gin-contrib/sse v1.1.1 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.30.3 // indirect + github.com/goccy/go-json v0.10.6 // indirect + github.com/goccy/go-yaml v1.19.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.4.0 // indirect + github.com/leodido/go-urn v1.5.0 // indirect + github.com/mattn/go-isatty v0.0.24 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/ncruces/go-strftime v1.0.0 // indirect + github.com/pelletier/go-toml/v2 v2.4.3 // indirect + github.com/quic-go/qpack v0.6.0 // indirect + github.com/quic-go/quic-go v0.61.0 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.3.2 // indirect + go.mongodb.org/mongo-driver/v2 v2.8.0 // indirect + go.yaml.in/yaml/v3 v3.0.5 // indirect + golang.org/x/arch v0.30.0 // indirect + golang.org/x/crypto v0.55.0 // indirect + golang.org/x/net v0.58.0 // indirect + golang.org/x/sys v0.47.0 // indirect + golang.org/x/text v0.41.0 // indirect + google.golang.org/protobuf v1.36.12 // indirect + modernc.org/libc v1.75.4 // indirect + modernc.org/mathutil v1.7.1 // indirect + modernc.org/memory v1.12.1 // indirect +) diff --git a/backend/go.sum b/backend/go.sum new file mode 100644 index 0000000..1b3da0c --- /dev/null +++ b/backend/go.sum @@ -0,0 +1,136 @@ +github.com/bytedance/gopkg v0.1.4 h1:oZnQwnX82KAIWb7033bEwtxvTqXcYMxDBaQxo5JJHWM= +github.com/bytedance/gopkg v0.1.4/go.mod h1:v1zWfPm21Fb+OsyXN2VAHdL6TBb2L88anLQgdyje6R4= +github.com/bytedance/sonic v1.15.2 h1:90H+rcF/FwLXwfB1cudOLq/je83n683Utf4Cbp0xHCo= +github.com/bytedance/sonic v1.15.2/go.mod h1:mT2NbXunuaEbnZ+mRIX/vYqKISmgEuHFDI4UzmKx2SA= +github.com/bytedance/sonic/loader v0.5.2 h1:0QtP1gevc1OZ6/H8Lb9BRZiCXd1Ftjd3OKuj1T1lBIo= +github.com/bytedance/sonic/loader v0.5.2/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= +github.com/cloudwego/base64x v0.1.7 h1:NppS+Fgzg5ovhn4NkUXaDT3x9jldgH5ToMCqzBSi2zI= +github.com/cloudwego/base64x v0.1.7/go.mod h1:Cu1PV9zfrSf7ET2tIbWbbEy7jO7HHJ13q4X2SQ8aWYg= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/gabriel-vasile/mimetype v1.4.15 h1:05iP/CYtZ/w455R/KZM6rZ5ieAdh99UPtd+d3YzLmaI= +github.com/gabriel-vasile/mimetype v1.4.15/go.mod h1:azpTcoLcDZRNgFou5j+APrqQx9HqVPWa6ijYQIIVswQ= +github.com/gin-contrib/sse v1.1.1 h1:uGYpNwTacv5R68bSGMapo62iLTRa9l5zxGCps4hK6ko= +github.com/gin-contrib/sse v1.1.1/go.mod h1:QXzuVkA0YO7o/gun03UI1Q+FTI8ZV/n5t03kIQAI89s= +github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8= +github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.30.3 h1:4MU6YkEwx7GbcPJOZxrtbu+QfF3pJLJuaYTeAH0DYy8= +github.com/go-playground/validator/v10 v10.30.3/go.mod h1:4Axh7oCNGcoGkqLoE4YWt6n20mcEIsPRlB7vPk3lpyc= +github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU= +github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= +github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 h1:LMLX+LgTNWpfvCBdFebv6EsYotImrt/Ppc5cXIriCSo= +github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw= +github.com/klauspost/cpuid/v2 v2.4.0/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU= +github.com/leodido/go-urn v1.5.0 h1:pLqT2kq1zpHW/1D18QMjMpdtX7cekxqtJJjg5ANyWw0= +github.com/leodido/go-urn v1.5.0/go.mod h1:9BORnCDhdPBJNDEX+w1bJisa8yOKYi116VeO96s4ifE= +github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI= +github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w= +github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY= +github.com/pelletier/go-toml/v2 v2.4.3/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/quic-go/go-ossfuzz-seeds v0.1.0 h1:APacT+iIaNF6fd8AGEiN3bT/Jtkd2jz4v4TzM7MFjy0= +github.com/quic-go/go-ossfuzz-seeds v0.1.0/go.mod h1:3IOHRbJIc+L6YKMwfDtJAM9Vj9k0YY4muhuyUYk5tbk= +github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= +github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= +github.com/quic-go/quic-go v0.61.0 h1:ui88A53s8MSVYLC56en0KQ17HARk+9986Dn0SBfKNvA= +github.com/quic-go/quic-go v0.61.0/go.mod h1:9So2anK4Tp22URSQq00k+Vo2PNkle96ycDPDHL4s9vs= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= +github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.3.2 h1:zkEASHHyEClGeURfgNT9PJZVfAbs9oEX9QXggwWNJbc= +github.com/ugorji/go/codec v1.3.2/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= +go.mongodb.org/mongo-driver/v2 v2.8.0 h1:CxWDGQYY8QQwNjAl/aq2sfWakdnWZynnqJ9F4DhHbP8= +go.mongodb.org/mongo-driver/v2 v2.8.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= +go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= +go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= +golang.org/x/arch v0.30.0 h1:sB9h+1gRGa2+LauFSV0tm8bK1J2yo1bx6/Uyi/P6DTU= +golang.org/x/arch v0.30.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8= +golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= +golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= +golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= +golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= +golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= +golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= +golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= +golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= +golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= +golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE= +golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk= +google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc= +google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +modernc.org/cc/v4 v4.29.2 h1:h6+9ciCnPKutf4I03CvheAvDLX7+IHlqR6Iy6J+cgd8= +modernc.org/cc/v4 v4.29.2/go.mod h1:OnovgIhbbMXMu1aISnJ0wvVD1KnW+cAUJkIrAWh+kVI= +modernc.org/ccgo/v4 v4.35.0 h1:F+TUsmw09QxLzmi3aeYYGxjAXarmZaKgj3mKQHNaA8w= +modernc.org/ccgo/v4 v4.35.0/go.mod h1:qrVGs9S3Sr2Ztcg9ve+kTAYMp5a3YvWjo+SoN06kJ5I= +modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM= +modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU= +modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= +modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= +modernc.org/gc/v3 v3.1.5 h1:21ldfPfRYE31Tb7B3mwAK8gy1AxP4+dKjrOQPfqakoc= +modernc.org/gc/v3 v3.1.5/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY= +modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks= +modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI= +modernc.org/libc v1.75.4 h1:EHQJNYDC6LiDIOqM76862xe4frbDc7IzEOZTtGxZV8Q= +modernc.org/libc v1.75.4/go.mod h1:bO5o2ztHxBb2rjz0PgdHN0sSMw57CgxGFLZ3Qd/QpVQ= +modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= +modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= +modernc.org/memory v1.12.1 h1:nFMiWrpStgZczNl6XI9GnIk/rWhYIyHGUaR04pGbp9g= +modernc.org/memory v1.12.1/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= +modernc.org/opt v0.2.0 h1:tGyef5ApycA7FSEOMraay9SaTk5zmbx7Tu+cJs4QKZg= +modernc.org/opt v0.2.0/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= +modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= +modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= +modernc.org/sqlite v1.57.0 h1:qNQP6xnx5M0ISNtlnxoOX0+cD5bJ0/gr9aMmndFczzg= +modernc.org/sqlite v1.57.0/go.mod h1:yCJ2cmAaIkHQ25oXWrF8H4O1lIfPYPR26yCEDj2P3pQ= +modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= +modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go new file mode 100644 index 0000000..432faab --- /dev/null +++ b/backend/internal/config/config.go @@ -0,0 +1,104 @@ +package config + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +// Config holds all server configuration derived from environment variables and flags. +type Config struct { + Port int + Host string + DBPath string + GinMode string + CORSAllowOrigins string + AutoMigrate bool +} + +// LoadEnvFile reads a simple .env file if it exists and loads variables into environment without overriding existing ones. +func LoadEnvFile(filenames ...string) { + if len(filenames) == 0 { + filenames = []string{".env", "../.env"} + } + + for _, filename := range filenames { + file, err := os.Open(filename) + if err != nil { + continue + } + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if line == "" || strings.HasPrefix(line, "#") { + continue + } + + parts := strings.SplitN(line, "=", 2) + if len(parts) != 2 { + continue + } + + key := strings.TrimSpace(parts[0]) + val := strings.TrimSpace(parts[1]) + // Strip optional surrounding quotes + val = strings.Trim(val, `"'`) + + // Only set if not already present in environment + if _, exists := os.LookupEnv(key); !exists { + _ = os.Setenv(key, val) + } + } + _ = file.Close() + } +} + +// Load reads and parses all configuration settings from the environment. +func Load() *Config { + LoadEnvFile() + + cfg := &Config{ + Port: 8080, + Host: "0.0.0.0", + DBPath: "anl.db", + GinMode: "release", + CORSAllowOrigins: "*", + AutoMigrate: true, + } + + if portStr := os.Getenv("PORT"); portStr != "" { + if p, err := strconv.Atoi(portStr); err == nil && p > 0 { + cfg.Port = p + } + } + + if hostStr := os.Getenv("HOST"); hostStr != "" { + cfg.Host = hostStr + } + + if dbPathStr := os.Getenv("DB_PATH"); dbPathStr != "" { + cfg.DBPath = dbPathStr + } + + if ginModeStr := os.Getenv("GIN_MODE"); ginModeStr != "" { + cfg.GinMode = ginModeStr + } + + if corsStr := os.Getenv("CORS_ALLOW_ORIGINS"); corsStr != "" { + cfg.CORSAllowOrigins = corsStr + } + + if autoMigrateStr := os.Getenv("AUTO_MIGRATE"); autoMigrateStr != "" { + cfg.AutoMigrate = strings.ToLower(autoMigrateStr) != "false" && autoMigrateStr != "0" + } + + return cfg +} + +// Address returns the combined host:port address string. +func (c *Config) Address() string { + return fmt.Sprintf("%s:%d", c.Host, c.Port) +} diff --git a/backend/internal/config/config_test.go b/backend/internal/config/config_test.go new file mode 100644 index 0000000..724f6ea --- /dev/null +++ b/backend/internal/config/config_test.go @@ -0,0 +1,80 @@ +package config_test + +import ( + "os" + "path/filepath" + "testing" + + "git.godopu.com/lab/landing_page/backend/internal/config" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestConfigDefaults(t *testing.T) { + // Clear env + _ = os.Unsetenv("PORT") + _ = os.Unsetenv("HOST") + _ = os.Unsetenv("DB_PATH") + _ = os.Unsetenv("GIN_MODE") + _ = os.Unsetenv("CORS_ALLOW_ORIGINS") + _ = os.Unsetenv("AUTO_MIGRATE") + + cfg := config.Load() + assert.Equal(t, 8080, cfg.Port) + assert.Equal(t, "0.0.0.0", cfg.Host) + assert.Equal(t, "anl.db", cfg.DBPath) + assert.Equal(t, "release", cfg.GinMode) + assert.Equal(t, "*", cfg.CORSAllowOrigins) + assert.True(t, cfg.AutoMigrate) + assert.Equal(t, "0.0.0.0:8080", cfg.Address()) +} + +func TestConfigEnvOverrides(t *testing.T) { + _ = os.Setenv("PORT", "9090") + _ = os.Setenv("HOST", "127.0.0.1") + _ = os.Setenv("DB_PATH", "/tmp/custom.db") + _ = os.Setenv("GIN_MODE", "debug") + _ = os.Setenv("CORS_ALLOW_ORIGINS", "https://anl.knu.ac.kr") + _ = os.Setenv("AUTO_MIGRATE", "false") + defer func() { + _ = os.Unsetenv("PORT") + _ = os.Unsetenv("HOST") + _ = os.Unsetenv("DB_PATH") + _ = os.Unsetenv("GIN_MODE") + _ = os.Unsetenv("CORS_ALLOW_ORIGINS") + _ = os.Unsetenv("AUTO_MIGRATE") + }() + + cfg := config.Load() + assert.Equal(t, 9090, cfg.Port) + assert.Equal(t, "127.0.0.1", cfg.Host) + assert.Equal(t, "/tmp/custom.db", cfg.DBPath) + assert.Equal(t, "debug", cfg.GinMode) + assert.Equal(t, "https://anl.knu.ac.kr", cfg.CORSAllowOrigins) + assert.False(t, cfg.AutoMigrate) + assert.Equal(t, "127.0.0.1:9090", cfg.Address()) +} + +func TestLoadEnvFile(t *testing.T) { + tmpDir := t.TempDir() + envPath := filepath.Join(tmpDir, ".env") + envContent := ` +# Sample comment +TEST_CUSTOM_KEY="hello_world" +TEST_PORT_KEY=8888 +INVALID_LINE_WITHOUT_EQUALS +` + err := os.WriteFile(envPath, []byte(envContent), 0644) + require.NoError(t, err) + + _ = os.Unsetenv("TEST_CUSTOM_KEY") + _ = os.Unsetenv("TEST_PORT_KEY") + defer func() { + _ = os.Unsetenv("TEST_CUSTOM_KEY") + _ = os.Unsetenv("TEST_PORT_KEY") + }() + + config.LoadEnvFile(envPath) + assert.Equal(t, "hello_world", os.Getenv("TEST_CUSTOM_KEY")) + assert.Equal(t, "8888", os.Getenv("TEST_PORT_KEY")) +} diff --git a/backend/internal/db/db.go b/backend/internal/db/db.go new file mode 100644 index 0000000..6ae0aae --- /dev/null +++ b/backend/internal/db/db.go @@ -0,0 +1,50 @@ +package db + +import ( + "database/sql" + _ "embed" + "fmt" + "strings" + + _ "modernc.org/sqlite" +) + +//go:embed migrations/000001_init.up.sql +var initMigrationUp string + +//go:embed migrations/000001_init.down.sql +var initMigrationDown string + +// Connect opens an SQLite database connection with appropriate pragmas +func Connect(dbPath string) (*sql.DB, error) { + dsn := dbPath + if !strings.Contains(dsn, "?") { + dsn += "?_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)&_pragma=busy_timeout(5000)" + } + db, err := sql.Open("sqlite", dsn) + if err != nil { + return nil, fmt.Errorf("failed to open database: %w", err) + } + + if err := db.Ping(); err != nil { + return nil, fmt.Errorf("failed to ping database: %w", err) + } + + return db, nil +} + +// RunMigrations applies up migrations +func RunMigrations(db *sql.DB) error { + if _, err := db.Exec(initMigrationUp); err != nil { + return fmt.Errorf("failed to apply migration up: %w", err) + } + return nil +} + +// RollbackMigrations applies down migrations +func RollbackMigrations(db *sql.DB) error { + if _, err := db.Exec(initMigrationDown); err != nil { + return fmt.Errorf("failed to apply migration down: %w", err) + } + return nil +} diff --git a/backend/internal/db/migrations/000001_init.down.sql b/backend/internal/db/migrations/000001_init.down.sql new file mode 100644 index 0000000..7592fb3 --- /dev/null +++ b/backend/internal/db/migrations/000001_init.down.sql @@ -0,0 +1,10 @@ +DROP TABLE IF EXISTS standard_documents; +DROP TABLE IF EXISTS standards_bodies; +DROP TABLE IF EXISTS courses; +DROP TABLE IF EXISTS semesters; +DROP TABLE IF EXISTS patents; +DROP TABLE IF EXISTS publications; +DROP TABLE IF EXISTS alumni; +DROP TABLE IF EXISTS members; +DROP TABLE IF EXISTS research_areas; +DROP TABLE IF EXISTS research_projects; diff --git a/backend/internal/db/migrations/000001_init.up.sql b/backend/internal/db/migrations/000001_init.up.sql new file mode 100644 index 0000000..3c75cc5 --- /dev/null +++ b/backend/internal/db/migrations/000001_init.up.sql @@ -0,0 +1,114 @@ +PRAGMA foreign_keys = ON; + +CREATE TABLE IF NOT EXISTS research_projects ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + slug TEXT NOT NULL UNIQUE, + title TEXT NOT NULL, + abstract TEXT NOT NULL, + keywords TEXT NOT NULL DEFAULT '[]', + organization TEXT, + standards_org TEXT, + period TEXT, + funder TEXT, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE IF NOT EXISTS research_areas ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name_en TEXT NOT NULL, + name_kr TEXT, + display_order INTEGER NOT NULL DEFAULT 0 +); + +CREATE TABLE IF NOT EXISTS members ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name_ko TEXT NOT NULL, + name_en TEXT NOT NULL, + degree TEXT NOT NULL CHECK (degree IN ('Professor','PhD','PhDCandidate','PhDStudent','MSCandidate','MSStudent')), + affiliation TEXT, + email TEXT, + is_advisor BOOLEAN NOT NULL DEFAULT 0, + display_order INTEGER NOT NULL DEFAULT 0, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE IF NOT EXISTS alumni ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name_ko TEXT NOT NULL, + name_en TEXT NOT NULL, + degree TEXT NOT NULL CHECK (degree IN ('PhD','MS')), + graduated_at TEXT NOT NULL, + major TEXT, + current_position TEXT, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE IF NOT EXISTS publications ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + category TEXT NOT NULL CHECK (category IN ('intl-journal-conf','domestic-journal-conf')), + title TEXT NOT NULL, + authors TEXT, + venue TEXT NOT NULL, + volume TEXT, + published_at TEXT NOT NULL, + kci BOOLEAN NOT NULL DEFAULT 0, + doi TEXT, + is_highlight BOOLEAN NOT NULL DEFAULT 0, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); +CREATE INDEX IF NOT EXISTS idx_publications_category ON publications(category); +CREATE INDEX IF NOT EXISTS idx_publications_highlight ON publications(is_highlight) WHERE is_highlight = 1; + +CREATE TABLE IF NOT EXISTS patents ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + title TEXT NOT NULL, + inventors TEXT NOT NULL, + application_no TEXT NOT NULL, + application_at TEXT NOT NULL, + registration_no TEXT, + registration_at TEXT, + country TEXT NOT NULL, + published_at TEXT NOT NULL, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE IF NOT EXISTS semesters ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + year INTEGER NOT NULL, + term TEXT NOT NULL CHECK (term IN ('Spring','Fall')), + UNIQUE(year, term) +); + +CREATE TABLE IF NOT EXISTS courses ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + semester_id INTEGER NOT NULL REFERENCES semesters(id) ON DELETE CASCADE, + code TEXT NOT NULL, + name_en TEXT NOT NULL, + name_kr TEXT, + note TEXT, + display_order INTEGER NOT NULL DEFAULT 0 +); +CREATE INDEX IF NOT EXISTS idx_courses_semester ON courses(semester_id); + +CREATE TABLE IF NOT EXISTS standards_bodies ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + org TEXT NOT NULL, + full_name TEXT NOT NULL, + scope TEXT NOT NULL CHECK (scope IN ('international','domestic')), + period TEXT NOT NULL, + role TEXT, + display_order INTEGER NOT NULL DEFAULT 0 +); + +CREATE TABLE IF NOT EXISTS standard_documents ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + body_id INTEGER NOT NULL REFERENCES standards_bodies(id) ON DELETE CASCADE, + wg TEXT NOT NULL, + project_name TEXT NOT NULL, + title TEXT NOT NULL, + doc_ref TEXT NOT NULL, + status TEXT NOT NULL CHECK (status IN ('IS','TS','TR','CDV','WDTR','InProgress')), + published_at TEXT +); +CREATE INDEX IF NOT EXISTS idx_stddocs_body ON standard_documents(body_id); diff --git a/backend/internal/handlers/home.go b/backend/internal/handlers/home.go new file mode 100644 index 0000000..c7b0e99 --- /dev/null +++ b/backend/internal/handlers/home.go @@ -0,0 +1,42 @@ +package handlers + +import ( + "git.godopu.com/lab/landing_page/backend/internal/httpx" + "git.godopu.com/lab/landing_page/backend/internal/repository" + "github.com/gin-gonic/gin" +) + +type HomeHandler struct { + repo *repository.HomeRepository +} + +func NewHomeHandler(repo *repository.HomeRepository) *HomeHandler { + return &HomeHandler{repo: repo} +} + +func (h *HomeHandler) GetResearchProjects(c *gin.Context) { + projects, err := h.repo.GetResearchProjects(c.Request.Context()) + if err != nil { + httpx.InternalServerError(c, "Failed to retrieve research projects: "+err.Error()) + return + } + httpx.OK(c, projects) +} + +func (h *HomeHandler) GetResearchAreas(c *gin.Context) { + areas, err := h.repo.GetResearchAreas(c.Request.Context()) + if err != nil { + httpx.InternalServerError(c, "Failed to retrieve research areas: "+err.Error()) + return + } + httpx.OK(c, areas) +} + +func (h *HomeHandler) GetStatsSummary(c *gin.Context) { + stats, err := h.repo.GetStatsSummary(c.Request.Context()) + if err != nil { + httpx.InternalServerError(c, "Failed to retrieve statistics summary: "+err.Error()) + return + } + httpx.OK(c, stats) +} diff --git a/backend/internal/handlers/lectures.go b/backend/internal/handlers/lectures.go new file mode 100644 index 0000000..1b4ab83 --- /dev/null +++ b/backend/internal/handlers/lectures.go @@ -0,0 +1,24 @@ +package handlers + +import ( + "git.godopu.com/lab/landing_page/backend/internal/httpx" + "git.godopu.com/lab/landing_page/backend/internal/repository" + "github.com/gin-gonic/gin" +) + +type LecturesHandler struct { + repo *repository.LecturesRepository +} + +func NewLecturesHandler(repo *repository.LecturesRepository) *LecturesHandler { + return &LecturesHandler{repo: repo} +} + +func (h *LecturesHandler) GetSemesters(c *gin.Context) { + semesters, err := h.repo.GetSemestersWithCourses(c.Request.Context()) + if err != nil { + httpx.InternalServerError(c, "Failed to retrieve semesters: "+err.Error()) + return + } + httpx.OK(c, semesters) +} diff --git a/backend/internal/handlers/members.go b/backend/internal/handlers/members.go new file mode 100644 index 0000000..949e253 --- /dev/null +++ b/backend/internal/handlers/members.go @@ -0,0 +1,33 @@ +package handlers + +import ( + "git.godopu.com/lab/landing_page/backend/internal/httpx" + "git.godopu.com/lab/landing_page/backend/internal/repository" + "github.com/gin-gonic/gin" +) + +type MembersHandler struct { + repo *repository.MembersRepository +} + +func NewMembersHandler(repo *repository.MembersRepository) *MembersHandler { + return &MembersHandler{repo: repo} +} + +func (h *MembersHandler) GetMembers(c *gin.Context) { + members, err := h.repo.GetMembers(c.Request.Context()) + if err != nil { + httpx.InternalServerError(c, "Failed to retrieve members: "+err.Error()) + return + } + httpx.OK(c, members) +} + +func (h *MembersHandler) GetAlumni(c *gin.Context) { + alumni, err := h.repo.GetAlumni(c.Request.Context()) + if err != nil { + httpx.InternalServerError(c, "Failed to retrieve alumni: "+err.Error()) + return + } + httpx.OK(c, alumni) +} diff --git a/backend/internal/handlers/publications.go b/backend/internal/handlers/publications.go new file mode 100644 index 0000000..e797d6d --- /dev/null +++ b/backend/internal/handlers/publications.go @@ -0,0 +1,48 @@ +package handlers + +import ( + "git.godopu.com/lab/landing_page/backend/internal/httpx" + "git.godopu.com/lab/landing_page/backend/internal/repository" + "github.com/gin-gonic/gin" +) + +type PublicationsHandler struct { + repo *repository.PublicationsRepository +} + +func NewPublicationsHandler(repo *repository.PublicationsRepository) *PublicationsHandler { + return &PublicationsHandler{repo: repo} +} + +func (h *PublicationsHandler) GetPublications(c *gin.Context) { + category := c.Query("category") + if category != "" && category != "intl-journal-conf" && category != "domestic-journal-conf" { + httpx.BadRequest(c, "Invalid category parameter: must be 'intl-journal-conf' or 'domestic-journal-conf'") + return + } + + pubs, err := h.repo.GetPublications(c.Request.Context(), category) + if err != nil { + httpx.InternalServerError(c, "Failed to retrieve publications: "+err.Error()) + return + } + httpx.OK(c, pubs) +} + +func (h *PublicationsHandler) GetHighlights(c *gin.Context) { + highlights, err := h.repo.GetHighlights(c.Request.Context()) + if err != nil { + httpx.InternalServerError(c, "Failed to retrieve highlights: "+err.Error()) + return + } + httpx.OK(c, highlights) +} + +func (h *PublicationsHandler) GetPatents(c *gin.Context) { + patents, err := h.repo.GetPatents(c.Request.Context()) + if err != nil { + httpx.InternalServerError(c, "Failed to retrieve patents: "+err.Error()) + return + } + httpx.OK(c, patents) +} diff --git a/backend/internal/handlers/standardization.go b/backend/internal/handlers/standardization.go new file mode 100644 index 0000000..7ae949f --- /dev/null +++ b/backend/internal/handlers/standardization.go @@ -0,0 +1,24 @@ +package handlers + +import ( + "git.godopu.com/lab/landing_page/backend/internal/httpx" + "git.godopu.com/lab/landing_page/backend/internal/repository" + "github.com/gin-gonic/gin" +) + +type StandardizationHandler struct { + repo *repository.StandardizationRepository +} + +func NewStandardizationHandler(repo *repository.StandardizationRepository) *StandardizationHandler { + return &StandardizationHandler{repo: repo} +} + +func (h *StandardizationHandler) GetStandardsBodies(c *gin.Context) { + bodies, err := h.repo.GetStandardsBodiesWithProjects(c.Request.Context()) + if err != nil { + httpx.InternalServerError(c, "Failed to retrieve standards bodies: "+err.Error()) + return + } + httpx.OK(c, bodies) +} diff --git a/backend/internal/httpx/response.go b/backend/internal/httpx/response.go new file mode 100644 index 0000000..a2b8801 --- /dev/null +++ b/backend/internal/httpx/response.go @@ -0,0 +1,45 @@ +package httpx + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +type ErrorDetail struct { + Message string `json:"message"` +} + +type ErrorResponse struct { + Error ErrorDetail `json:"error"` +} + +type SuccessResponse struct { + Data any `json:"data"` +} + +func OK(c *gin.Context, data any) { + c.JSON(http.StatusOK, SuccessResponse{ + Data: data, + }) +} + +func Error(c *gin.Context, status int, msg string) { + c.JSON(status, ErrorResponse{ + Error: ErrorDetail{ + Message: msg, + }, + }) +} + +func BadRequest(c *gin.Context, msg string) { + Error(c, http.StatusBadRequest, msg) +} + +func NotFound(c *gin.Context, msg string) { + Error(c, http.StatusNotFound, msg) +} + +func InternalServerError(c *gin.Context, msg string) { + Error(c, http.StatusInternalServerError, msg) +} diff --git a/backend/internal/models/home.go b/backend/internal/models/home.go new file mode 100644 index 0000000..656a8cb --- /dev/null +++ b/backend/internal/models/home.go @@ -0,0 +1,30 @@ +package models + +import "time" + +type ResearchProject struct { + ID int `json:"id"` + Slug string `json:"slug"` + Title string `json:"title"` + Abstract string `json:"abstract"` + Keywords []string `json:"keywords"` + Organization *string `json:"organization,omitempty"` + StandardsOrg *string `json:"standards_org,omitempty"` + Period *string `json:"period,omitempty"` + Funder *string `json:"funder,omitempty"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +type ResearchArea struct { + ID int `json:"id"` + NameEn string `json:"name_en"` + NameKr *string `json:"name_kr,omitempty"` + DisplayOrder int `json:"display_order"` +} + +type StatsSummary struct { + IntlPublications int `json:"intl_publications"` + StandardizationDocs int `json:"standardization_docs"` + Patents int `json:"patents"` +} diff --git a/backend/internal/models/lectures.go b/backend/internal/models/lectures.go new file mode 100644 index 0000000..89679f8 --- /dev/null +++ b/backend/internal/models/lectures.go @@ -0,0 +1,24 @@ +package models + +type Course struct { + ID int `json:"id"` + SemesterID int `json:"semester_id"` + Code string `json:"code"` + NameEn string `json:"name_en"` + NameKr *string `json:"name_kr,omitempty"` + Note *string `json:"note,omitempty"` + DisplayOrder int `json:"display_order"` +} + +type Semester struct { + ID int `json:"id"` + Year int `json:"year"` + Term string `json:"term"` +} + +type SemesterWithCourses struct { + ID int `json:"id"` + Year int `json:"year"` + Term string `json:"term"` + Courses []Course `json:"courses"` +} diff --git a/backend/internal/models/members.go b/backend/internal/models/members.go new file mode 100644 index 0000000..26e4884 --- /dev/null +++ b/backend/internal/models/members.go @@ -0,0 +1,26 @@ +package models + +import "time" + +type Member struct { + ID int `json:"id"` + NameKo string `json:"name_ko"` + NameEn string `json:"name_en"` + Degree string `json:"degree"` + Affiliation *string `json:"affiliation,omitempty"` + Email *string `json:"email,omitempty"` + IsAdvisor bool `json:"is_advisor"` + DisplayOrder int `json:"display_order"` + CreatedAt time.Time `json:"created_at"` +} + +type Alumnus struct { + ID int `json:"id"` + NameKo string `json:"name_ko"` + NameEn string `json:"name_en"` + Degree string `json:"degree"` + GraduatedAt string `json:"graduated_at"` + Major *string `json:"major,omitempty"` + CurrentPosition *string `json:"current_position,omitempty"` + CreatedAt time.Time `json:"created_at"` +} diff --git a/backend/internal/models/publications.go b/backend/internal/models/publications.go new file mode 100644 index 0000000..6bc018a --- /dev/null +++ b/backend/internal/models/publications.go @@ -0,0 +1,30 @@ +package models + +import "time" + +type Publication struct { + ID int `json:"id"` + Category string `json:"category"` + Title string `json:"title"` + Authors *string `json:"authors,omitempty"` + Venue string `json:"venue"` + Volume *string `json:"volume,omitempty"` + PublishedAt string `json:"published_at"` + KCI bool `json:"kci"` + DOI *string `json:"doi,omitempty"` + IsHighlight bool `json:"is_highlight"` + CreatedAt time.Time `json:"created_at"` +} + +type Patent struct { + ID int `json:"id"` + Title string `json:"title"` + Inventors string `json:"inventors"` + ApplicationNo string `json:"application_no"` + ApplicationAt string `json:"application_at"` + RegistrationNo *string `json:"registration_no,omitempty"` + RegistrationAt *string `json:"registration_at,omitempty"` + Country string `json:"country"` + PublishedAt string `json:"published_at"` + CreatedAt time.Time `json:"created_at"` +} diff --git a/backend/internal/models/standardization.go b/backend/internal/models/standardization.go new file mode 100644 index 0000000..0648037 --- /dev/null +++ b/backend/internal/models/standardization.go @@ -0,0 +1,39 @@ +package models + +type StandardDocument struct { + ID int `json:"id"` + BodyID int `json:"body_id"` + WG string `json:"wg"` + ProjectName string `json:"project_name"` + Title string `json:"title"` + DocRef string `json:"doc_ref"` + Status string `json:"status"` + PublishedAt *string `json:"published_at,omitempty"` +} + +type StandardProjectGroup struct { + WG string `json:"wg"` + Name string `json:"name"` + Documents []StandardDocument `json:"documents"` +} + +type StandardsBody struct { + ID int `json:"id"` + Org string `json:"org"` + FullName string `json:"full_name"` + Scope string `json:"scope"` + Period string `json:"period"` + Role *string `json:"role,omitempty"` + DisplayOrder int `json:"display_order"` +} + +type StandardsBodyWithProjects struct { + ID int `json:"id"` + Org string `json:"org"` + FullName string `json:"full_name"` + Scope string `json:"scope"` + Period string `json:"period"` + Role *string `json:"role,omitempty"` + DisplayOrder int `json:"display_order"` + Projects []StandardProjectGroup `json:"projects"` +} diff --git a/backend/internal/repository/home.go b/backend/internal/repository/home.go new file mode 100644 index 0000000..fc94c96 --- /dev/null +++ b/backend/internal/repository/home.go @@ -0,0 +1,100 @@ +package repository + +import ( + "context" + "database/sql" + "encoding/json" + "fmt" + + "git.godopu.com/lab/landing_page/backend/internal/models" +) + +type HomeRepository struct { + db *sql.DB +} + +func NewHomeRepository(db *sql.DB) *HomeRepository { + return &HomeRepository{db: db} +} + +func (r *HomeRepository) GetResearchProjects(ctx context.Context) ([]models.ResearchProject, error) { + query := ` + SELECT id, slug, title, abstract, keywords, organization, standards_org, period, funder, created_at, updated_at + FROM research_projects + ORDER BY id ASC + ` + rows, err := r.db.QueryContext(ctx, query) + if err != nil { + return nil, fmt.Errorf("query research projects: %w", err) + } + defer rows.Close() + + var projects []models.ResearchProject + for rows.Next() { + var p models.ResearchProject + var kwJSON string + err := rows.Scan( + &p.ID, &p.Slug, &p.Title, &p.Abstract, &kwJSON, + &p.Organization, &p.StandardsOrg, &p.Period, &p.Funder, + &p.CreatedAt, &p.UpdatedAt, + ) + if err != nil { + return nil, fmt.Errorf("scan research project: %w", err) + } + if kwJSON != "" { + _ = json.Unmarshal([]byte(kwJSON), &p.Keywords) + } + if p.Keywords == nil { + p.Keywords = []string{} + } + projects = append(projects, p) + } + if err := rows.Err(); err != nil { + return nil, err + } + return projects, nil +} + +func (r *HomeRepository) GetResearchAreas(ctx context.Context) ([]models.ResearchArea, error) { + query := ` + SELECT id, name_en, name_kr, display_order + FROM research_areas + ORDER BY display_order ASC, id ASC + ` + rows, err := r.db.QueryContext(ctx, query) + if err != nil { + return nil, fmt.Errorf("query research areas: %w", err) + } + defer rows.Close() + + var areas []models.ResearchArea + for rows.Next() { + var a models.ResearchArea + if err := rows.Scan(&a.ID, &a.NameEn, &a.NameKr, &a.DisplayOrder); err != nil { + return nil, fmt.Errorf("scan research area: %w", err) + } + areas = append(areas, a) + } + return areas, rows.Err() +} + +func (r *HomeRepository) GetStatsSummary(ctx context.Context) (*models.StatsSummary, error) { + var summary models.StatsSummary + + err := r.db.QueryRowContext(ctx, "SELECT COUNT(*) FROM publications WHERE category = 'intl-journal-conf'").Scan(&summary.IntlPublications) + if err != nil { + return nil, fmt.Errorf("count intl publications: %w", err) + } + + err = r.db.QueryRowContext(ctx, "SELECT COUNT(*) FROM standard_documents").Scan(&summary.StandardizationDocs) + if err != nil { + return nil, fmt.Errorf("count standard documents: %w", err) + } + + err = r.db.QueryRowContext(ctx, "SELECT COUNT(*) FROM patents").Scan(&summary.Patents) + if err != nil { + return nil, fmt.Errorf("count patents: %w", err) + } + + return &summary, nil +} diff --git a/backend/internal/repository/lectures.go b/backend/internal/repository/lectures.go new file mode 100644 index 0000000..7691495 --- /dev/null +++ b/backend/internal/repository/lectures.go @@ -0,0 +1,71 @@ +package repository + +import ( + "context" + "database/sql" + "fmt" + + "git.godopu.com/lab/landing_page/backend/internal/models" +) + +type LecturesRepository struct { + db *sql.DB +} + +func NewLecturesRepository(db *sql.DB) *LecturesRepository { + return &LecturesRepository{db: db} +} + +func (r *LecturesRepository) GetSemestersWithCourses(ctx context.Context) ([]models.SemesterWithCourses, error) { + // Query semesters ordered by year DESC and Fall before Spring within same year + semQuery := ` + SELECT id, year, term + FROM semesters + ORDER BY year DESC, CASE term WHEN 'Fall' THEN 1 WHEN 'Spring' THEN 2 ELSE 3 END, id DESC + ` + semRows, err := r.db.QueryContext(ctx, semQuery) + if err != nil { + return nil, fmt.Errorf("query semesters: %w", err) + } + defer semRows.Close() + + var semesters []models.SemesterWithCourses + semMap := make(map[int]int) // semester_id -> index in slice + + for semRows.Next() { + var s models.SemesterWithCourses + if err := semRows.Scan(&s.ID, &s.Year, &s.Term); err != nil { + return nil, fmt.Errorf("scan semester: %w", err) + } + s.Courses = []models.Course{} + semMap[s.ID] = len(semesters) + semesters = append(semesters, s) + } + if err := semRows.Err(); err != nil { + return nil, err + } + + // Query courses ordered by display_order ASC, id ASC + courseQuery := ` + SELECT id, semester_id, code, name_en, name_kr, note, display_order + FROM courses + ORDER BY semester_id ASC, display_order ASC, id ASC + ` + courseRows, err := r.db.QueryContext(ctx, courseQuery) + if err != nil { + return nil, fmt.Errorf("query courses: %w", err) + } + defer courseRows.Close() + + for courseRows.Next() { + var c models.Course + if err := courseRows.Scan(&c.ID, &c.SemesterID, &c.Code, &c.NameEn, &c.NameKr, &c.Note, &c.DisplayOrder); err != nil { + return nil, fmt.Errorf("scan course: %w", err) + } + if idx, exists := semMap[c.SemesterID]; exists { + semesters[idx].Courses = append(semesters[idx].Courses, c) + } + } + + return semesters, courseRows.Err() +} diff --git a/backend/internal/repository/members.go b/backend/internal/repository/members.go new file mode 100644 index 0000000..1b133b0 --- /dev/null +++ b/backend/internal/repository/members.go @@ -0,0 +1,69 @@ +package repository + +import ( + "context" + "database/sql" + "fmt" + + "git.godopu.com/lab/landing_page/backend/internal/models" +) + +type MembersRepository struct { + db *sql.DB +} + +func NewMembersRepository(db *sql.DB) *MembersRepository { + return &MembersRepository{db: db} +} + +func (r *MembersRepository) GetMembers(ctx context.Context) ([]models.Member, error) { + query := ` + SELECT id, name_ko, name_en, degree, affiliation, email, is_advisor, display_order, created_at + FROM members + ORDER BY display_order ASC, id ASC + ` + rows, err := r.db.QueryContext(ctx, query) + if err != nil { + return nil, fmt.Errorf("query members: %w", err) + } + defer rows.Close() + + var members []models.Member + for rows.Next() { + var m models.Member + if err := rows.Scan( + &m.ID, &m.NameKo, &m.NameEn, &m.Degree, + &m.Affiliation, &m.Email, &m.IsAdvisor, &m.DisplayOrder, &m.CreatedAt, + ); err != nil { + return nil, fmt.Errorf("scan member: %w", err) + } + members = append(members, m) + } + return members, rows.Err() +} + +func (r *MembersRepository) GetAlumni(ctx context.Context) ([]models.Alumnus, error) { + query := ` + SELECT id, name_ko, name_en, degree, graduated_at, major, current_position, created_at + FROM alumni + ORDER BY graduated_at DESC, id ASC + ` + rows, err := r.db.QueryContext(ctx, query) + if err != nil { + return nil, fmt.Errorf("query alumni: %w", err) + } + defer rows.Close() + + var alumni []models.Alumnus + for rows.Next() { + var a models.Alumnus + if err := rows.Scan( + &a.ID, &a.NameKo, &a.NameEn, &a.Degree, + &a.GraduatedAt, &a.Major, &a.CurrentPosition, &a.CreatedAt, + ); err != nil { + return nil, fmt.Errorf("scan alumnus: %w", err) + } + alumni = append(alumni, a) + } + return alumni, rows.Err() +} diff --git a/backend/internal/repository/publications.go b/backend/internal/repository/publications.go new file mode 100644 index 0000000..1f3e074 --- /dev/null +++ b/backend/internal/repository/publications.go @@ -0,0 +1,102 @@ +package repository + +import ( + "context" + "database/sql" + "fmt" + + "git.godopu.com/lab/landing_page/backend/internal/models" +) + +type PublicationsRepository struct { + db *sql.DB +} + +func NewPublicationsRepository(db *sql.DB) *PublicationsRepository { + return &PublicationsRepository{db: db} +} + +func (r *PublicationsRepository) GetPublications(ctx context.Context, category string) ([]models.Publication, error) { + query := ` + SELECT id, category, title, authors, venue, volume, published_at, kci, doi, is_highlight, created_at + FROM publications + ` + var args []any + if category != "" { + query += " WHERE category = ?" + args = append(args, category) + } + query += " ORDER BY published_at DESC, id ASC" + + rows, err := r.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, fmt.Errorf("query publications: %w", err) + } + defer rows.Close() + + var pubs []models.Publication + for rows.Next() { + var p models.Publication + if err := rows.Scan( + &p.ID, &p.Category, &p.Title, &p.Authors, + &p.Venue, &p.Volume, &p.PublishedAt, &p.KCI, &p.DOI, &p.IsHighlight, &p.CreatedAt, + ); err != nil { + return nil, fmt.Errorf("scan publication: %w", err) + } + pubs = append(pubs, p) + } + return pubs, rows.Err() +} + +func (r *PublicationsRepository) GetHighlights(ctx context.Context) ([]models.Publication, error) { + query := ` + SELECT id, category, title, authors, venue, volume, published_at, kci, doi, is_highlight, created_at + FROM publications + WHERE is_highlight = 1 + ORDER BY published_at DESC, id ASC + ` + rows, err := r.db.QueryContext(ctx, query) + if err != nil { + return nil, fmt.Errorf("query highlights: %w", err) + } + defer rows.Close() + + var pubs []models.Publication + for rows.Next() { + var p models.Publication + if err := rows.Scan( + &p.ID, &p.Category, &p.Title, &p.Authors, + &p.Venue, &p.Volume, &p.PublishedAt, &p.KCI, &p.DOI, &p.IsHighlight, &p.CreatedAt, + ); err != nil { + return nil, fmt.Errorf("scan highlight: %w", err) + } + pubs = append(pubs, p) + } + return pubs, rows.Err() +} + +func (r *PublicationsRepository) GetPatents(ctx context.Context) ([]models.Patent, error) { + query := ` + SELECT id, title, inventors, application_no, application_at, registration_no, registration_at, country, published_at, created_at + FROM patents + ORDER BY published_at DESC, id ASC + ` + rows, err := r.db.QueryContext(ctx, query) + if err != nil { + return nil, fmt.Errorf("query patents: %w", err) + } + defer rows.Close() + + var patents []models.Patent + for rows.Next() { + var p models.Patent + if err := rows.Scan( + &p.ID, &p.Title, &p.Inventors, &p.ApplicationNo, + &p.ApplicationAt, &p.RegistrationNo, &p.RegistrationAt, &p.Country, &p.PublishedAt, &p.CreatedAt, + ); err != nil { + return nil, fmt.Errorf("scan patent: %w", err) + } + patents = append(patents, p) + } + return patents, rows.Err() +} diff --git a/backend/internal/repository/standardization.go b/backend/internal/repository/standardization.go new file mode 100644 index 0000000..e970ca1 --- /dev/null +++ b/backend/internal/repository/standardization.go @@ -0,0 +1,95 @@ +package repository + +import ( + "context" + "database/sql" + "fmt" + + "git.godopu.com/lab/landing_page/backend/internal/models" +) + +type StandardizationRepository struct { + db *sql.DB +} + +func NewStandardizationRepository(db *sql.DB) *StandardizationRepository { + return &StandardizationRepository{db: db} +} + +func (r *StandardizationRepository) GetStandardsBodiesWithProjects(ctx context.Context) ([]models.StandardsBodyWithProjects, error) { + // Query bodies ordered by display_order + bodyQuery := ` + SELECT id, org, full_name, scope, period, role, display_order + FROM standards_bodies + ORDER BY display_order ASC, id ASC + ` + bodyRows, err := r.db.QueryContext(ctx, bodyQuery) + if err != nil { + return nil, fmt.Errorf("query standards bodies: %w", err) + } + defer bodyRows.Close() + + var bodies []models.StandardsBodyWithProjects + bodyMap := make(map[int]int) // body_id -> index in bodies + + for bodyRows.Next() { + var b models.StandardsBodyWithProjects + if err := bodyRows.Scan(&b.ID, &b.Org, &b.FullName, &b.Scope, &b.Period, &b.Role, &b.DisplayOrder); err != nil { + return nil, fmt.Errorf("scan standards body: %w", err) + } + b.Projects = []models.StandardProjectGroup{} + bodyMap[b.ID] = len(bodies) + bodies = append(bodies, b) + } + if err := bodyRows.Err(); err != nil { + return nil, err + } + + // Query documents ordered by body_id, and preserves curated insertion order with MIN(id) ASC + docQuery := ` + SELECT id, body_id, wg, project_name, title, doc_ref, status, published_at + FROM standard_documents + ORDER BY body_id ASC, id ASC + ` + docRows, err := r.db.QueryContext(ctx, docQuery) + if err != nil { + return nil, fmt.Errorf("query standard documents: %w", err) + } + defer docRows.Close() + + // Group documents into projects under each body preserving curated order + type projectKey struct { + bodyID int + wg string + projectName string + } + projectMap := make(map[projectKey]int) // projectKey -> index in bodies[bIdx].Projects + + for docRows.Next() { + var d models.StandardDocument + if err := docRows.Scan(&d.ID, &d.BodyID, &d.WG, &d.ProjectName, &d.Title, &d.DocRef, &d.Status, &d.PublishedAt); err != nil { + return nil, fmt.Errorf("scan standard document: %w", err) + } + + bIdx, bodyExists := bodyMap[d.BodyID] + if !bodyExists { + continue + } + + key := projectKey{bodyID: d.BodyID, wg: d.WG, projectName: d.ProjectName} + pIdx, projExists := projectMap[key] + if !projExists { + pIdx = len(bodies[bIdx].Projects) + bodies[bIdx].Projects = append(bodies[bIdx].Projects, models.StandardProjectGroup{ + WG: d.WG, + Name: d.ProjectName, + Documents: []models.StandardDocument{}, + }) + projectMap[key] = pIdx + } + + bodies[bIdx].Projects[pIdx].Documents = append(bodies[bIdx].Projects[pIdx].Documents, d) + } + + return bodies, docRows.Err() +} diff --git a/backend/internal/router/router.go b/backend/internal/router/router.go new file mode 100644 index 0000000..584a31d --- /dev/null +++ b/backend/internal/router/router.go @@ -0,0 +1,76 @@ +package router + +import ( + "database/sql" + "net/http" + + "git.godopu.com/lab/landing_page/backend/internal/handlers" + "git.godopu.com/lab/landing_page/backend/internal/httpx" + "git.godopu.com/lab/landing_page/backend/internal/repository" + "github.com/gin-gonic/gin" +) + +func SetupRouter(db *sql.DB, corsOrigins ...string) *gin.Engine { + r := gin.Default() + + allowOrigin := "*" + if len(corsOrigins) > 0 && corsOrigins[0] != "" { + allowOrigin = corsOrigins[0] + } + + // CORS Middleware + r.Use(func(c *gin.Context) { + c.Writer.Header().Set("Access-Control-Allow-Origin", allowOrigin) + c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") + c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") + if c.Request.Method == "OPTIONS" { + c.AbortWithStatus(http.StatusNoContent) + return + } + c.Next() + }) + + // Repositories + homeRepo := repository.NewHomeRepository(db) + membersRepo := repository.NewMembersRepository(db) + pubsRepo := repository.NewPublicationsRepository(db) + lecturesRepo := repository.NewLecturesRepository(db) + standardsRepo := repository.NewStandardizationRepository(db) + + // Handlers + homeHandler := handlers.NewHomeHandler(homeRepo) + membersHandler := handlers.NewMembersHandler(membersRepo) + pubsHandler := handlers.NewPublicationsHandler(pubsRepo) + lecturesHandler := handlers.NewLecturesHandler(lecturesRepo) + standardsHandler := handlers.NewStandardizationHandler(standardsRepo) + + // API v1 Group + v1 := r.Group("/api/v1") + { + v1.GET("/health", func(c *gin.Context) { + httpx.OK(c, gin.H{"status": "ok", "service": "anl-backend-api"}) + }) + + // Home + v1.GET("/research-projects", homeHandler.GetResearchProjects) + v1.GET("/research-areas", homeHandler.GetResearchAreas) + v1.GET("/stats/summary", homeHandler.GetStatsSummary) + + // Members & Alumni + v1.GET("/members", membersHandler.GetMembers) + v1.GET("/alumni", membersHandler.GetAlumni) + + // Publications & Patents + v1.GET("/publications", pubsHandler.GetPublications) + v1.GET("/publications/highlights", pubsHandler.GetHighlights) + v1.GET("/patents", pubsHandler.GetPatents) + + // Lectures + v1.GET("/semesters", lecturesHandler.GetSemesters) + + // Standardization + v1.GET("/standards-bodies", standardsHandler.GetStandardsBodies) + } + + return r +} diff --git a/backend/internal/router/router_test.go b/backend/internal/router/router_test.go new file mode 100644 index 0000000..81566a5 --- /dev/null +++ b/backend/internal/router/router_test.go @@ -0,0 +1,446 @@ +package router_test + +import ( + "context" + "database/sql" + "encoding/json" + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "testing" + + "git.godopu.com/lab/landing_page/backend/internal/db" + "git.godopu.com/lab/landing_page/backend/internal/models" + "git.godopu.com/lab/landing_page/backend/internal/router" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + _ "modernc.org/sqlite" +) + +func setupTestDB(t *testing.T) *sql.DB { + // In-memory or temporary file sqlite DB + tmpDB := filepath.Join(t.TempDir(), "test.db") + database, err := db.Connect(tmpDB) + require.NoError(t, err) + + err = db.RunMigrations(database) + require.NoError(t, err) + + // Seed test data from ../../seed/data + seedDir := filepath.Join("..", "..", "seed", "data") + seedDatabase(t, database, seedDir) + + return database +} + +func seedDatabase(t *testing.T, database *sql.DB, seedDir string) { + tx, err := database.BeginTx(context.Background(), nil) + require.NoError(t, err) + defer tx.Rollback() + + // 1. Projects + pData, err := os.ReadFile(filepath.Join(seedDir, "research_projects.json")) + require.NoError(t, err) + var projects []struct { + Slug string `json:"slug"` + Title string `json:"title"` + Abstract string `json:"abstract"` + Keywords []string `json:"keywords"` + StandardsTrack *string `json:"standardsTrack"` + StandardsOrg *string `json:"standardsOrg"` + Period *string `json:"period"` + Funder *string `json:"funder"` + } + require.NoError(t, json.Unmarshal(pData, &projects)) + for _, p := range projects { + kwJSON, _ := json.Marshal(p.Keywords) + _, err := tx.Exec(` + INSERT INTO research_projects (slug, title, abstract, keywords, organization, standards_org, period, funder) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + `, p.Slug, p.Title, p.Abstract, string(kwJSON), p.StandardsTrack, p.StandardsOrg, p.Period, p.Funder) + require.NoError(t, err) + } + + // 2. Areas + aData, err := os.ReadFile(filepath.Join(seedDir, "research_areas.json")) + require.NoError(t, err) + var areas []models.ResearchArea + require.NoError(t, json.Unmarshal(aData, &areas)) + for _, a := range areas { + _, err := tx.Exec(`INSERT INTO research_areas (name_en, name_kr, display_order) VALUES (?, ?, ?)`, a.NameEn, a.NameKr, a.DisplayOrder) + require.NoError(t, err) + } + + // 3. Members + mData, err := os.ReadFile(filepath.Join(seedDir, "members.json")) + require.NoError(t, err) + var members []models.Member + require.NoError(t, json.Unmarshal(mData, &members)) + for _, m := range members { + _, err := tx.Exec(` + INSERT INTO members (name_ko, name_en, degree, affiliation, email, is_advisor, display_order) + VALUES (?, ?, ?, ?, ?, ?, ?) + `, m.NameKo, m.NameEn, m.Degree, m.Affiliation, m.Email, m.IsAdvisor, m.DisplayOrder) + require.NoError(t, err) + } + + // 4. Alumni + alumniData, err := os.ReadFile(filepath.Join(seedDir, "alumni.json")) + require.NoError(t, err) + var alumni []models.Alumnus + require.NoError(t, json.Unmarshal(alumniData, &alumni)) + for _, a := range alumni { + _, err := tx.Exec(` + INSERT INTO alumni (name_ko, name_en, degree, graduated_at, major, current_position) + VALUES (?, ?, ?, ?, ?, ?) + `, a.NameKo, a.NameEn, a.Degree, a.GraduatedAt, a.Major, a.CurrentPosition) + require.NoError(t, err) + } + + // 5. Publications + pubData, err := os.ReadFile(filepath.Join(seedDir, "publications.json")) + require.NoError(t, err) + var pubs []models.Publication + require.NoError(t, json.Unmarshal(pubData, &pubs)) + for _, p := range pubs { + _, err := tx.Exec(` + INSERT INTO publications (category, title, authors, venue, volume, published_at, kci, doi, is_highlight) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + `, p.Category, p.Title, p.Authors, p.Venue, p.Volume, p.PublishedAt, p.KCI, p.DOI, p.IsHighlight) + require.NoError(t, err) + } + + // 6. Patents + patData, err := os.ReadFile(filepath.Join(seedDir, "patents.json")) + require.NoError(t, err) + var patents []models.Patent + require.NoError(t, json.Unmarshal(patData, &patents)) + for _, pat := range patents { + _, err := tx.Exec(` + INSERT INTO patents (title, inventors, application_no, application_at, registration_no, registration_at, country, published_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + `, pat.Title, pat.Inventors, pat.ApplicationNo, pat.ApplicationAt, pat.RegistrationNo, pat.RegistrationAt, pat.Country, pat.PublishedAt) + require.NoError(t, err) + } + + // 7. Semesters & Courses + lecData, err := os.ReadFile(filepath.Join(seedDir, "lectures.json")) + require.NoError(t, err) + var semesters []struct { + Term string `json:"term"` + Year int `json:"year"` + Courses []struct { + Code string `json:"code"` + En string `json:"en"` + Note *string `json:"note"` + } `json:"courses"` + } + require.NoError(t, json.Unmarshal(lecData, &semesters)) + for _, s := range semesters { + res, err := tx.Exec(`INSERT INTO semesters (year, term) VALUES (?, ?)`, s.Year, s.Term) + require.NoError(t, err) + semID, _ := res.LastInsertId() + for cIdx, c := range s.Courses { + _, err := tx.Exec(` + INSERT INTO courses (semester_id, code, name_en, name_kr, note, display_order) + VALUES (?, ?, ?, ?, ?, ?) + `, semID, c.Code, c.En, nil, c.Note, cIdx+1) + require.NoError(t, err) + } + } + + // 8. Standards + stdData, err := os.ReadFile(filepath.Join(seedDir, "standards.json")) + require.NoError(t, err) + var standards []struct { + Org string `json:"org"` + Full string `json:"full"` + Scope string `json:"scope"` + Period string `json:"period"` + Role *string `json:"role"` + Projects []struct { + WG string `json:"wg"` + Name string `json:"name"` + Documents []struct { + Title string `json:"title"` + Ref string `json:"ref"` + Status string `json:"status"` + PublishedAt *string `json:"publishedAt"` + } `json:"documents"` + } `json:"projects"` + } + require.NoError(t, json.Unmarshal(stdData, &standards)) + for bIdx, b := range standards { + res, err := tx.Exec(` + INSERT INTO standards_bodies (org, full_name, scope, period, role, display_order) + VALUES (?, ?, ?, ?, ?, ?) + `, b.Org, b.Full, b.Scope, b.Period, b.Role, bIdx+1) + require.NoError(t, err) + bodyID, _ := res.LastInsertId() + + for _, p := range b.Projects { + for _, d := range p.Documents { + _, err := tx.Exec(` + INSERT INTO standard_documents (body_id, wg, project_name, title, doc_ref, status, published_at) + VALUES (?, ?, ?, ?, ?, ?, ?) + `, bodyID, p.WG, p.Name, d.Title, d.Ref, d.Status, d.PublishedAt) + require.NoError(t, err) + } + } + } + + require.NoError(t, tx.Commit()) +} + +type APIResponse[T any] struct { + Data T `json:"data"` + Error *struct { + Message string `json:"message"` + } `json:"error"` +} + +func executeRequest(r http.Handler, method, target string) *httptest.ResponseRecorder { + req := httptest.NewRequest(method, target, nil) + w := httptest.NewRecorder() + r.ServeHTTP(w, req) + return w +} + +func TestHealthEndpoint(t *testing.T) { + database := setupTestDB(t) + defer database.Close() + + r := router.SetupRouter(database) + w := executeRequest(r, "GET", "/api/v1/health") + + assert.Equal(t, http.StatusOK, w.Code) + var resp APIResponse[map[string]any] + err := json.Unmarshal(w.Body.Bytes(), &resp) + require.NoError(t, err) + assert.Equal(t, "ok", resp.Data["status"]) + assert.Equal(t, "anl-backend-api", resp.Data["service"]) +} + +func TestResearchProjects(t *testing.T) { + database := setupTestDB(t) + defer database.Close() + + r := router.SetupRouter(database) + w := executeRequest(r, "GET", "/api/v1/research-projects") + + assert.Equal(t, http.StatusOK, w.Code) + var resp APIResponse[[]models.ResearchProject] + require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp)) + assert.Len(t, resp.Data, 3) + assert.Equal(t, "iot-standards", resp.Data[0].Slug) + assert.Equal(t, "AIoT & AI-RAN", resp.Data[0].Title) +} + +func TestResearchAreas(t *testing.T) { + database := setupTestDB(t) + defer database.Close() + + r := router.SetupRouter(database) + w := executeRequest(r, "GET", "/api/v1/research-areas") + + assert.Equal(t, http.StatusOK, w.Code) + var resp APIResponse[[]models.ResearchArea] + require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp)) + assert.Len(t, resp.Data, 14) + assert.Equal(t, 1, resp.Data[0].DisplayOrder) + assert.Equal(t, "Quick UDP Internet Connection (QUIC)", resp.Data[0].NameEn) +} + +func TestStatsSummary(t *testing.T) { + database := setupTestDB(t) + defer database.Close() + + r := router.SetupRouter(database) + w := executeRequest(r, "GET", "/api/v1/stats/summary") + + assert.Equal(t, http.StatusOK, w.Code) + var resp APIResponse[models.StatsSummary] + require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp)) + assert.Equal(t, 68, resp.Data.IntlPublications) + assert.Equal(t, 44, resp.Data.StandardizationDocs) + assert.Equal(t, 75, resp.Data.Patents) +} + +func TestMembersAndAlumni(t *testing.T) { + database := setupTestDB(t) + defer database.Close() + + r := router.SetupRouter(database) + + // Members + wMem := executeRequest(r, "GET", "/api/v1/members") + assert.Equal(t, http.StatusOK, wMem.Code) + var respMem APIResponse[[]models.Member] + require.NoError(t, json.Unmarshal(wMem.Body.Bytes(), &respMem)) + assert.Len(t, respMem.Data, 16) + assert.True(t, respMem.Data[0].IsAdvisor) + assert.Equal(t, "Seok-Joo Koh", respMem.Data[0].NameEn) + + // Alumni + wAlumni := executeRequest(r, "GET", "/api/v1/alumni") + assert.Equal(t, http.StatusOK, wAlumni.Code) + var respAlumni APIResponse[[]models.Alumnus] + require.NoError(t, json.Unmarshal(wAlumni.Body.Bytes(), &respAlumni)) + assert.Len(t, respAlumni.Data, 60) + assert.GreaterOrEqual(t, respAlumni.Data[0].GraduatedAt, respAlumni.Data[1].GraduatedAt) +} + +func TestPublicationsAndHighlights(t *testing.T) { + database := setupTestDB(t) + defer database.Close() + + r := router.SetupRouter(database) + + // Full Publications + wAll := executeRequest(r, "GET", "/api/v1/publications") + assert.Equal(t, http.StatusOK, wAll.Code) + var respAll APIResponse[[]models.Publication] + require.NoError(t, json.Unmarshal(wAll.Body.Bytes(), &respAll)) + assert.Len(t, respAll.Data, 148) + + // Category filter: intl + wIntl := executeRequest(r, "GET", "/api/v1/publications?category=intl-journal-conf") + assert.Equal(t, http.StatusOK, wIntl.Code) + var respIntl APIResponse[[]models.Publication] + require.NoError(t, json.Unmarshal(wIntl.Body.Bytes(), &respIntl)) + assert.Len(t, respIntl.Data, 68) + + // Category filter: domestic + wDom := executeRequest(r, "GET", "/api/v1/publications?category=domestic-journal-conf") + assert.Equal(t, http.StatusOK, wDom.Code) + var respDom APIResponse[[]models.Publication] + require.NoError(t, json.Unmarshal(wDom.Body.Bytes(), &respDom)) + assert.Len(t, respDom.Data, 80) + + // Invalid category + wInvalid := executeRequest(r, "GET", "/api/v1/publications?category=unknown") + assert.Equal(t, http.StatusBadRequest, wInvalid.Code) + + // Highlights (asserts exactly the 5 known representative titles) + wHL := executeRequest(r, "GET", "/api/v1/publications/highlights") + assert.Equal(t, http.StatusOK, wHL.Code) + var respHL APIResponse[[]models.Publication] + require.NoError(t, json.Unmarshal(wHL.Body.Bytes(), &respHL)) + assert.Len(t, respHL.Data, 5) + + expectedTitles := map[string]bool{ + "Globally Integrated Trust Authority (GITA) for Resource-Constrained Edge Devices in IoT and 6G": true, + "Application Level Trust Authority (APPLETA) for Resource-Constrained Edge Devices in IoT and 6G": true, + "mQUIC: Use of QUIC for Handover Support with Connection Migration in Wireless/Mobile Networks": true, + "Use of QUIC for CoAP Transport in IoT Networks": true, + "Use of QUIC for Mobile-Oriented Future Internet (Q-MOFI)": true, + } + for _, hl := range respHL.Data { + assert.True(t, hl.IsHighlight) + assert.True(t, expectedTitles[hl.Title], "Unexpected highlight title: %s", hl.Title) + } + + // Patents + wPat := executeRequest(r, "GET", "/api/v1/patents") + assert.Equal(t, http.StatusOK, wPat.Code) + var respPat APIResponse[[]models.Patent] + require.NoError(t, json.Unmarshal(wPat.Body.Bytes(), &respPat)) + assert.Len(t, respPat.Data, 75) +} + +func TestSemestersAndCourses(t *testing.T) { + database := setupTestDB(t) + defer database.Close() + + r := router.SetupRouter(database) + + w := executeRequest(r, "GET", "/api/v1/semesters") + assert.Equal(t, http.StatusOK, w.Code) + var resp APIResponse[[]models.SemesterWithCourses] + require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp)) + assert.Len(t, resp.Data, 45) + + // Check semester ordering (Year DESC, Fall before Spring within same year) + first := resp.Data[0] + assert.Equal(t, 2026, first.Year) + assert.Equal(t, "Spring", first.Term) + assert.NotEmpty(t, first.Courses) + + // In 2025: Fall must come before Spring + var s2025Fall, s2025Spring int + for idx, s := range resp.Data { + if s.Year == 2025 && s.Term == "Fall" { + s2025Fall = idx + } + if s.Year == 2025 && s.Term == "Spring" { + s2025Spring = idx + } + } + assert.Less(t, s2025Fall, s2025Spring, "2025 Fall should precede 2025 Spring in chronological descending order") +} + +func TestStandardsBodiesAndHierarchy(t *testing.T) { + database := setupTestDB(t) + defer database.Close() + + r := router.SetupRouter(database) + + w := executeRequest(r, "GET", "/api/v1/standards-bodies") + assert.Equal(t, http.StatusOK, w.Code) + var resp APIResponse[[]models.StandardsBodyWithProjects] + require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp)) + assert.Len(t, resp.Data, 6) + + // First body: IEC TC100 + iec := resp.Data[0] + assert.Equal(t, "IEC TC100", iec.Org) + require.NotEmpty(t, iec.Projects) + + // Verify project ordering within IEC TC100 (deterministic order: WG12 before WG11(Convenor)) + assert.Equal(t, "WG12", iec.Projects[0].WG) + assert.Equal(t, "WG11(Convenor)", iec.Projects[1].WG) + assert.NotEmpty(t, iec.Projects[0].Documents) +} + +func TestJSONKeyCasingSnakeCase(t *testing.T) { + database := setupTestDB(t) + defer database.Close() + + r := router.SetupRouter(database) + + // Test Members endpoint raw JSON map + wMem := executeRequest(r, "GET", "/api/v1/members") + assert.Equal(t, http.StatusOK, wMem.Code) + var rawMem map[string]any + require.NoError(t, json.Unmarshal(wMem.Body.Bytes(), &rawMem)) + dataList, ok := rawMem["data"].([]any) + require.True(t, ok) + require.NotEmpty(t, dataList) + firstMember, ok := dataList[0].(map[string]any) + require.True(t, ok) + + // Verify snake_case keys exist and camelCase keys do not + assert.Contains(t, firstMember, "name_ko") + assert.Contains(t, firstMember, "name_en") + assert.Contains(t, firstMember, "is_advisor") + assert.Contains(t, firstMember, "display_order") + assert.NotContains(t, firstMember, "nameKo") + assert.NotContains(t, firstMember, "isAdvisor") + + // Test Highlights endpoint raw JSON map + wHL := executeRequest(r, "GET", "/api/v1/publications/highlights") + assert.Equal(t, http.StatusOK, wHL.Code) + var rawHL map[string]any + require.NoError(t, json.Unmarshal(wHL.Body.Bytes(), &rawHL)) + hlList, ok := rawHL["data"].([]any) + require.True(t, ok) + require.NotEmpty(t, hlList) + firstHL, ok := hlList[0].(map[string]any) + require.True(t, ok) + + assert.Contains(t, firstHL, "is_highlight") + assert.Contains(t, firstHL, "published_at") + assert.NotContains(t, firstHL, "isHighlight") + assert.NotContains(t, firstHL, "publishedAt") +} diff --git a/backend/scripts/export_ts_to_json.py b/backend/scripts/export_ts_to_json.py new file mode 100755 index 0000000..22b54bf --- /dev/null +++ b/backend/scripts/export_ts_to_json.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python3 +""" +Exports curated data from refer_landing_page/content/*.ts and app/page.tsx into backend/seed/data/*.json. +Ensures is_highlight is properly tagged on the 5 representative publications. +""" + +import json +import os +import re +import sys + +REPO_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +CONTENT_DIR = os.path.join(REPO_ROOT, "refer_landing_page", "content") +SEED_DATA_DIR = os.path.join(REPO_ROOT, "backend", "seed", "data") +PAGE_TSX = os.path.join(REPO_ROOT, "refer_landing_page", "app", "page.tsx") + +os.makedirs(SEED_DATA_DIR, exist_ok=True) + +HIGHLIGHT_TITLES = { + "Globally Integrated Trust Authority (GITA) for Resource-Constrained Edge Devices in IoT and 6G", + "Application Level Trust Authority (APPLETA) for Resource-Constrained Edge Devices in IoT and 6G", + "mQUIC: Use of QUIC for Handover Support with Connection Migration in Wireless/Mobile Networks", + "Use of QUIC for CoAP Transport in IoT Networks", + "Use of QUIC for Mobile-Oriented Future Internet (Q-MOFI)", +} + +def clean_json_str(s): + # Remove trailing commas before ] or } + s = re.sub(r',\s*\]', ']', s) + s = re.sub(r',\s*\}', '}', s) + return s + +def extract_json_array_from_ts(filepath, var_name): + with open(filepath, "r", encoding="utf-8") as f: + content = f.read() + + # Match export const [: Type] = [ ... ]; + pattern = rf'export\s+const\s+{var_name}(?:\s*:\s*[^=]+)?\s*=\s*(\[\s*[\s\S]*?\s*\]);' + match = re.search(pattern, content) + if not match: + raise ValueError(f"Could not find array literal for '{var_name}' in {filepath}") + + array_str = clean_json_str(match.group(1)) + return json.loads(array_str) + +def main(): + print("=== Extracting TypeScript content to JSON for SQLite seeding ===") + + # 1. Projects + projects_file = os.path.join(CONTENT_DIR, "projects.ts") + projects = extract_json_array_from_ts(projects_file, "researchProjects") + with open(os.path.join(SEED_DATA_DIR, "research_projects.json"), "w", encoding="utf-8") as f: + json.dump(projects, f, indent=2, ensure_ascii=False) + print(f"✓ Extracted {len(projects)} research projects") + + # 2. Research Areas (from app/page.tsx) + with open(PAGE_TSX, "r", encoding="utf-8") as f: + page_src = f.read() + areas_match = re.search(r'const\s+RESEARCH_AREAS(?:\s*:\s*[^=]+)?\s*=\s*(\[\s*[\s\S]*?\s*\]);', page_src) + if not areas_match: + raise ValueError("Could not find RESEARCH_AREAS in app/page.tsx") + areas_str = clean_json_str(areas_match.group(1)) + areas_list = json.loads(areas_str) + research_areas = [{"name_en": name, "name_kr": None, "display_order": i + 1} for i, name in enumerate(areas_list)] + with open(os.path.join(SEED_DATA_DIR, "research_areas.json"), "w", encoding="utf-8") as f: + json.dump(research_areas, f, indent=2, ensure_ascii=False) + print(f"✓ Extracted {len(research_areas)} research areas") + + # 3. Members & Alumni + members_file = os.path.join(CONTENT_DIR, "members.ts") + active_members = extract_json_array_from_ts(members_file, "activeMembers") + alumni = extract_json_array_from_ts(members_file, "alumni") + + # Format active members with is_advisor + formatted_members = [] + for i, m in enumerate(active_members): + formatted_members.append({ + "name_ko": m["ko"], + "name_en": m["en"], + "degree": m["degree"], + "affiliation": m.get("affiliation"), + "email": "sjkoh@knu.ac.kr" if m["degree"] == "Professor" else None, + "is_advisor": m["degree"] == "Professor", + "display_order": i + 1, + }) + with open(os.path.join(SEED_DATA_DIR, "members.json"), "w", encoding="utf-8") as f: + json.dump(formatted_members, f, indent=2, ensure_ascii=False) + print(f"✓ Extracted {len(formatted_members)} active members") + + formatted_alumni = [] + for a in alumni: + formatted_alumni.append({ + "name_ko": a["ko"], + "name_en": a["en"], + "degree": a["degree"], + "graduated_at": a["graduatedAt"], + "major": a.get("major"), + "current_position": a.get("currentPosition"), + }) + with open(os.path.join(SEED_DATA_DIR, "alumni.json"), "w", encoding="utf-8") as f: + json.dump(formatted_alumni, f, indent=2, ensure_ascii=False) + print(f"✓ Extracted {len(formatted_alumni)} alumni") + + # 4. Publications & Patents + pubs_file = os.path.join(CONTENT_DIR, "publications.ts") + raw_pubs = extract_json_array_from_ts(pubs_file, "publications") + raw_patents = extract_json_array_from_ts(pubs_file, "patents") + + matched_highlights = [] + formatted_pubs = [] + for p in raw_pubs: + title_clean = p["title"].strip() + is_hl = title_clean in HIGHLIGHT_TITLES + if is_hl: + matched_highlights.append(title_clean) + formatted_pubs.append({ + "category": p["category"], + "title": p["title"], + "authors": p.get("authors"), + "venue": p["venue"], + "volume": p.get("volume"), + "published_at": p["publishedAt"], + "kci": bool(p.get("kci", False)), + "doi": p.get("doi"), + "is_highlight": is_hl, + }) + + if len(matched_highlights) != 5: + raise ValueError(f"Highlight matching error: expected exactly 5 matched highlights, found {len(matched_highlights)}: {matched_highlights}") + + with open(os.path.join(SEED_DATA_DIR, "publications.json"), "w", encoding="utf-8") as f: + json.dump(formatted_pubs, f, indent=2, ensure_ascii=False) + print(f"✓ Extracted {len(formatted_pubs)} publications (exactly {len(matched_highlights)} highlights tagged)") + + formatted_patents = [] + for pat in raw_patents: + formatted_patents.append({ + "title": pat["title"], + "inventors": pat["inventors"], + "application_no": pat["applicationNo"], + "application_at": pat["applicationAt"], + "registration_no": pat.get("registrationNo"), + "registration_at": pat.get("registrationAt"), + "country": pat["country"], + "published_at": pat["publishedAt"], + }) + with open(os.path.join(SEED_DATA_DIR, "patents.json"), "w", encoding="utf-8") as f: + json.dump(formatted_patents, f, indent=2, ensure_ascii=False) + print(f"✓ Extracted {len(formatted_patents)} patents") + + # 5. Lectures (Semesters & Courses) + lectures_file = os.path.join(CONTENT_DIR, "lectures.ts") + raw_semesters = extract_json_array_from_ts(lectures_file, "semesters") + with open(os.path.join(SEED_DATA_DIR, "lectures.json"), "w", encoding="utf-8") as f: + json.dump(raw_semesters, f, indent=2, ensure_ascii=False) + + total_courses = sum(len(s.get("courses", [])) for s in raw_semesters) + print(f"✓ Extracted {len(raw_semesters)} semesters with {total_courses} courses") + + # 6. Standardization + standards_file = os.path.join(CONTENT_DIR, "standards.ts") + raw_standards = extract_json_array_from_ts(standards_file, "standardsBodies") + with open(os.path.join(SEED_DATA_DIR, "standards.json"), "w", encoding="utf-8") as f: + json.dump(raw_standards, f, indent=2, ensure_ascii=False) + + total_docs = sum( + sum(len(p.get("documents", [])) for p in b.get("projects", [])) + for b in raw_standards + ) + print(f"✓ Extracted {len(raw_standards)} standards bodies with {total_docs} documents") + + print("=== Extraction completed successfully ===") + +if __name__ == "__main__": + main() diff --git a/backend/seed/data/alumni.json b/backend/seed/data/alumni.json new file mode 100644 index 0000000..7020f25 --- /dev/null +++ b/backend/seed/data/alumni.json @@ -0,0 +1,482 @@ +[ + { + "name_ko": "김동주", + "name_en": "Dongju Kim", + "degree": "PhD", + "graduated_at": "2026-08", + "major": "Computer Science and Engineering", + "current_position": "He is now with Daegu Catholic University (대구가톨릭대학교) as Professor" + }, + { + "name_ko": "황정미", + "name_en": "Jung-Mi Hwang", + "degree": "MS", + "graduated_at": "2026-08", + "major": "Information Science", + "current_position": "She is now with NIA (한국지능정보사회진흥원)" + }, + { + "name_ko": "배드로", + "name_en": "Dro Bae", + "degree": "MS", + "graduated_at": "2026-02", + "major": "Industrial Engineering", + "current_position": "He is now with SK AX" + }, + { + "name_ko": "권세기", + "name_en": "Se-Gi Kwon", + "degree": "MS", + "graduated_at": "2026-02", + "major": "Information Security", + "current_position": "He is now with J Solution (제이솔루션) as CEO" + }, + { + "name_ko": "조세현", + "name_en": "Se-Hyun Cho", + "degree": "PhD", + "graduated_at": "2025-08", + "major": "Information Security", + "current_position": "He is now with Cyber Security Center" + }, + { + "name_ko": "김윤성", + "name_en": "Yun-Seong Kim", + "degree": "MS", + "graduated_at": "2025-08", + "major": "Data Convergence Computing", + "current_position": "He is now with SL (에스엘)" + }, + { + "name_ko": "김수진", + "name_en": "Su-Jin Kim", + "degree": "MS", + "graduated_at": "2025-08", + "major": "Information Science", + "current_position": "He is now with NIA (한국지능정보사회진흥원)" + }, + { + "name_ko": "김상태", + "name_en": "Sang-Tae Kim", + "degree": "MS", + "graduated_at": "2025-08", + "major": "Industrial Engineering", + "current_position": "He is now with Oh-Sung Electronis (오성전자)" + }, + { + "name_ko": "김규범", + "name_en": "Gyu-Bum Kim", + "degree": "MS", + "graduated_at": "2025-08", + "major": "Computer Science and Engineering", + "current_position": "He is now with Korea Real Estate Board (한국부동산원)" + }, + { + "name_ko": "정중화", + "name_en": "Joong-Hwa Jung", + "degree": "PhD", + "graduated_at": "2025-02", + "major": null, + "current_position": "He is now with Lychee AI Coding Academy (리치AI코딩학원) as CEO" + }, + { + "name_ko": "임도현", + "name_en": "Dohyeon Lim", + "degree": "MS", + "graduated_at": "2025-02", + "major": "Computer Science and Engineering", + "current_position": "He is now with TakenSoft (테이큰소프트)" + }, + { + "name_ko": "김소용", + "name_en": "So-Yong Kim", + "degree": "PhD", + "graduated_at": "2024-08", + "major": null, + "current_position": "He is now with Catholic University of Leuven (UCLouvain) in Belgium" + }, + { + "name_ko": "김민지", + "name_en": "Min-Ji Kim", + "degree": "MS", + "graduated_at": "2024-02", + "major": null, + "current_position": "She is now with LG Electronics" + }, + { + "name_ko": "안은지", + "name_en": "Eun-Ji Ahn", + "degree": "MS", + "graduated_at": "2024-02", + "major": null, + "current_position": "S is now with National Security Research Institute (국가보안연구소)" + }, + { + "name_ko": "오동규", + "name_en": "Dong-Kyu Oh", + "degree": "MS", + "graduated_at": "2024-02", + "major": "Industrial Engineering", + "current_position": "He is now with Human-Plus (휴먼플러스)" + }, + { + "name_ko": "김재성", + "name_en": "Jae-Seong Kim", + "degree": "MS", + "graduated_at": "2023-08", + "major": "Information Science", + "current_position": "He is now with NIA (한국지능정보사회진흥원)" + }, + { + "name_ko": "최동규", + "name_en": "Dong-Kyu Choi", + "degree": "PhD", + "graduated_at": "2023-02", + "major": null, + "current_position": "He is now with ISL in KNU" + }, + { + "name_ko": "최진원", + "name_en": "Jin-Won Choi", + "degree": "MS", + "graduated_at": "2023-02", + "major": "Information Science", + "current_position": "He is now with NIA (한국지능정보사회진흥원)" + }, + { + "name_ko": "김지은", + "name_en": "Ji-Eun Kim", + "degree": "MS", + "graduated_at": "2023-02", + "major": "Information Science", + "current_position": "She is now with NIA (한국지능정보사회진흥원)" + }, + { + "name_ko": "김철민", + "name_en": "Cheol-Min Kim", + "degree": "PhD", + "graduated_at": "2022-08", + "major": null, + "current_position": "He is now with KETI (한국전자기술연구원)" + }, + { + "name_ko": "김경식", + "name_en": "Kyung-Sik Kim", + "degree": "MS", + "graduated_at": "2022-02", + "major": null, + "current_position": "He is now with Hyundai Autoever (현대오토에버)" + }, + { + "name_ko": "김근수", + "name_en": "Keun-Soo Kim", + "degree": "MS", + "graduated_at": "2022-02", + "major": null, + "current_position": "He is now with Shinhan Bank (신한은행)" + }, + { + "name_ko": "정성우", + "name_en": "Seong-Woo Jeong", + "degree": "MS", + "graduated_at": "2022-02", + "major": "Information Science", + "current_position": "He is now with NIA (한국지능정보사회진흥원)" + }, + { + "name_ko": "최민철", + "name_en": "Min-Cheol Choi", + "degree": "MS", + "graduated_at": "2022-02", + "major": "Information Science", + "current_position": "He is now with NIA (한국지능정보사회진흥원)" + }, + { + "name_ko": "장준희", + "name_en": "Jun-Hee Jang", + "degree": "MS", + "graduated_at": "2021-08", + "major": "Computer Science and Engineering", + "current_position": "He is now with NIA (한국지능정보사회진흥원)" + }, + { + "name_ko": "Muhammad Hafidh Firmansyah", + "name_en": "Muhammad Hafidh Firmansyah", + "degree": "MS", + "graduated_at": "2021-08", + "major": null, + "current_position": "He is now with State Polytechnic University of Jember in Indonesia" + }, + { + "name_ko": "장강민", + "name_en": "Kang-Min Jang", + "degree": "MS", + "graduated_at": "2021-02", + "major": "Information Science", + "current_position": "He is now with NIA (한국지능정보사회진흥원)" + }, + { + "name_ko": "이홍근", + "name_en": "Hong-Keun Lee", + "degree": "MS", + "graduated_at": "2021-02", + "major": "Information Science", + "current_position": "He is now with NIA (한국지능정보사회진흥원)" + }, + { + "name_ko": "남혜빈", + "name_en": "Hyebeen Nam", + "degree": "MS", + "graduated_at": "2021-02", + "major": null, + "current_position": "She is now with ISL in KNU" + }, + { + "name_ko": "최낙중", + "name_en": "Nak-Jung Choi", + "degree": "PhD", + "graduated_at": "2020-02", + "major": null, + "current_position": "He is now with Agency for Defense Development (국방과학연구소)" + }, + { + "name_ko": "정민우", + "name_en": "Min-Woo Jung", + "degree": "MS", + "graduated_at": "2019-02", + "major": null, + "current_position": "He is now with LG Electronics (LG전자)" + }, + { + "name_ko": "강형우", + "name_en": "Hyung-Woo Kang", + "degree": "PhD", + "graduated_at": "2018-08", + "major": null, + "current_position": "He is now with Samsung Electronics (삼성전자)" + }, + { + "name_ko": "최예찬", + "name_en": "Ye-Chan Choi", + "degree": "MS", + "graduated_at": "2018-02", + "major": null, + "current_position": "He is now with LG-CNS" + }, + { + "name_ko": "최상일", + "name_en": "Sang-Il Choi", + "degree": "PhD", + "graduated_at": "2017-02", + "major": null, + "current_position": "He is now with Daegu Catholic University (대구가톨릭대학교) as a professor" + }, + { + "name_ko": "박진호", + "name_en": "Jin-Ho Park", + "degree": "MS", + "graduated_at": "2016-08", + "major": null, + "current_position": "He is now with BiThumb (빗썸코리아)" + }, + { + "name_ko": "석성윤", + "name_en": "Sung-Yoon Seok", + "degree": "MS", + "graduated_at": "2016-08", + "major": "Samsung Electronics Program", + "current_position": "He is now with Samsung Electronics (삼성전자)" + }, + { + "name_ko": "김진규", + "name_en": "Jin-Kyu Kim", + "degree": "MS", + "graduated_at": "2016-08", + "major": "Samsung Electronics Program", + "current_position": "He is now with Samsung Electronics (삼성전자)" + }, + { + "name_ko": "김재철", + "name_en": "Jae-Cheol Kim", + "degree": "MS", + "graduated_at": "2016-08", + "major": "Samsung Electronics Program", + "current_position": "He is now with Samsung Electronics (삼성전자)" + }, + { + "name_ko": "김지인", + "name_en": "Ji-In Kim", + "degree": "PhD", + "graduated_at": "2016-02", + "major": null, + "current_position": "He is now with FAM Tech. (팸텍) as CEO" + }, + { + "name_ko": "김우주", + "name_en": "Woo-Ju Kim", + "degree": "MS", + "graduated_at": "2016-02", + "major": null, + "current_position": "He is now with ZCube (지큐브)" + }, + { + "name_ko": "박정섭", + "name_en": "Jung-Sub Park", + "degree": "MS", + "graduated_at": "2015-08", + "major": "Samsung Electronics Program", + "current_position": "He is now with Samsung Electronics (삼성전자)" + }, + { + "name_ko": "최종명", + "name_en": "Jong-Myoung Choi", + "degree": "MS", + "graduated_at": "2015-02", + "major": null, + "current_position": "He is now with NP Communications" + }, + { + "name_ko": "이종관", + "name_en": "Jong-Kwan Lee", + "degree": "MS", + "graduated_at": "2014-02", + "major": "Samsung Electronics Program", + "current_position": "He is now with Hanwha Ocean (한화오션)" + }, + { + "name_ko": "이상헌", + "name_en": "Sang-Hun Lee", + "degree": "MS", + "graduated_at": "2014-02", + "major": null, + "current_position": "He is now with Inno Wireless" + }, + { + "name_ko": "민경욱", + "name_en": "Kyeong-Wook Min", + "degree": "MS", + "graduated_at": "2013-02", + "major": "Samsung Electronics Program", + "current_position": "He is now with Samsung Electronics (삼성전자)" + }, + { + "name_ko": "김상헌", + "name_en": "Sang-Heon Kim", + "degree": "MS", + "graduated_at": "2013-02", + "major": "Samsung Electronics Program", + "current_position": "He is now with Samsung Electronics (삼성전자)" + }, + { + "name_ko": "Moneeb Gohar", + "name_en": "Moneeb Gohar", + "degree": "PhD", + "graduated_at": "2012-08", + "major": null, + "current_position": "He is now with Department of Computer Science, Bahria University (at Islamabad) in Pakistan" + }, + { + "name_ko": "박재완", + "name_en": "Jae-Wan Park", + "degree": "MS", + "graduated_at": "2012-02", + "major": null, + "current_position": "He is now with Ministry of Justice (Immigration Information Center, 법무부)" + }, + { + "name_ko": "이재경", + "name_en": "Jae-Kyoung Lee", + "degree": "MS", + "graduated_at": "2012-02", + "major": null, + "current_position": "She is now with Korea Transportation Satefy Authority (한국교통안전공단)" + }, + { + "name_ko": "하원기", + "name_en": "Won-Ki Ha", + "degree": "MS", + "graduated_at": "2012-02", + "major": "Samsung Electronics Program", + "current_position": "He is now with Samsung Electronics (삼성전자)" + }, + { + "name_ko": "김근희", + "name_en": "Keun-Hee Kim", + "degree": "MS", + "graduated_at": "2012-02", + "major": "Samsung Electronics Program", + "current_position": "She is now with Samsung Electronics (삼성전자)" + }, + { + "name_ko": "권순홍", + "name_en": "Soon-Hong Kwon", + "degree": "MS", + "graduated_at": "2010-02", + "major": null, + "current_position": "He is now with Samsung Electronics (삼성전자)" + }, + { + "name_ko": "김동필", + "name_en": "Dong-Phil Kim", + "degree": "PhD", + "graduated_at": "2009-02", + "major": null, + "current_position": "He is now with National Security Research Institute (국가보안연구소)" + }, + { + "name_ko": "최린", + "name_en": "Lin Cui", + "degree": "PhD", + "graduated_at": "2009-02", + "major": null, + "current_position": "He is now with Tianjin University of Technology and Education in China" + }, + { + "name_ko": "이동화", + "name_en": "Dong-Hwa Lee", + "degree": "MS", + "graduated_at": "2009-02", + "major": null, + "current_position": "He is now with Samsung Electronics (삼성전자)" + }, + { + "name_ko": "박재성", + "name_en": "Jae-Sung Park", + "degree": "MS", + "graduated_at": "2008-08", + "major": null, + "current_position": "He is now with Gom&Company (곰앤컴퍼니)" + }, + { + "name_ko": "주수경", + "name_en": "Su-Kyoung Ju", + "degree": "MS", + "graduated_at": "2008-02", + "major": null, + "current_position": "She is now with Youngjin Univ. (영진전문대학교)" + }, + { + "name_ko": "윤성식", + "name_en": "Sung-Shik Yoon", + "degree": "MS", + "graduated_at": "2007-08", + "major": null, + "current_position": "He is now with Jo-Il Textile Processing Company (조일가공) as CEO" + }, + { + "name_ko": "김상태", + "name_en": "Sang-Tae Kim", + "degree": "MS", + "graduated_at": "2007-02", + "major": null, + "current_position": "He is now with LG Electronics (LG전자)" + }, + { + "name_ko": "하종식", + "name_en": "Jong-Shik Ha", + "degree": "MS", + "graduated_at": "2007-02", + "major": null, + "current_position": "He is now with Samsung Electronics (삼성전자)" + } +] \ No newline at end of file diff --git a/backend/seed/data/lectures.json b/backend/seed/data/lectures.json new file mode 100644 index 0000000..01d512b --- /dev/null +++ b/backend/seed/data/lectures.json @@ -0,0 +1,801 @@ +[ + { + "term": "Spring", + "year": 2026, + "courses": [ + { + "code": "COMP 0414", + "en": "Computer Networks" + }, + { + "code": "ITEC 0401", + "en": "Capstone Design Project I" + } + ] + }, + { + "term": "Fall", + "year": 2025, + "courses": [ + { + "code": "COMP 0432", + "en": "Topics in Software" + }, + { + "code": "ITEC 0402", + "en": "Capstone Design Project II" + } + ] + }, + { + "term": "Spring", + "year": 2025, + "courses": [ + { + "code": "ITEC 0201", + "en": "Introduction to Computer Science and Engineering" + }, + { + "code": "EECS 0312", + "en": "Network Programming" + }, + { + "code": "ITEC 0401", + "en": "Capstone Design Project I" + }, + { + "code": "COMP 0461", + "en": "Problem-based Engineering Training Experiment" + } + ] + }, + { + "term": "Fall", + "year": 2024, + "courses": [ + { + "code": "COMP 0432", + "en": "Topics in Software" + }, + { + "code": "BIDA 0201", + "en": "Big Data Convergence Project" + }, + { + "code": "ITEC 0402", + "en": "Capstone Design Project II" + }, + { + "code": "COMP 0460", + "en": "Problem-based Engineering Training Experiment" + } + ] + }, + { + "term": "Spring", + "year": 2024, + "courses": [ + { + "code": "BIDA 0201", + "en": "Big Data Convergence Project" + }, + { + "code": "ITEC 0401", + "en": "Capstone Design Project I" + } + ] + }, + { + "term": "Fall", + "year": 2023, + "courses": [ + { + "code": "SABBATICAL", + "en": "No Class (Sabbatical)", + "note": "Sabbatical" + } + ] + }, + { + "term": "Spring", + "year": 2023, + "courses": [ + { + "code": "EECS 0312", + "en": "Network Programming" + }, + { + "code": "BIDA 0201", + "en": "Big Data Convergence Project" + }, + { + "code": "CICT 0703", + "en": "Software Convergence Project 3" + } + ] + }, + { + "term": "Fall", + "year": 2022, + "courses": [ + { + "code": "CLTR 273001", + "en": "Problem Solving and Computing" + }, + { + "code": "COMP 432001", + "en": "Topics in Software" + }, + { + "code": "ITEC 401001", + "en": "Capstone Design Project I" + } + ] + }, + { + "term": "Spring", + "year": 2022, + "courses": [ + { + "code": "EECS 312002", + "en": "Network Programming" + }, + { + "code": "ITEC 402001", + "en": "Capstone Design Project II" + }, + { + "code": "COMP 460001", + "en": "Problem-based Engineering Training Experiment" + }, + { + "code": "CICT 701001", + "en": "Software Convergence Project 1" + } + ] + }, + { + "term": "Fall", + "year": 2021, + "courses": [ + { + "code": "ITEC 402001", + "en": "Capstone Design Project II" + } + ] + }, + { + "term": "Spring", + "year": 2021, + "courses": [ + { + "code": "CLTR 273001", + "en": "Problem Solving and Computing" + }, + { + "code": "GLSO 218001", + "en": "Software Convergence Design 1" + }, + { + "code": "ITEC 402001", + "en": "Capstone Design Project II" + }, + { + "code": "COMP 778001", + "en": "Advanced Mobile Computing" + } + ] + }, + { + "term": "Fall", + "year": 2020, + "courses": [ + { + "code": "ITEC 401003", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 401004", + "en": "Capstone Design Project I" + }, + { + "code": "GLSO 228001", + "en": "Topics in Software Convergence IV" + } + ] + }, + { + "term": "Spring", + "year": 2020, + "courses": [ + { + "code": "ITEC 401016", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 402003", + "en": "Capstone Design Project II" + }, + { + "code": "COMP 778001", + "en": "Advanced Mobile Computing" + } + ] + }, + { + "term": "Fall", + "year": 2019, + "courses": [ + { + "code": "COMP 432001", + "en": "Topics in Software" + }, + { + "code": "ITEC 401003", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 402016", + "en": "Capstone Design Project II" + } + ] + }, + { + "term": "Spring", + "year": 2019, + "courses": [ + { + "code": "ITEC 201010", + "en": "Introduction to Computer Science and Engineering" + }, + { + "code": "ITEC 401016", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 402003", + "en": "Capstone Design Project II" + } + ] + }, + { + "term": "Fall", + "year": 2018, + "courses": [ + { + "code": "ITEC 401005", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 402017", + "en": "Capstone Design Project II" + } + ] + }, + { + "term": "Spring", + "year": 2018, + "courses": [ + { + "code": "ITEC 401021", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 402006", + "en": "Capstone Design Project II" + } + ] + }, + { + "term": "Fall", + "year": 2017, + "courses": [ + { + "code": "COMP 432001", + "en": "Topics in Software" + }, + { + "code": "GLSO 213001", + "en": "Creative Convergence Design" + }, + { + "code": "ITEC 401003", + "en": "Capstone Design Project I" + } + ] + }, + { + "term": "Spring", + "year": 2017, + "courses": [ + { + "code": "EECS 312001", + "en": "Network Programming" + }, + { + "code": "ITEC 401018", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 402005", + "en": "Capstone Design Project II" + }, + { + "code": "COME 742001", + "en": "Advanced Computer Networks" + } + ] + }, + { + "term": "Fall", + "year": 2016, + "courses": [ + { + "code": "COMP 432001", + "en": "Topics in Software" + }, + { + "code": "COME 331013) and DS Applications (COMP 216002", + "en": "Data Structures" + }, + { + "code": "ITEC 401004", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 402016", + "en": "Capstone Design Project II" + } + ] + }, + { + "term": "Spring", + "year": 2016, + "courses": [ + { + "code": "COMP 414003", + "en": "Computer Networks" + }, + { + "code": "ITEC 401031", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 402005", + "en": "Capstone Design Project II" + }, + { + "code": "ITEC 402006", + "en": "Capstone Design Project II" + } + ] + }, + { + "term": "Fall", + "year": 2015, + "courses": [ + { + "code": "COMP 432001", + "en": "Topics in Software" + }, + { + "code": "ITEC 401006", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 401007", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 402022", + "en": "Capstone Design Project II" + } + ] + }, + { + "term": "Spring", + "year": 2015, + "courses": [ + { + "code": "ITEC 201009", + "en": "Introduction to Computer Science and Engineering" + }, + { + "code": "EECS 312001", + "en": "Network Programming" + }, + { + "code": "EECS 312002", + "en": "Network Programming" + }, + { + "code": "ITEC 401021", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 402004", + "en": "Capstone Design Project II" + } + ] + }, + { + "term": "Fall", + "year": 2014, + "courses": [ + { + "code": "ITEC 401006", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 402021", + "en": "Capstone Design Project II" + }, + { + "code": "COME 742001", + "en": "Advanced Computer Networks" + } + ] + }, + { + "term": "Spring", + "year": 2014, + "courses": [ + { + "code": "COMP 414002", + "en": "Computer Networks" + }, + { + "code": "ITEC 402004", + "en": "Capstone Design Project II" + } + ] + }, + { + "term": "Fall", + "year": 2013, + "courses": [ + { + "code": "ITEC 401005", + "en": "Capstone Design Project I" + }, + { + "code": "ITEC 402017", + "en": "Capstone Design Project II" + } + ] + }, + { + "term": "Spring", + "year": 2013, + "courses": [ + { + "code": "COMP 432001", + "en": "Topics in Software" + }, + { + "code": "ITEC 402005", + "en": "Capstone Design Project II" + } + ] + }, + { + "term": "Fall", + "year": 2012, + "courses": [ + { + "code": "COMP 432001", + "en": "Topics in Software" + }, + { + "code": "ITEC 401003", + "en": "Capstone Design Project I" + }, + { + "code": "EECS 422021", + "en": "Senior Project II" + } + ] + }, + { + "term": "Spring", + "year": 2012, + "courses": [ + { + "code": "COMP 214002", + "en": "Web Programming Design" + }, + { + "code": "COMP 749001", + "en": "Computer Network Protocols" + }, + { + "code": "ELEC 957001", + "en": "Next Generation Internet Technology" + } + ] + }, + { + "term": "Fall", + "year": 2011, + "courses": [ + { + "code": "COME 311003", + "en": "Probability and Statistics: Class 1" + }, + { + "code": "COME 311004", + "en": "Probability and Statistics: Class 2" + }, + { + "code": "COMP 764001", + "en": "Internet Computing" + }, + { + "code": "COMP 432001", + "en": "Topics in Software" + } + ] + }, + { + "term": "Spring", + "year": 2011, + "courses": [ + { + "code": "COMP 214001", + "en": "Web Programming Design: Class 1" + }, + { + "code": "COMP 214002", + "en": "Web Programming Design: Class 2" + } + ] + }, + { + "term": "Fall", + "year": 2010, + "courses": [ + { + "code": "COME 311003", + "en": "Probability and Statistics" + }, + { + "code": "COME 331004", + "en": "Data Structures" + }, + { + "code": "EECS 422022", + "en": "Senior Project II" + } + ] + }, + { + "term": "Spring", + "year": 2010, + "courses": [ + { + "code": "EECS 450001", + "en": "Internet Programming Design" + }, + { + "code": "COMP 414003", + "en": "Computer Networks" + }, + { + "code": "ELEC 957001", + "en": "Next-Generation Internet Technology" + }, + { + "code": "EECS 408016", + "en": "Senior Project I" + } + ] + }, + { + "term": "Fall", + "year": 2009, + "courses": [ + { + "code": "COME 31103", + "en": "Probability and Statistics" + }, + { + "code": "COME 33105", + "en": "Data Structures" + }, + { + "code": "EECS 42202", + "en": "Senior Project II" + } + ] + }, + { + "term": "Spring", + "year": 2009, + "courses": [ + { + "code": "EECS 20704", + "en": "Introduction to Computer Science" + }, + { + "code": "EECS 45001", + "en": "Internet Programming Design" + }, + { + "code": "EECS 40803", + "en": "Senior Project I" + } + ] + }, + { + "term": "Fall", + "year": 2008, + "courses": [ + { + "code": "COME 31103", + "en": "Probability and Statistics" + }, + { + "code": "COMP 76401", + "en": "Internet Computing" + }, + { + "code": "ELEC 75401", + "en": "Computer Network: Special" + } + ] + }, + { + "term": "Spring", + "year": 2008, + "courses": [ + { + "code": "EECS 31401", + "en": "Internet Programming and Practices" + }, + { + "code": "COMP 74901", + "en": "Computer Network Protocols" + } + ] + }, + { + "term": "Fall", + "year": 2007, + "courses": [ + { + "code": "EECS 20703", + "en": "Introduction to Computer Science" + }, + { + "code": "COME 31103", + "en": "Probability and Statistics" + }, + { + "code": "COMP 41401", + "en": "Computer Networks" + } + ] + }, + { + "term": "Spring", + "year": 2007, + "courses": [ + { + "code": "EECS 20109", + "en": "C Programming and Practices" + }, + { + "code": "EECS 20704", + "en": "Introduction to Computer Science" + }, + { + "code": "EECS 31401", + "en": "Internet Programming and Practices" + } + ] + }, + { + "term": "Fall", + "year": 2006, + "courses": [ + { + "code": "EECS 20703", + "en": "Introduction to Computer Science" + }, + { + "code": "COME 31103", + "en": "Probability and Statistics" + }, + { + "code": "COMP 76401", + "en": "Internet Computing" + } + ] + }, + { + "term": "Spring", + "year": 2006, + "courses": [ + { + "code": "EECS 20704", + "en": "Introduction to Computer Science" + }, + { + "code": "EECS 31401", + "en": "Internet Programming and Practices" + }, + { + "code": "COMP 75101", + "en": "Computer Performance Analysis" + } + ] + }, + { + "term": "Fall", + "year": 2005, + "courses": [ + { + "code": "EECS 20703", + "en": "Introduction to Computer Science" + }, + { + "code": "EECS 20806", + "en": "Data Structures" + }, + { + "code": "COMP 41402", + "en": "Computer Network" + } + ] + }, + { + "term": "Spring", + "year": 2005, + "courses": [ + { + "code": "EECS 20704", + "en": "Introduction to Computer Science" + }, + { + "code": "EECS 49201", + "en": "Internet Programming Design" + }, + { + "code": "COMP 74901", + "en": "Computer Network Protocols" + } + ] + }, + { + "term": "Fall", + "year": 2004, + "courses": [ + { + "code": "ELEC 26104", + "en": "Computer Engineering" + }, + { + "code": "COMP 22101", + "en": "Data Structures II" + }, + { + "code": "EECS 31201", + "en": "Network Programming" + } + ] + }, + { + "term": "Spring", + "year": 2004, + "courses": [ + { + "code": "EECS 20704", + "en": "Introduction to Computer Science" + }, + { + "code": "COMP 21105", + "en": "Data Structures I" + } + ] + } +] \ No newline at end of file diff --git a/backend/seed/data/members.json b/backend/seed/data/members.json new file mode 100644 index 0000000..cce0bc3 --- /dev/null +++ b/backend/seed/data/members.json @@ -0,0 +1,146 @@ +[ + { + "name_ko": "고석주", + "name_en": "Seok-Joo Koh", + "degree": "Professor", + "affiliation": null, + "email": "sjkoh@knu.ac.kr", + "is_advisor": true, + "display_order": 1 + }, + { + "name_ko": "최동규", + "name_en": "Dong-Kyu Choi", + "degree": "PhD", + "affiliation": null, + "email": null, + "is_advisor": false, + "display_order": 2 + }, + { + "name_ko": "남혜빈", + "name_en": "Hye-Been Nam", + "degree": "PhDCandidate", + "affiliation": null, + "email": null, + "is_advisor": false, + "display_order": 3 + }, + { + "name_ko": "임도현", + "name_en": "Dohyeon Lim", + "degree": "PhDStudent", + "affiliation": null, + "email": null, + "is_advisor": false, + "display_order": 4 + }, + { + "name_ko": "최준혁", + "name_en": "Jun-Hyeok Choi", + "degree": "PhDStudent", + "affiliation": null, + "email": null, + "is_advisor": false, + "display_order": 5 + }, + { + "name_ko": "신광선", + "name_en": "Gwang-Seon Shin", + "degree": "MSCandidate", + "affiliation": null, + "email": null, + "is_advisor": false, + "display_order": 6 + }, + { + "name_ko": "이환웅", + "name_en": "Hwan-Woong Lee", + "degree": "MSStudent", + "affiliation": null, + "email": null, + "is_advisor": false, + "display_order": 7 + }, + { + "name_ko": "Hoang Anh Dang", + "name_en": "Hoang Anh Dang", + "degree": "MSStudent", + "affiliation": null, + "email": null, + "is_advisor": false, + "display_order": 8 + }, + { + "name_ko": "김민희", + "name_en": "Minhee Kim", + "degree": "PhDCandidate", + "affiliation": "School of Computer Science and Engineering", + "email": null, + "is_advisor": false, + "display_order": 9 + }, + { + "name_ko": "김근솔", + "name_en": "Keun-Sol Kim", + "degree": "PhDCandidate", + "affiliation": "Department of Information Security", + "email": null, + "is_advisor": false, + "display_order": 10 + }, + { + "name_ko": "민성준", + "name_en": "Sung-Jun Min", + "degree": "PhDCandidate", + "affiliation": "Department of Information Science", + "email": null, + "is_advisor": false, + "display_order": 11 + }, + { + "name_ko": "최진원", + "name_en": "Jin-Won Choi", + "degree": "PhDStudent", + "affiliation": "Department of Science and Technology", + "email": null, + "is_advisor": false, + "display_order": 12 + }, + { + "name_ko": "정기수", + "name_en": "Ki-Soo Jung", + "degree": "PhDStudent", + "affiliation": "Department of Science and Technology", + "email": null, + "is_advisor": false, + "display_order": 13 + }, + { + "name_ko": "이미주", + "name_en": "Mi-Joo Lee", + "degree": "PhDStudent", + "affiliation": "Department of ICT Convergence", + "email": null, + "is_advisor": false, + "display_order": 14 + }, + { + "name_ko": "박유나", + "name_en": "Yunah Park", + "degree": "MSCandidate", + "affiliation": "Department of Information Security", + "email": null, + "is_advisor": false, + "display_order": 15 + }, + { + "name_ko": "박채영", + "name_en": "Chae-Young Park", + "degree": "MSCandidate", + "affiliation": "Department of Information Science", + "email": null, + "is_advisor": false, + "display_order": 16 + } +] \ No newline at end of file diff --git a/backend/seed/data/patents.json b/backend/seed/data/patents.json new file mode 100644 index 0000000..a8e2db5 --- /dev/null +++ b/backend/seed/data/patents.json @@ -0,0 +1,752 @@ +[ + { + "title": "국내 지역별 태양광 발전량 및 전력 단가 예측 웹 서비스 제공 장치 및 그 방법", + "inventors": "고석주, 김경훈, 김나현, 정수인, 홍일표", + "application_no": "2025-0200788", + "application_at": "2025-12-16", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2025-12" + }, + { + "title": "사물인터넷 네트워크 환경에서 QUIC 기반으로 CoAP 메시지를 중계하는 시스템", + "inventors": "고석주, 정중화, 남혜빈, 최동규, 김민지", + "application_no": "2023-0180751", + "application_at": "2023-12-13", + "registration_no": "2963109", + "registration_at": "2026-05-06", + "country": "한국", + "published_at": "2023-12" + }, + { + "title": "엣지 컴퓨팅을 위한 사물인터넷 서비스 시스템", + "inventors": "고석주, 정중화, 남혜빈, 최동규", + "application_no": "2023-0161365", + "application_at": "2023-11-20", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2023-11" + }, + { + "title": "무선 네트워크 환경에서 핸드오버 및 커넥션 마이그레이션을 지원하는 장치 및 방법", + "inventors": "고석주, 김소용, 모닙 고하르, 최동규", + "application_no": "2023-0063455", + "application_at": "2023-05-17", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2023-05" + }, + { + "title": "제한된 통신 환경에서 브로커 서버를 이용한 스마트 약상자 제어 시스템 및 방법", + "inventors": "고석주, 김근수, 김철민, 김경식, 나재욱, 박진호", + "application_no": "2020-0164156", + "application_at": "2020-11-30", + "registration_no": "2384614", + "registration_at": "2022-04-05", + "country": "한국", + "published_at": "2020-11" + }, + { + "title": "단방향 가시광 통신 환경에서 데이터 전송 신뢰성 개선을 위한 방법 및 이를 이용한 하이브리드", + "inventors": "고석주, 김소용, 최동규, 남혜빈, 정중화, 김창묵", + "application_no": "2020-0164152", + "application_at": "2020-11-30", + "registration_no": "2420614", + "registration_at": "2022-07-08", + "country": "한국", + "published_at": "2020-11" + }, + { + "title": "사물 인터넷 서비스를 제공하기 위한 QUIC-Proxy를 이용한 데이터 전달 방법 및 장치", + "inventors": "고석주, 김소용, 최동규, 남혜빈, 정중화", + "application_no": "2020-0164141", + "application_at": "2020-11-30", + "registration_no": "2345473", + "registration_at": "2021-12-27", + "country": "한국", + "published_at": "2020-11" + }, + { + "title": "금연구역 관리 서비스 방법 및 시스템", + "inventors": "고석주, 이정우, 이용호, 권오상, 정서영, 김경식", + "application_no": "2020-0101365", + "application_at": "2020-08-12", + "registration_no": "2375686", + "registration_at": "2022-03-14", + "country": "한국", + "published_at": "2020-08" + }, + { + "title": "사물 인터넷 환경에서 CoAP 기반의 데이터 스트리밍 방법 및 통신 시스템", + "inventors": "고석주, 정중화, 최동규, 남혜빈, 이채현", + "application_no": "2020-0094058", + "application_at": "2020-07-28", + "registration_no": "2375703", + "registration_at": "2022-03-14", + "country": "한국", + "published_at": "2020-07" + }, + { + "title": "인공지능 기반 적외선 카메라 센싱 시스템 및 방법", + "inventors": "고석주, 홍성기, 김희원, 박명훈, 권민철", + "application_no": "2019-0174964", + "application_at": "2019-12-26", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2019-12" + }, + { + "title": "폭력 행위 관리 시스템 및 방법", + "inventors": "고석주, 김동욱, 윤서원, 구영준, 성경화, 경예지", + "application_no": "2019-0122161", + "application_at": "2019-10-02", + "registration_no": "2264275", + "registration_at": "2021-06-07", + "country": "한국", + "published_at": "2019-10" + }, + { + "title": "차량 인포테인먼트 관리 시스템", + "inventors": "고석주, 최동규, 정중화, 남혜빈, 손종명", + "application_no": "2019-0120044", + "application_at": "2019-09-27", + "registration_no": "2410024", + "registration_at": "2022-06-13", + "country": "한국", + "published_at": "2019-09" + }, + { + "title": "차량 인포테인먼트 마스터 장치 및 이를 포함하는 차량 인포테인먼트 통합 관리 시스템", + "inventors": "고석주, 최동규, 정중화, 남혜빈, 신호경", + "application_no": "2019-0059551", + "application_at": "2019-05-21", + "registration_no": "2251310", + "registration_at": "2021-05-06", + "country": "한국", + "published_at": "2019-05" + }, + { + "title": "CoAP 기반의 센싱 정보 스트리밍 방법", + "inventors": "고석주, 최동규, 정중화, 남혜빈", + "application_no": "2018-0168580", + "application_at": "2018-12-24", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2018-12" + }, + { + "title": "이미지에서 기계학습 기법을 활용한 특정 부품영역 탐지 방법", + "inventors": "고석주, 김대기, 김동인, 방종원, 우진철, 정중화", + "application_no": "2018-0167974", + "application_at": "2018-12-21", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2018-12" + }, + { + "title": "블록체인 기반의 재정장부 관리 시스템", + "inventors": "고석주, 신승민, 서상민, 송동훈, 최효선, 그레고즈 리뼤시치", + "application_no": "2018-0167970", + "application_at": "2018-12-21", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2018-12" + }, + { + "title": "블록체인을 이용한 게임정보 처리 방법", + "inventors": "고석주, 정재훈, 서창호, 노경환, 원응호", + "application_no": "2018-0167951", + "application_at": "2018-12-21", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2018-12" + }, + { + "title": "가시광 통신을 이용한 서비스 제공 시스템 및 그 방법", + "inventors": "고석주, 김철민, 김소용, 모닙고하르", + "application_no": "2018-0155013", + "application_at": "2018-12-05", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2018-12" + }, + { + "title": "차량 인포테인먼트 시스템", + "inventors": "고석주, 최동규, 정중화, 정민우", + "application_no": "2018-0083515", + "application_at": "2018-07-18", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2018-07" + }, + { + "title": "CoAP 기반의 사물인터넷 기술을 이용한 센서 관리 방법 및 이를 이용한 시스템", + "inventors": "고석주, 최동규, 정중화, 정민우", + "application_no": "2018-0082485", + "application_at": "2018-07-16", + "registration_no": "2071974", + "registration_at": "2020-01-23", + "country": "한국", + "published_at": "2018-07" + }, + { + "title": "가시광 통신을 이용한 무선 인터넷 비밀번호 관리 시스템 및 방법", + "inventors": "김소용, 김철민, 고석주", + "application_no": "2018-0082463", + "application_at": "2018-07-16", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2018-07" + }, + { + "title": "시각 장애인을 위한 가시광 통신 기반의 교통 신호 전달 시스템 및 방법", + "inventors": "권경동, 금동우, 황지영, 채윤창, 김철민, 김소용, 고석주", + "application_no": "2018-0079319", + "application_at": "2018-07-09", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2018-07" + }, + { + "title": "데이터 전달 장치, 방법과 그를 이용한 사물 인터넷 시스템, 데이터 전달 방법을 실행하기 위한 프로그램이", + "inventors": "고석주, 최동규, 정중화", + "application_no": "2017-0153908", + "application_at": "2017-11-17", + "registration_no": "1969652", + "registration_at": "2019-04-10", + "country": "한국", + "published_at": "2017-11" + }, + { + "title": "분산된 게시-구독 기법을 이용한 CoAP 기반 사물 인터넷 시스템의 작동 방법", + "inventors": "고석주, 정중화, 최동규", + "application_no": "2017-0153357", + "application_at": "2017-11-16", + "registration_no": "2031726", + "registration_at": "2019-10-07", + "country": "한국", + "published_at": "2017-11" + }, + { + "title": "비콘 기반 식당 정보 서비스 시스템 및 방법", + "inventors": "고석주, 안창준, 김혜경, 송명근, 최예찬, 허동", + "application_no": "2017-0087265", + "application_at": "2017-07-10", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2017-07" + }, + { + "title": "사물 인터넷 네트워크에서의 모바일 단말 이동성 제어 장치 및 방법", + "inventors": "고석주, 최상일", + "application_no": "2017-0064039", + "application_at": "2017-05-24", + "registration_no": "1847081", + "registration_at": "2018-04-03", + "country": "한국", + "published_at": "2017-05" + }, + { + "title": "데이터 전달 장치, 방법 및 그를 이용한 사물인터넷 시스템", + "inventors": "고석주, 정중화, 강형우, 최동규", + "application_no": "2016-0175882", + "application_at": "2016-12-21", + "registration_no": "1972470", + "registration_at": "2019-04-19", + "country": "한국", + "published_at": "2016-12" + }, + { + "title": "저전력 근거리 통신을 이용한 개인 정보 교환 방법 및 시스템, 이를 수행하기 위한 기록매체", + "inventors": "고석주, 김지인, 김지희, 김송아, 박지혜, 이승일, 서대화", + "application_no": "2016-0157411", + "application_at": "2016-11-24", + "registration_no": "1784309", + "registration_at": "2017-09-27", + "country": "한국", + "published_at": "2016-11" + }, + { + "title": "가시광 통신 기기 관리 방법 및 장치 (with 유양디앤유)", + "inventors": "김상옥, 유병오, 윤상호, 노승완, 고석주, 최상일", + "application_no": "2016-0157606", + "application_at": "2016-11-24", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2016-11" + }, + { + "title": "가시광 통신 방법 및 장치 (with 유양디앤유)", + "inventors": "김상옥, 유병오, 윤상호, 노승완, 고석주, 최상일", + "application_no": "2016-0157576", + "application_at": "2016-11-24", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2016-11" + }, + { + "title": "이동 단말 및 관리 서버의 제어 방법", + "inventors": "고석주, 최상일", + "application_no": "2016-0051126", + "application_at": "2016-04-26", + "registration_no": "1836116", + "registration_at": "2018-03-02", + "country": "한국", + "published_at": "2016-04" + }, + { + "title": "무선 통신을 이용한 범용 안내 서비스 제공 방법 및 시스템", + "inventors": "고석주, 장호영, 이종훈, 박찬석, 서민영", + "application_no": "2016-0013614", + "application_at": "2016-02-03", + "registration_no": "1716661", + "registration_at": "2017-03-09", + "country": "한국", + "published_at": "2016-02" + }, + { + "title": "디지털 도어락 시스템 및 그 제어 방법", + "inventors": "고석주, 권다영, 노혜성, 이수정", + "application_no": "2015-0163735", + "application_at": "2015-11-23", + "registration_no": "1814555", + "registration_at": "2017-12-27", + "country": "한국", + "published_at": "2015-11" + }, + { + "title": "무인 지상차량을 이용한 주차차량 관리 시스템", + "inventors": "김인한, 권혜련, 이은섭, 고석주", + "application_no": "2015-0008735", + "application_at": "2015-01-19", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2015-01" + }, + { + "title": "ESL 신호를 이용하는 측위 방법, 이를 수행하기 위한 기록 매체, 단말기 및 시스템", + "inventors": "고석주, 김지인, 이민형, 김종근, 박지수, 조정근, 이승일, 서대화", + "application_no": "2014-0180037", + "application_at": "2014-12-15", + "registration_no": "1596320", + "registration_at": "2016-02-16", + "country": "한국", + "published_at": "2014-12" + }, + { + "title": "ESL 신호를 이용하여 위치 기반 서비스를 제공하는 스마트 장치", + "inventors": "고석주, 김지인, 이민형, 김종근, 박지수, 조정근, 이승일, 서대화", + "application_no": "2014-0180036", + "application_at": "2014-12-15", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2014-12" + }, + { + "title": "3차원 형상 복원을 위한 볼륨 카빙 장치 및 그 방법", + "inventors": "고석주, 하태윤, 서대화, 정귀영, 이상은, 김지인, 김한별", + "application_no": "2014-0167063", + "application_at": "2014-11-27", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2014-11" + }, + { + "title": "립모션 기기를 이용한 수화 번역 시스템 및 그 방법", + "inventors": "고석주, 조재현, 서대화, 이동훈, 이상은, 김지인, 하대규", + "application_no": "2014-0166166", + "application_at": "2014-11-26", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2014-11" + }, + { + "title": "립모션 기기의 수화 번역 정확도 향상을 위한 수화 번역 시스템 및 그 방법", + "inventors": "고석주, 조재현, 서대화, 이동훈, 이상은, 김지인, 하대규", + "application_no": "2014-0166165", + "application_at": "2014-11-26", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2014-11" + }, + { + "title": "저전력 근거리 통신을 이용한 개인 정보 교환 방법 및 시스템, 이를 수행하기 위한 기록매체", + "inventors": "고석주, 김지희, 서대화, 박지혜, 이승일, 김지인, 김송아", + "application_no": "2014-0164802", + "application_at": "2014-11-24", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2014-11" + }, + { + "title": "차량 분산 방법 및 장치, 이를 수행하기 위한 기록매체", + "inventors": "고석주, 김지인, 엄진욱, 김민규, 홍석진, 배정규, 서대화", + "application_no": "2014-0161975", + "application_at": "2014-11-19", + "registration_no": "1612047", + "registration_at": "2016-04-06", + "country": "한국", + "published_at": "2014-11" + }, + { + "title": "신규 액세스 포인트의 위치 인식 방법 및 이를 이용하는 서버", + "inventors": "고석주, 김우주, 이민형, 하태윤, 심대섭, 조정근, 강보영, 서대화", + "application_no": "2013-0167207", + "application_at": "2013-12-30", + "registration_no": "1568365", + "registration_at": "2015-11-05", + "country": "한국", + "published_at": "2013-12" + }, + { + "title": "디바이스 탐색 장치 및 디바이스 탐색 방법", + "inventors": "고석주, 이상헌, 최상일", + "application_no": "2013-0140737", + "application_at": "2013-11-19", + "registration_no": "1405248", + "registration_at": "2015-04-17", + "country": "한국", + "published_at": "2013-11" + }, + { + "title": "오픈플로우 통신 시스템 및 방법", + "inventors": "고석주, 김지인, 최낙중", + "application_no": "2013-0140736", + "application_at": "2013-11-19", + "registration_no": "1525047", + "registration_at": "2015-05-27", + "country": "한국", + "published_at": "2013-11" + }, + { + "title": "이동통신 시스템의 추적 영역 코드 구성 장치 및 방법", + "inventors": "고석주, 강형우, 백태산, 강현구", + "application_no": "2013-0140734", + "application_at": "2013-11-19", + "registration_no": "1538453", + "registration_at": "2015-07-15", + "country": "한국", + "published_at": "2013-11" + }, + { + "title": "프로세스 모니터링과 키보드 잠금을 이용한 프로세스 관리 방법 및 프로세스 관리 장치", + "inventors": "고석주, 박진호, 이재휘", + "application_no": "2013-0108587", + "application_at": "2013-09-10", + "registration_no": "1515493", + "registration_at": "2015-04-21", + "country": "한국", + "published_at": "2013-09" + }, + { + "title": "공유기 탐지 장치 및 공유기 탐지 방법", + "inventors": "고석주, 박진호, 김철민", + "application_no": "2013-0091483", + "application_at": "2013-08-01", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2013-08" + }, + { + "title": "호스트 식별 프로토콜 네트워크 환경의 통신 시스템 및 방법", + "inventors": "고석주, 최상일", + "application_no": "2012-0154836", + "application_at": "2012-12-27", + "registration_no": "1405248", + "registration_at": "2014-06-02", + "country": "한국", + "published_at": "2012-12" + }, + { + "title": "액세스 라우터 및 그를 이용한 핸드오버 제어 방법", + "inventors": "고석주, 최낙중, 김지인", + "application_no": "2012-0154835", + "application_at": "2012-12-27", + "registration_no": "1447104", + "registration_at": "2014-09-26", + "country": "한국", + "published_at": "2012-12" + }, + { + "title": "호스트 식별 프로토콜 네트워크 환경의 이동통신 시스템 및 방법", + "inventors": "고석주, 김지인, 이상헌", + "application_no": "2012-0146740", + "application_at": "2012-12-14", + "registration_no": "1459628", + "registration_at": "2014-11-03", + "country": "한국", + "published_at": "2012-12" + }, + { + "title": "라우터의 호스트 위치 관리 방법", + "inventors": "고석주, 김지인", + "application_no": "2012-0030058", + "application_at": "2012-03-23", + "registration_no": "1356721", + "registration_at": "2014-01-20", + "country": "한국", + "published_at": "2012-03" + }, + { + "title": "분산형 구조를 이용한 데이터 통신 방법", + "inventors": "고석주, 모닙고하르, 이재경", + "application_no": "2011-0111384", + "application_at": "2011-10-28", + "registration_no": "1311864", + "registration_at": "2013-09-17", + "country": "한국", + "published_at": "2011-10" + }, + { + "title": "라우터, 그것을 포함하는 통신 네트워크 시스템 및 그것의 이동성 제어 방법", + "inventors": "고석주, 최상일", + "application_no": "2011-0107533", + "application_at": "2011-10-20", + "registration_no": "1329331", + "registration_at": "2013-11-07", + "country": "한국", + "published_at": "2011-10" + }, + { + "title": "모바일 액세스 게이트웨이 및 이를 이용한 이동성 제어 방법", + "inventors": "고석주, 김지인", + "application_no": "2011-0057608", + "application_at": "2011-06-14", + "registration_no": "1223047", + "registration_at": "2013-01-10", + "country": "한국", + "published_at": "2011-06" + }, + { + "title": "멀티홈잉 환경에서 프록시 모바일 인터넷 프로토콜을 사용하는 이동통신 시스템 및 그것의 핸드오버 방법", + "inventors": "고석주, 김지인", + "application_no": "2011-0001905", + "application_at": "2011-01-07", + "registration_no": "1189140", + "registration_at": "2012-10-02", + "country": "한국", + "published_at": "2011-01" + }, + { + "title": "멀티캐스트 방법 및 억세스 게이트웨이", + "inventors": "고석주, 모닙고하르, 이재경", + "application_no": "2010-0137897", + "application_at": "2010-12-29", + "registration_no": "1200407", + "registration_at": "2012-11-06", + "country": "한국", + "published_at": "2010-12" + }, + { + "title": "프록시 모바일 인터넷 프로토콜을 사용하는 이동통신 시스템 및 그것의 핸드오버 방법", + "inventors": "고석주, 김지인", + "application_no": "2010-0108058", + "application_at": "2010-11-02", + "registration_no": "1258238", + "registration_at": "2013-04-19", + "country": "한국", + "published_at": "2010-11" + }, + { + "title": "이동 단말, 통신 네트워크 및 그것의 이동성 제어 방법", + "inventors": "고석주, 최상일", + "application_no": "2010-0107701", + "application_at": "2010-11-01", + "registration_no": "1177354", + "registration_at": "2012-08-21", + "country": "한국", + "published_at": "2010-11" + }, + { + "title": "빠른 핸드오버를 지원하기 위한 이동통신 시스템 및 방법", + "inventors": "고석주, 모닙고하르, 박재완", + "application_no": "2010-0039688", + "application_at": "2010-04-28", + "registration_no": "1091397", + "registration_at": "2011-12-01", + "country": "한국", + "published_at": "2010-04" + }, + { + "title": "이동 단말간 데이터 전송 시스템 및 그 방법", + "inventors": "고석주, 권순홍", + "application_no": "2009-0048797", + "application_at": "2009-06-02", + "registration_no": "1078156", + "registration_at": "2011-10-24", + "country": "한국", + "published_at": "2009-06" + }, + { + "title": "프록시 모바일 IPv6망내 이동단말간 통신 경로 최적화 시스템 및 그 방법", + "inventors": "고석주, 김지인", + "application_no": "2009-0048796", + "application_at": "2009-06-02", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2009-06" + }, + { + "title": "이종 무선망간 수직 핸드오버를 위한 이동 SCTP의 적응적 혼잡 제어 방법 및 장치", + "inventors": "고석주, 김동필", + "application_no": "2009-0013072", + "application_at": "2009-02-17", + "registration_no": "1048251", + "registration_at": "2011-07-04", + "country": "한국", + "published_at": "2009-02" + }, + { + "title": "서비스 품질 향상을 위한 PR-SCTP 기반 실시간 멀티미디어 데이터 전송 방법", + "inventors": "고석주, 김상태", + "application_no": "2008-0135342", + "application_at": "2008-12-29", + "registration_no": "1040780", + "registration_at": "2011-06-03", + "country": "한국", + "published_at": "2008-12" + }, + { + "title": "이종 무선망간의 수직적 핸드오버를 위한 데이터 전송 방법 및 장치", + "inventors": "고석주, 김동필", + "application_no": "2008-0083995", + "application_at": "2008-08-27", + "registration_no": "0980592", + "registration_at": "2010-08-31", + "country": "한국", + "published_at": "2008-08" + }, + { + "title": "무선통신용 멀티캐스트 핸드오버 방법", + "inventors": "고석주, 박재성", + "application_no": "2008-0077918", + "application_at": "2008-08-08", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2008-08" + }, + { + "title": "무선 인터넷 망에서의 바이캐스팅을 이용한 SIP 핸드오버 방법 및 이동 단말", + "inventors": "고석주, 이동화", + "application_no": "2008-0052456", + "application_at": "2008-06-04", + "registration_no": "0987555", + "registration_at": "2010-10-06", + "country": "한국", + "published_at": "2008-06" + }, + { + "title": "무선 인터넷 환경에서의 바이캐스팅 기반 SCTP 핸드오버 방법 및 이동 단말", + "inventors": "고석주, 권순홍, 김동필", + "application_no": "2008-0049203", + "application_at": "2008-05-27", + "registration_no": "0980582", + "registration_at": "2010-08-31", + "country": "한국", + "published_at": "2008-05" + }, + { + "title": "Proxy MIP 기반 무선 인터넷 망에서의 바이캐스팅을 이용한 핸드오버 방법 및 장치", + "inventors": "고석주, 김지인", + "application_no": "2008-0049153", + "application_at": "2008-05-27", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2008-05" + }, + { + "title": "윈도우 기반의 이동 단말에서 SCTPLIB를 이용한 mSCTP 핸드오버 방법", + "inventors": "김용진, 고석주, 이동화, 김상태", + "application_no": "2007-0139730", + "application_at": "2007-12-28", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2007-12" + }, + { + "title": "전송 처리율 향상을 위한 SCTP 우선경로 설정 방법", + "inventors": "고석주, 주수경", + "application_no": "2007-0102031", + "application_at": "2007-10-10", + "registration_no": null, + "registration_at": null, + "country": "한국", + "published_at": "2007-10" + }, + { + "title": "무선 네트워크에서 패킷의 손상정보를 사용하는 TCP 혼잡제어 방법", + "inventors": "고석주, 최린, 이동화, 김용진", + "application_no": "2007-0061209", + "application_at": "2007-06-21", + "registration_no": "0870619", + "registration_at": "2008-11-19", + "country": "한국", + "published_at": "2007-06" + }, + { + "title": "이동 단말의 SCTP 핸드오버와 모바일 아이피의 연동 장치 및 그 방법", + "inventors": "고석주, 김동필", + "application_no": "2007-0050648", + "application_at": "2007-05-25", + "registration_no": "0880112", + "registration_at": "2009-01-15", + "country": "한국", + "published_at": "2007-05" + }, + { + "title": "청크첵섬을 사용하는 무선 인터넷 에스씨티피 송수신 시스템 및 방법", + "inventors": "김용진, 정종일, 고석주", + "application_no": "2006-0117121", + "application_at": "2006-11-24", + "registration_no": "0780921", + "registration_at": "2007-11-23", + "country": "한국", + "published_at": "2006-11" + }, + { + "title": "데이터 링크계층의 링크 정보를 이용하여 핸드오버를 수행하는 단말장치", + "inventors": "고석주, 김동필", + "application_no": "2005-0110213", + "application_at": "2005-11-17", + "registration_no": "0685740", + "registration_at": "2007-02-15", + "country": "한국", + "published_at": "2005-11" + }, + { + "title": "SCTP 기반의 핸드오버 기능을 구비한 단말장치 및 핸드오버 방법", + "inventors": "고석주, 김동필", + "application_no": "US 11-915457 (미국, 2007.11.26)", + "application_at": "2005-05-27", + "registration_no": "US 8,644,248 (미국, 2014.2.4)", + "registration_at": "2007-01-26", + "country": "한국", + "published_at": "2005-05" + } +] \ No newline at end of file diff --git a/backend/seed/data/publications.json b/backend/seed/data/publications.json new file mode 100644 index 0000000..8633b33 --- /dev/null +++ b/backend/seed/data/publications.json @@ -0,0 +1,1630 @@ +[ + { + "category": "domestic-journal-conf", + "title": "다기관 데이터 기반 도메인 일반화를 적용한 소아청소년 뼈나이 자동 예측 딥러닝 모델의 개발 및 외부 검증", + "authors": null, + "venue": "한국IT서비스학회지", + "volume": "제 25권 제 3호, pp. 75 ~ 87, 2026년 6월 (KCI)", + "published_at": "2026-06", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "골반 X-ray 영상에서 딥러닝 기반 Risser Grade 자동 분류의 다기관 외부 검증 및 도메인 시프트 분석 : AI 의료기기 상용화 전략에 대한 시사점", + "authors": null, + "venue": "경영컨설팅연구", + "volume": "제 26권 제 3호, pp. 337 ~ 348, 2026년 6월 (KCI)", + "published_at": "2026-06", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Globally Integrated Trust Authority (GITA) for Resource-Constrained Edge Devices in IoT and 6G", + "authors": null, + "venue": "IEEE Transactions on Network and Service Management", + "volume": "Vol. 23, pp. 4490~4505, April 2026", + "published_at": "2026-04", + "kci": false, + "doi": null, + "is_highlight": true + }, + { + "category": "domestic-journal-conf", + "title": "엣지 장치용 경량 LLM 한국어 스팸 탐지 추론 성능 비교", + "authors": null, + "venue": "사물인터넷융복합논문지", + "volume": "제 12권 제 2호, pp. 95 ~ 101, 2026년 4월 (KCI)", + "published_at": "2026-04", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "성장클리닉 진단 보조를 위한 지식 그래프 및 대규모 언어 모델 융합 뉴로-심볼릭 임상의사결정 지원 시스템 설계", + "authors": null, + "venue": "한국IT서비스학회지", + "volume": "제 25권 제 1호, pp. 63 ~ 73, 2026년 2월 (KCI)", + "published_at": "2026-02", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "분산형 하이브리드 AI 기반 모바일 RPG NPC 시스템의 구현", + "authors": null, + "venue": "사물인터넷융복합논문지", + "volume": "제 11권 제 6호, pp. 83 ~ 90, 2025년 12월 (KCI)", + "published_at": "2025-12", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "관심 영역을 활용한 딥러닝 기반 해무 탐지 시스템", + "authors": null, + "venue": "한국통신학회논문지", + "volume": "제 50권 제 7호, pp. 1133 ~ 1142, 2025년 7월 (SCOPUS & KCI)", + "published_at": "2025-07", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "FSM과 강화학습 기반의 지능형 NPC AI: 2D 모바일 자동 진행 RPG 게임의 구현 연구", + "authors": null, + "venue": "정보처리학회논문지", + "volume": "제 14권 제 6호, pp. 480 ~ 488, 2025년 6월 (KCI)", + "published_at": "2025-06", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Application Level Trust Authority (APPLETA) for Resource-Constrained Edge Devices in IoT and 6G", + "authors": null, + "venue": "IEEE Transactions on Consumer Electronics", + "volume": "Vol. 71, No. 2, pp. 4934~4948, May 2025", + "published_at": "2025-05", + "kci": false, + "doi": null, + "is_highlight": true + }, + { + "category": "domestic-journal-conf", + "title": "공공기관 IT시스템 보안 강화를 위한 사이버 위협 점검/수집 시스템", + "authors": null, + "venue": "한국IT서비스학회지", + "volume": "제 24권 제 2호, pp. 31 ~ 46, 2025년 4월 (KCI)", + "published_at": "2025-04", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "QUIC 프로토콜의 혼잡제어 성능 비교 분석", + "authors": null, + "venue": "정보처리학회논문지", + "volume": "제 14권 제 1호, pp. 9 ~ 13, 2025년 1월 (KCI)", + "published_at": "2025-01", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "mQUIC: Use of QUIC for Handover Support with Connection Migration in Wireless/Mobile Networks", + "authors": null, + "venue": "IEEE Communications Magazine", + "volume": "Vol. 62, Issue 4, pp. 128~134, April 2024", + "published_at": "2024-04", + "kci": false, + "doi": null, + "is_highlight": true + }, + { + "category": "intl-journal-conf", + "title": "Enhanced Backoff Mechanism for Uplink OFDMA in Wireless Local Area Network", + "authors": null, + "venue": "Journal of King Saud University - Computer and Information Sciences", + "volume": "Vol. 36, Issue 3, pp. 1~15, March 2024", + "published_at": "2024-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Use of QUIC for Mobile-Oriented Future Internet (Q-MOFI)", + "authors": null, + "venue": "Electronics", + "volume": "Vol. 13, Article No. 13020431, pp. 1~20, January 2024", + "published_at": "2024-01", + "kci": false, + "doi": null, + "is_highlight": true + }, + { + "category": "intl-journal-conf", + "title": "Use of QUIC for CoAP Transport in IoT Networks", + "authors": null, + "venue": "Internet of Things (ISSN: 2543-1536)", + "volume": "Vol. 24, pp. 1~16, Article No. 100905, December 2023", + "published_at": "2023-12", + "kci": false, + "doi": null, + "is_highlight": true + }, + { + "category": "intl-journal-conf", + "title": "Adaptive Control of Congestion Window in QUIC", + "authors": null, + "venue": "International Conference on ICTC", + "volume": "pp. 1394~1396, October 2023", + "published_at": "2023-10", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "멀티미디어 영상회의 서비스를 위한 사용자 체감 품질 측정 방법 표준 기술 동향", + "authors": null, + "venue": "한국컴퓨터통신연구회(OSIA) S&TR Journal", + "volume": "제 36권 제 2호, pp. 15 ~ 20, 2023년 9월", + "published_at": "2023-09", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "차량용 인포테인먼트 서비스 표준화 동향", + "authors": null, + "venue": "정보과학회지", + "volume": "제 41권 제 9호, pp. 25 ~ 29, 2023년 9월", + "published_at": "2023-09", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Performance Evaluation of AMQP over QUIC in the Internet-of-Thing Networks", + "authors": null, + "venue": "Journal of King Saud University - Computer and Information Sciences", + "volume": "Vol. 35, Issue 4, pp. 1~9, April 2023", + "published_at": "2023-04", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Use of QUIC for AMQP in IoT networks", + "authors": null, + "venue": "Computer Networks", + "volume": "Vol. 225, Article No. 109640, pp. 1~10, April 2023", + "published_at": "2023-04", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Zero Energy IoT Devices in Smart Cities Using RF Energy Harvesting", + "authors": null, + "venue": "Electronics", + "volume": "Vol. 12, Article No. 12010148, pp. 1~24, January 2023", + "published_at": "2023-01", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Image Forensics Using Non-Reducing Convolutional Neural Network for Consecutive Dual Operators", + "authors": null, + "venue": "Applied Sciences", + "volume": "Vol. 12, Article No. 12147152, pp. 1~18, July 2022", + "published_at": "2022-07", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "6LoWPAN over Optical Wireless Communications for IPv6 Transport in Internet of Things Networks", + "authors": null, + "venue": "IEEE Wireless Communications Letters", + "volume": "Vol. 11, No. 6, pp. 1142~1145, June 2022", + "published_at": "2022-06", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "AEDCN-Net: Accurate and Efficient Deep Convolutional Neural Network Model for Medical Image Segmentation", + "authors": null, + "venue": "IEEE Access", + "volume": "Vol. 9, pp. 154194~154203, November 2021", + "published_at": "2021-11", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "NAT 기반 사물인터넷 환경에서 실시간 통신 지원을 위한 MQTT-CoAP 혼합 기법", + "authors": null, + "venue": "한국통신학회논문지", + "volume": "제 46권 제 11호, pp. 1822 ~ 1833, 2021년 11월 (SCOPUS & KCI)", + "published_at": "2021-11", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Proxy-based Adaptive Transmission of MP-QUIC in Internet-of-Things Environment", + "authors": null, + "venue": "Electronics", + "volume": "Vol. 10, Article No. 10172175, pp. 1~14, September 2021", + "published_at": "2021-09", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "웹 및 스트리밍 서비스에 대한 QUIC 프로토콜 성능 분석", + "authors": null, + "venue": "정보처리학회논문지: 컴퓨터 및 통신 시스템", + "volume": "제 10권 제 5호, pp. 137 ~ 144, 2021년 5월 (KCI)", + "published_at": "2021-05", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Digital Certificate Verification Scheme for Smart Grid Using Fog Computing (FONICA)", + "authors": null, + "venue": "Sustainability", + "volume": "Vol. 13, Article No. 13052549, pp. 1~19, February 2021", + "published_at": "2021-02", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Framework of IoT Services over Unidirectional Visible Lights Communication Networks", + "authors": null, + "venue": "Electronics", + "volume": "Vol. 9, Article No. 9091349, pp. 1~22, September 2020", + "published_at": "2020-09", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "CoAP-based Streaming Control for IoT Applications", + "authors": null, + "venue": "Electronics", + "volume": "Vol. 9, Article No. 9081320, pp. 1~19, August 2020", + "published_at": "2020-08", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Agent-based In-Vehicle Infotainment Services in Internet-of-Things Environments", + "authors": null, + "venue": "Electronics", + "volume": "Vol. 9, Article No. 9081288, pp. 1~22, August 2020", + "published_at": "2020-08", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Partial Bicasting with Buffering for Proxy Mobile IPv6 Mobility Management in CoAP-Based IoT Networks", + "authors": null, + "venue": "Electronics", + "volume": "Vol. 9, Article No. 9040598, pp. 1~13, April 2020", + "published_at": "2020-04", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Distributed Identifier-Locator Mapping Management in Mobile ILNP Networks", + "authors": null, + "venue": "Electronics", + "volume": "Vol. 9, Article No. 9010058, pp. 1~26, January 2020", + "published_at": "2020-01", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "가시광 통신 기반 출결 관리 시스템 설계 및 구현", + "authors": null, + "venue": "한국통신학회논문지", + "volume": "제 44권 제 7호, pp. 1381 ~ 1390, 2019년 7월 (KCI)", + "published_at": "2019-07", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Mobile-Oriented Future Internet: Implementation and Experimentations over EU-Korea Testbed", + "authors": null, + "venue": "Electronics", + "volume": "Vol. 8, Article No. 8030338, pp. 1~24, March 2019", + "published_at": "2019-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "IoT-Based Resource Control for In-Vehicle Infotainment Services: Design and Experimentation", + "authors": null, + "venue": "Sensors", + "volume": "Vol. 19, Article No. s19030620, pp. 1~19, March 2019", + "published_at": "2019-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "CoAP-based group mobility management protocol for the Internet-of-Things in WBAN environment", + "authors": null, + "venue": "Future Generation Computer Systems", + "volume": "Vol. 88, pp. 309~318, November 2018", + "published_at": "2018-11", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Domain-based Distributed Identifier-Locator Mapping Management in Internet-of-Things Networks", + "authors": null, + "venue": "International Journal of Network Management", + "volume": "Vol. 28, Issue 5 (e2035), pp. 1~13, October 2018", + "published_at": "2018-10", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Cluster-Based Device Mobility Management in Named Data Networking for Vehicular Networks", + "authors": null, + "venue": "Mobile Information Systems", + "volume": "Vol. 2018, pp. 1~7, Open Access Article (Article ID 1710591), August 2018", + "published_at": "2018-08", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Device Management and Data Transport in IoT Networks Based on Visible Light Communication", + "authors": null, + "venue": "Sensors", + "volume": "Vol. 18, Article No. s18082741, August 2018", + "published_at": "2018-08", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "In-Vehicle Infotainment 시스템에서 Configuration Protocol의 설계 및 구현", + "authors": null, + "venue": "한국통신학회논문지", + "volume": "제 43권 제 7호, pp. 1140 ~ 1151, 2018년 7월 (KCI)", + "published_at": "2018-07", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Enhanced group communication in constrained application protocol-based Internet-of-things networks", + "authors": null, + "venue": "International Journal of Distributed Sensor Networks", + "volume": "Vol. 14, Issue 4, pp. 1~14, April 2018", + "published_at": "2018-04", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Reliable transmission of visible light communication data in lighting control networks", + "authors": null, + "venue": "IET Networks", + "volume": "Vol. 6, Issue 3, pp. 62~68, May 2017 (SCOPUS)", + "published_at": "2017-05", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Distributed CoAP Handover using Distributed Mobility Agents in Internet-of-Things Networks", + "authors": null, + "venue": "Journal of Information and Communication Convergence Engineering", + "volume": "Vol. 15, No. 1, pp. 37~42, March 2017 (SCOPUS)", + "published_at": "2017-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "A hash-based distributed mapping control scheme in mobile locator-identifier separation protocol networks", + "authors": null, + "venue": "International Journal of Network Management", + "volume": "Vol. 27, No. 2, pp. 1~13, March 2017", + "published_at": "2017-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Use of Proxy Mobile IPv6 for Mobility Management in CoAP-based IoT Networks", + "authors": null, + "venue": "IEEE Communications Letters", + "volume": "Vol. 20, No. 11, pp. 2284~2287, November 2016", + "published_at": "2016-11", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Mobility-Aware TAC Configuration in LTE-Based Mobile Communication Systems", + "authors": null, + "venue": "Lecture Notes in Electrical Engineering", + "volume": "Vol. 393, pp. 295~301, August 2016 (SCOPUS)", + "published_at": "2016-08", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Inter-Domain Mobility Management Based on the Proxy Mobile IP in Mobile Networks", + "authors": null, + "venue": "Journal of Information Processing Systems", + "volume": "Vol. 12, No. 2, pp. 196~213, June 2016 (SCOPUS)", + "published_at": "2016-06", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "BLE 네트워크 상에서 사물인터넷 서비스 제공을 위한 CoAP과 6LoWPAN 구현", + "authors": null, + "venue": "방송공학회논문지", + "volume": "제 21권 제 3호, pp. 298 ~ 306, 2016년 5월 (KCI)", + "published_at": "2016-05", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "TRILL-Based Mobile Packet Core Network for 5G Mobile Communication Systems", + "authors": null, + "venue": "Wireless Personal Communications", + "volume": "Vol. 87, No. 1, pp. 125~144, March 2016", + "published_at": "2016-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Distributed Mobility Management in 6LoWPAN-Based Wireless Sensor Networks", + "authors": null, + "venue": "International Journal of Distributed Sensor Networks", + "volume": "Vol. 11, Issue 10, 12 pages, October 2015", + "published_at": "2015-10", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "A Comparative Analysis of Centralized and Distributed Mobility Management in IP-Based Mobile Networks", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 25권 제 4호, pp. 656 ~ 671, 2015년 8월 (KCI)", + "published_at": "2015-08", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "An ID/Locator Separation Based Group Mobility Management in Wireless Body Area Network", + "authors": null, + "venue": "Journal of Sensors", + "volume": "Vol. 2015, Open Access Article (Article ID 537205), 12 pages, July 2015", + "published_at": "2015-07", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "IoT(사물기반 인터넷) 기반 헬스케어 서비스: 일상 생활습관 ‧ 건강관리 중심으로", + "authors": null, + "venue": "생명공학정책연구센터(BioINpro)", + "volume": "BioINpro 제 13호, pp. 1 ~ 12, 2015년 6월", + "published_at": "2015-06", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "Mobility Support Using Locator-Identifier Separation Protocol in 4G Mobile Communication Networks", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 25권 제 2호, pp. 337 ~ 355, 2015년 4월 (KCI)", + "published_at": "2015-04", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Fast Device Discovery for Remote Device Management in Lighting Control Networks", + "authors": null, + "venue": "Journal of Information Processing Systems", + "volume": "Vol. 11, No. 1, pp. 125~133, March 2015 (SCOPUS)", + "published_at": "2015-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "사물인터넷 기반 헬스케어 서비스 및 플랫폼 동향", + "authors": null, + "venue": "한국통신학회지(정보와통신)", + "volume": "제 31권 제 12호, pp. 25 ~ 30, 2014년 12월", + "published_at": "2014-12", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "모바일 중심 미래 인터넷: OpenFlow 기반 구현 및 KOREN 테스트베드 실험", + "authors": null, + "venue": "정보과학회논문지: 정보통신", + "volume": "제 41권 제 4호, pp. 167 ~ 176, 2014년 8월 (KCI)", + "published_at": "2014-08", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "Load Balancing for Proxy Mobile IPv6 in SAE-based Mobile Networks", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 24권 제 3호, pp. 433 ~ 448, 2014년 6월 (KCI)", + "published_at": "2014-06", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "LED 기반 조명 제어를 위한 PLASA 표준 프로토콜 기술", + "authors": null, + "venue": "조명전기설비학회지", + "volume": "제 28권 제 3호, pp. 9 ~ 21, 2014년 5월", + "published_at": "2014-05", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Performance Analysis of Distributed Mapping System in ID/Locator Separation Architectures", + "authors": null, + "venue": "Journal of Network and Computer Applications", + "volume": "Vol. 39, pp. 223~232, March 2014", + "published_at": "2014-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "A Distributed Mobility Control Scheme in LISP Networks", + "authors": null, + "venue": "Wireless Networks", + "volume": "Vol. 20, No. 2, pp. 245~259, February 2014", + "published_at": "2014-02", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Distributed Mapping Management of Identifiers and Locators in Mobile-Oriented Internet Environment", + "authors": null, + "venue": "International Journal of Communication Systems", + "volume": "Vol. 27, No. 1, pp. 95~115, January 2014", + "published_at": "2014-01", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "A Network-Based Handover Scheme in HIP-Based Mobile Networks", + "authors": null, + "venue": "Journal of Information Processing Systems", + "volume": "Vol. 9, No. 4, pp. 651~659, December 2013 (SCOPUS)", + "published_at": "2013-12", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Distributed Mapping Management of Identifiers and Locators in LISP-based Mobile Networks", + "authors": null, + "venue": "Wireless Personal Communications", + "volume": "Vol. 72, No. 1, pp. 565~579, September 2013", + "published_at": "2013-09", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "5세대 이동통신에서의 네트워크 이슈", + "authors": null, + "venue": "정보과학회지", + "volume": "제 31권 제 9호, pp. 20 ~ 26, 2013년 9월", + "published_at": "2013-09", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Mobile Oriented Future Internet (MOFI): Architectural Design and Implementations", + "authors": null, + "venue": "ETRI Journal", + "volume": "Vol. 35, No. 4, pp. 666~676, August 2013", + "published_at": "2013-08", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "무선 인터넷 환경에서 SCTP 프로토콜의 성능 최적화 방안", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 23권 제 3호, pp. 381 ~ 392, 2013년 6월 (KCI)< 무선 네트워크 환경에서 안드로이드 기반 SCTP 프로토콜의 성능 분석 정보과학회논문지: 시스템 및 이론, 제 40권 제 2호, pp. 105 ~ 110, 2013년 4월 (KCI)", + "published_at": "2013-06", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "조명 제어 네트워크에서 디바이스 관리를 위한 표준 프로토콜 기술 동향", + "authors": null, + "venue": "조명전기설비학회지", + "volume": "제 27권 제 2호, pp. 56 ~ 65, 2013년 3월", + "published_at": "2013-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "ID-LOC 분리 기반 인터넷 구조에서 분산형 매핑 시스템의 구현 및 평가", + "authors": null, + "venue": "한국통신학회논문지", + "volume": "제 37B권(네트워크 및 서비스) 제 11호, pp. 984 ~ 992, 2012년 11월 (KCI)", + "published_at": "2012-11", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "이동통신 로밍 환경에서 빠른 홈망 복귀를 위한 망탐색 알고리즘", + "authors": null, + "venue": "정보처리학회논문지", + "volume": "제 19-C권 제 2호, pp. 149 ~ 152, 2012년 4월 (KCI)", + "published_at": "2012-04", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "미래 인터넷의 이동 네트워크 구조 및 연구동향", + "authors": null, + "venue": "한국통신학회지(정보와통신)", + "volume": "제 29권 제 3호, pp. 41 ~ 48, 2012년 3월", + "published_at": "2012-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "모바일 단말 환경에서 웹브라우저의 로딩속도 개선 기법", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 22권 제 1호, pp. 139 ~ 152, 2012년 2월 (KCI)", + "published_at": "2012-02", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Network-Based Distributed Mobility Control in Localized Mobile LISP Networks", + "authors": null, + "venue": "IEEE Communications Letters", + "volume": "Vol. 16, No. 1, pp. 104~107, January 2012", + "published_at": "2012-01", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Partial Bicasting with Buffering for Proxy Mobile IPv6 Handover in Wireless Networks", + "authors": null, + "venue": "Journal of Information Processing Systems", + "volume": "Vol. 7, No. 4, pp. 627~634, December 2011 (SCOPUS)", + "published_at": "2011-12", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "Binding Query를 활용한 Proxy Mobile IPv6의 성능 향상 기법", + "authors": null, + "venue": "한국통신학회논문지", + "volume": "제 36권 제 11호(네트워크 및 융합서비스), pp. 1269 ~ 1276, 2011년 11월 (KCI)", + "published_at": "2011-11", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "이동 LISP망에서 네트워크 기반 이동성 제어 기법", + "authors": null, + "venue": "정보처리학회논문지", + "volume": "제 18-C권 제 5호, pp. 339 ~ 342, 2011년 10월 (KCI)", + "published_at": "2011-10", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Distributed Mobility Control in Proxy Mobile IPv6 Networks", + "authors": null, + "venue": "IEICE Transactions on Communications", + "volume": "Vol. E94-B, No. 8, pp. 2216~2224, August 2011", + "published_at": "2011-08", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Adaptive Congestion Control of mSCTP for Vertical Handover Based on Bandwidth Estimation in Heterogeneous Wireless Networks", + "authors": null, + "venue": "Wireless Personal Communications", + "volume": "Vol. 57, No. 4, pp. 707~725, April 2011", + "published_at": "2011-04", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "MOFI: Future Internet Architecture with Address-free Hosts for Mobile Environments", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 21권 제 2호, pp. 343 ~ 358, 2011년 4월 (KCI)", + "published_at": "2011-04", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "미래 인터넷을 위한 네이밍과 어드레싱을 위한 연구", + "authors": null, + "venue": "정보과학회지", + "volume": "제 29권 제 3호, pp. 53 ~ 65, 2011년 3월", + "published_at": "2011-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "Mobile Oriented Future Internet (MOFI): Design Considerations and Architecture", + "authors": null, + "venue": "OSIA Standards & Technology Review (ISSN:1738-9887)", + "volume": "Vol. 24, No. 1, pp. 61 ~ 77, 2011년 3월", + "published_at": "2011-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "Fast Tree Join for Seamless Multicast Handover in FMIPv6-based Mobile Networks", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 20권 제 6호, pp. 993 ~ 1003, 2010년 12월 (KCI)", + "published_at": "2010-12", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Multicast Handover Agents for Fast Handover in Wireless Multicast Networks", + "authors": null, + "venue": "IEEE Communications Letters", + "volume": "Vol. 14, No. 7, pp. 676~678, July 2010", + "published_at": "2010-07", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Fast Selective ACK Scheme for Throughput Enhancement of Multi-Homed SCTP Hosts", + "authors": null, + "venue": "IEEE Communications Letters", + "volume": "Vol. 14, No. 6, pp. 587~589, June 2010", + "published_at": "2010-06", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Performance Enhancement of mSCTP for Vertical Handover across Heterogeneous Wireless Networks", + "authors": null, + "venue": "International Journal of Communication Systems", + "volume": "Vol. 22, No. 12, pp. 1573~1591, December 2009", + "published_at": "2009-12", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "모바일 IPTV 멀티캐스트 전송 및 서비스 기술 동향", + "authors": null, + "venue": "정보과학회지", + "volume": "제 27권 제 8호, pp. 67 ~ 73, 2009년 8월", + "published_at": "2009-08", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "이동통신망에서의 모바일 IPTV 표준기술", + "authors": null, + "venue": "개방형컴퓨터통신연구회(OSIA) Standards & Technology Review", + "volume": "2009년 제 2호, pp. 49 ~ 59, 2009년 6월", + "published_at": "2009-06", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Corruption-aware Adaptive Increase and Adaptive Decrease Algorithm for TCP Error and Congestion Controls in Wireless Networks", + "authors": null, + "venue": "International Journal of Communication Systems", + "volume": "Vol. 22, No. 5, pp. 543~564, May 2009", + "published_at": "2009-05", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "A Technique to Enable the Corruption-aware Transport Protocols in Realistic Networks", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 19권 제 1호, pp. 129 ~ 137, 2009년 2월 (KCI)", + "published_at": "2009-02", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Partial CRC Checksum of SCTP for Error Control over Wireless Networks", + "authors": null, + "venue": "Wireless Personal Communications", + "volume": "Vol. 48, No. 2, pp. 247~260, January 2009", + "published_at": "2009-01", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "A Cross-layer Approach for Throughput Enhancement in Unsteady Satellite Networks", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 18권 제 6호, pp. 1089 ~ 1098, 2008년 12월 (KCI)", + "published_at": "2008-12", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "미래인터넷 이동성 제어 프레임워크", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 18권 제 5호, pp. 799 ~ 812, 2008년 10월 (KCI)", + "published_at": "2008-10", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Analysis of Handover Latency for Mobile IPv6 and mSCTP", + "authors": null, + "venue": "Journal of Information Processing Systems", + "volume": "Vol. 4, No. 3, pp. 87~96, September 2008 (SCOPUS)", + "published_at": "2008-09", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "리눅스 환경에서 SCTP와 TCP 프로토콜의 성능 비교", + "authors": null, + "venue": "한국통신학회논문지:네트워크및서비스", + "volume": "제 33권 제 8호, pp. 699 ~ 706, 2008년 8월 (KCI)", + "published_at": "2008-08", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "3G-WiBro 망간 수직핸드오버를 위한 mSCTP 기법", + "authors": null, + "venue": "정보과학회논문지:정보통신", + "volume": "제 35권 제 4호, pp. 355 ~ 365, 2008년 8월 (KCI)", + "published_at": "2008-08", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "ITU-T FMC 표준화 현황 및 국내 대응방안", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 18권 제 4호, pp. 583 ~ 592, 2008년 8월 (KCI)", + "published_at": "2008-08", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "mSIP: Extension of SIP for Soft Handover with Bicasting", + "authors": null, + "venue": "IEEE Communications Letters", + "volume": "Vol. 12, No. 7, pp. 532~534, July 2008", + "published_at": "2008-07", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "Standardization on Mobility Management Architectures and Protocols for All-IP Mobile Networks", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 18권 제 3호, pp. 508 ~ 516, 2008년 6월 (KCI)", + "published_at": "2008-06", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "ITU-T NGN-GSI 이동성 관리 표준개발 동향", + "authors": null, + "venue": "개방형컴퓨터통신연구회(OSIA) Standards & Technology Review", + "volume": "2008년 제 1호, pp. 37 ~ 44, 2008년 3월", + "published_at": "2008-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "CC-SCTP: Chunk Checksum of SCTP for Enhancement of Throughput in Wireless Network Environment", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 17권 제 4호, pp. 690 ~ 699, 2007년 8월 (KCI)", + "published_at": "2007-08", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "ITU-T SG19 이동성 관리기술 표준화 동향", + "authors": null, + "venue": "개방형컴퓨터통신연구회(OSIA) Standards & Technology Review", + "volume": "2007년 제 2호, pp. 13 ~ 26, 2007년 6월", + "published_at": "2007-06", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "SCTP 기반 수송계층 이동성 기술", + "authors": null, + "venue": "정보과학회 정보통신기술(정보통신연구회)", + "volume": "제 20권 제 1호, pp. 64 ~ 79, 2007년 5월", + "published_at": "2007-05", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "IP 핸드오버: 망기반 기법 versus 종단간 기법", + "authors": null, + "venue": "한국통신학회지(정보와통신)", + "volume": "제 24권 제 4호, pp. 106 ~ 115, 2007년 4월", + "published_at": "2007-04", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Chunk Checksum of SCTP for Throughput Enhancement", + "authors": null, + "venue": "IEEE Communications Letters", + "volume": "Vol. 10, No. 11, pp. 796~798, November 2006", + "published_at": "2006-11", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "ITU-T에서의 B3G 이동성관리 표준 기술 분석", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 16권 제 3호, pp. 460 ~ 469, 2006년 6월 (KCI)", + "published_at": "2006-06", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "멀티홈잉 기반 SCTP 성능 실험 및 비교 분석", + "authors": null, + "venue": "정보처리학회논문지", + "volume": "제 13-C권 제 2호, pp. 235 ~ 240, 2006년 4월 (KCI)", + "published_at": "2006-04", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Mobility Management Requirements and Framework for Systems Beyond IMT-2000", + "authors": null, + "venue": "Journal of Communications and Networks", + "volume": "Vol. 7, No. 2, pp. 171~177, June 2005", + "published_at": "2005-06", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Transport Layer Mobility Support Utilizing Link Signal Strength Information", + "authors": null, + "venue": "IEICE Transactions on Communications", + "volume": "Vol. E87-B, No. 9, pp. 2548~2556, September 2004", + "published_at": "2004-09", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "mSCTP를 이용한 종단간 이동성 지원 방안", + "authors": null, + "venue": "정보과학회논문지,", + "volume": "제 31권 제 4호, pp. 393 ~ 404, 2004년 8월 (KCI)", + "published_at": "2004-08", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Limiting the Length of BET for Tunnel-Based IP Fast Handover", + "authors": null, + "venue": "IEICE Transactions on Fundamentals of Electronics Communications and Computer Sciences", + "volume": "Vol. E87-A, No. 6, pp. 1527~1530, June 2004", + "published_at": "2004-06", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "SCTP의 멀티호밍 특성에 대한 성능 평가", + "authors": null, + "venue": "정보처리학회논문지,", + "volume": "제11-C권 제2호, pp. 245 ~ 252, 2004년 4월 (KCI)", + "published_at": "2004-04", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "mSCTP for Soft Handover in Transport Layer", + "authors": null, + "venue": "IEEE Communications Letters", + "volume": "Vol. 8, No. 3, pp. 189~191, March 2004", + "published_at": "2004-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "ECTP 멀티캐스트 전송 프로토콜 : 구현 및 성능분석", + "authors": null, + "venue": "한국통신학회논문지", + "volume": "제 28권 제 10호, pp. 876 - 890, 2003년 10월 (KCI)", + "published_at": "2003-10", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "3G-WLAN 연동기술 동향", + "authors": null, + "venue": "ETRI 전자통신동향분석", + "volume": "제 18권 4호 (통권 82호), pp. 1 - 10, 2003년 8월", + "published_at": "2003-08", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "SCTP 표준기술 분석 및 전망", + "authors": null, + "venue": "ETRI 전자통신동향분석", + "volume": "제 18권 3호 (통권 81호), pp. 11 - 21, 2003년 6월", + "published_at": "2003-06", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "인터넷 멀티캐스트 현황 및 전망", + "authors": null, + "venue": "주간기술동향", + "volume": "제 1090호, pp. 1 - 15, 2003년 4월", + "published_at": "2003-04", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "IP 멀티캐스트 시장 전망에 대한 고찰", + "authors": null, + "venue": "한국통신학회지(정보통신)", + "volume": "제 19권 제 10호, pp. 1577 ~ 1590, 2002년 10월", + "published_at": "2002-10", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "Subnet Multicast for Delivery of One-to-Many Multicast Applications", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 12권 제 5호, pp. 770 - 779, 2002년 10월 (KCI)", + "published_at": "2002-10", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "인터넷방송을 위한 멀티캐스트 기술 동향", + "authors": null, + "venue": "ETRI 전자통신동향분석", + "volume": "제 17권 3호 (통권 75호), 2002년 6월", + "published_at": "2002-06", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "종단간 서비스품질 표준기술 동향", + "authors": null, + "venue": "주간기술동향", + "volume": "제 1049호, 2002년 6월", + "published_at": "2002-06", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "신뢰적인 멀티캐스트 전송 프로토콜을 위한 Top-Down 기반의 제어 트리 구축 방안", + "authors": null, + "venue": "정보과학회논문지", + "volume": "제 28권, 4호, pp. 611 - 620, 2001년 12월 (KCI)", + "published_at": "2001-12", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "종단간 멀티캐스트 전송을 위한 ECTP 표준 프로토콜", + "authors": null, + "venue": "주간기술동향", + "volume": "제 1016호, 2001년 10월", + "published_at": "2001-10", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Configuration of ACK Trees for Multicast Transport Protocols", + "authors": null, + "venue": "ETRI Journal", + "volume": "Vol. 23, No. 3, pp. 111~120, September 2001", + "published_at": "2001-09", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "Enhanced Core Based Tree for Many-to-Many IP Multicasting", + "authors": null, + "venue": "Telecommunications Review", + "volume": "제 11권 제 3호, pp. 485 - 493, 2001년 6월 (KCI)", + "published_at": "2001-06", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "멀티캐스팅 프로토콜의 트리구성에 관한 성능평가 및 분석", + "authors": null, + "venue": "한국통신학회논문지", + "volume": "제 26권 제 5호, pp. 738 - 744, 2001년 5월 (KCI)", + "published_at": "2001-05", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Assignment of ADM Rings and DCS Mesh in Telecommunication Networks", + "authors": null, + "venue": "Journal of the O.R. Society", + "volume": "Vol. 52, No. 4, pp. 440~448, April 2001", + "published_at": "2001-04", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Multicast Delivery Based on Unicast and Subnet Multicast", + "authors": null, + "venue": "IEEE Communications Letters", + "volume": "Vol. 5, No. 4, pp. 181~183, April 2001", + "published_at": "2001-04", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "인터넷 멀티캐스트 신기술 동향", + "authors": null, + "venue": "ETRI 전자통신동향분석", + "volume": "제 16권 제 2호, pp. 1-9, 2001년 4월", + "published_at": "2001-04", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Dynamic Bandwidth Allocation Scheme for Multiple Real-time VBR Videos over ATM Networks", + "authors": null, + "venue": "Telecommunications Systems", + "volume": "Vol. 15, pp.359~380, December 2000", + "published_at": "2000-12", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "차세대 인터넷 멀티캐스팅 기술 동향", + "authors": null, + "venue": "한국통신학회지(정보통신)", + "volume": "제 17권 제 9호, pp. 168-187, 2000년 9월", + "published_at": "2000-09", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "인터넷 멀티캐스트 라우팅 기술 동향", + "authors": null, + "venue": "ETRI 전자통신동향분석", + "volume": "제 15권 제 3호, pp. 28-41, 2000년 6월", + "published_at": "2000-06", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "멀티캐스트 신뢰전송 기술 및 표준화 동향", + "authors": null, + "venue": "주간기술동향", + "volume": "제 944호, pp. 16 - 33, 2000년 5월", + "published_at": "2000-05", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "인터넷 전화 시장 및 표준화 동향", + "authors": null, + "venue": "ETRI 전자통신동향분석", + "volume": "제15권 2호, pp. 1 - 14, 2000년 4월호", + "published_at": "2000-04", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Minimizing Cost and Delay in Shared Multicast Trees", + "authors": null, + "venue": "ETRI Journal", + "volume": "Vol. 22, No. 1, pp.30~37, March 2000", + "published_at": "2000-03", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "액티브 네트워크 구조상에서 공동작업 응용을 위한 성능 향상 기법", + "authors": null, + "venue": "한국통신학회논문지", + "volume": "Vol. 24, No. 12B, pp. 2283 - 2291, 1999년 12월 (KCI)", + "published_at": "1999-12", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "다자간 멀티미디어 응용의 멀티캐스트 통신환경을 위한 통합관리 플랫폼", + "authors": null, + "venue": "한국통신학회논문지", + "volume": "Vol. 24, No. 12B, pp. 2262 - 2274, 1999년 12월 (KCI)", + "published_at": "1999-12", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "ATM 기반 MPLS 공중망에서의 IP 전송기술", + "authors": null, + "venue": "한국통신학회지(정보통신)", + "volume": "Vol. 16, No. 12, pp. 47 - 58, 1999년 12월", + "published_at": "1999-12", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "공중 ATM 망에서의 IP 전송기술 동향", + "authors": null, + "venue": "주간기술동향", + "volume": "924호, pp. 15 - 29, 1999년 12월", + "published_at": "1999-12", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "A Control of Channel Rate for Real-time VBR Video Transmission", + "authors": null, + "venue": "한국경영과학회논문지", + "volume": "제 24권 제 3호, pp. 63 - 72, 9월, 1999. (KCI)", + "published_at": "1999-09", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "Non-Core Based Shared Tree Architecture for IP Multicasting", + "authors": null, + "venue": "Electronics Letters", + "volume": "Vol. 35, No. 11, pp. 872~873, May 1999", + "published_at": "1999-05", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "인터넷 멀티캐스트 라우팅 프로토콜 분석", + "authors": null, + "venue": "ETRI 전자통신동향분석", + "volume": "99년 10월호, pp. 99 - 110, 1999.", + "published_at": "1999", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "멀티캐스트 전송을 위한 오류제어 기법의 분류", + "authors": null, + "venue": "ETRI 전자통신동향분석", + "volume": "99년 6월호, pp. 76 - 84, 1999.", + "published_at": "1999", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "A Design of the Self-Healing ATM Networks Based on the Backup Virtual Path", + "authors": null, + "venue": "Computers and Operations Research", + "volume": "Vol. 25, No. 7/8, pp. 595~609, July 1998", + "published_at": "1998-07", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "A Design of the Minimum Cost Ring-Chain Network with Dual-Homing Survivability: Tabu Search Approach", + "authors": null, + "venue": "Computers and Operations Research", + "volume": "Vol. 24, No. 9, pp. 883~897, September 1997", + "published_at": "1997-09", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "Design of Survivable Communication Networks with High Connectivity Constraints", + "authors": null, + "venue": "한국경영과학회논문지", + "volume": "Vol. 22, No. 3, pp. 59-80, September, 1997. (KCI)", + "published_at": "1997-09", + "kci": true, + "doi": null, + "is_highlight": false + }, + { + "category": "intl-journal-conf", + "title": "A Tabu Search for the Survivable Fiber Optic Communication Network Design", + "authors": null, + "venue": "Computers and Industrial Engineering", + "volume": "Vol. 28, Issue 4, pp. 689~700, October 1995", + "published_at": "1995-10", + "kci": false, + "doi": null, + "is_highlight": false + }, + { + "category": "domestic-journal-conf", + "title": "Heuristic Aspects of the Branch and Bound Procedure For a Job Scheduling Problem", + "authors": null, + "venue": "대한산업공학회지", + "volume": "Vol. 18, No. 2, 141-147, 1992. (KCI)", + "published_at": "1992", + "kci": true, + "doi": null, + "is_highlight": false + } +] \ No newline at end of file diff --git a/backend/seed/data/research_areas.json b/backend/seed/data/research_areas.json new file mode 100644 index 0000000..a4c7b86 --- /dev/null +++ b/backend/seed/data/research_areas.json @@ -0,0 +1,72 @@ +[ + { + "name_en": "Quick UDP Internet Connection (QUIC)", + "name_kr": null, + "display_order": 1 + }, + { + "name_en": "QUIC-based Mobility and Multi-Streaming Support", + "name_kr": null, + "display_order": 2 + }, + { + "name_en": "Services and Protocols for Internet-of-Things (IoT)", + "name_kr": null, + "display_order": 3 + }, + { + "name_en": "Constrained Application Protocol (CoAP)", + "name_kr": null, + "display_order": 4 + }, + { + "name_en": "In-Vehicle Infotainment (IVI)", + "name_kr": null, + "display_order": 5 + }, + { + "name_en": "Optical Wireless or Visible Light Communications (OWC/VLC)", + "name_kr": null, + "display_order": 6 + }, + { + "name_en": "Lighting Control Networks (PLASA E1.45) for LED-based VLC", + "name_kr": null, + "display_order": 7 + }, + { + "name_en": "Mobility Management: Distributed Mobility Control", + "name_kr": null, + "display_order": 8 + }, + { + "name_en": "Multicast Routing Protocols and Reliable Multicasting", + "name_kr": null, + "display_order": 9 + }, + { + "name_en": "mobile SCTP (mSCTP): Soft Handover in Transport Layer", + "name_kr": null, + "display_order": 10 + }, + { + "name_en": "Stream Control Transmission Protocol (SCTP)", + "name_kr": null, + "display_order": 11 + }, + { + "name_en": "Telecommunication Optimization: Network Planning and Management", + "name_kr": null, + "display_order": 12 + }, + { + "name_en": "TAC/TAL Configuration for Paging and Location Management", + "name_kr": null, + "display_order": 13 + }, + { + "name_en": "Tabu Search and Genetic Algorithm", + "name_kr": null, + "display_order": 14 + } +] \ No newline at end of file diff --git a/backend/seed/data/research_projects.json b/backend/seed/data/research_projects.json new file mode 100644 index 0000000..7347bc5 --- /dev/null +++ b/backend/seed/data/research_projects.json @@ -0,0 +1,50 @@ +[ + { + "slug": "iot-standards", + "title": "AIoT & AI-RAN", + "abstract": "AIoT & AI-RAN investigates agent-based IoT architectures in which autonomous AI agents are distributed across sensor, edge, and radio access layers. The project studies agent-to-agent coordination over high-performance transport (gRPC/QUIC) bridged with constrained edge protocols (MQTT/CoAP), targeting AI-RAN designs for distributed autonomous control.", + "keywords": [ + "AIoT", + "agent-based IoT", + "AI-RAN", + "constrained edge protocols", + "distributed autonomous control" + ], + "standardsTrack": "National Research Foundation of Korea (NRF)", + "standardsOrg": "NRF", + "period": "2026 ~ Present", + "deliverables": [] + }, + { + "slug": "ccis", + "title": "MCM", + "abstract": "Multilateral and Collaborative Metaverse (MCM) refers to metaverse systems in which two or more participants simultaneously interact within a shared virtual space for a common collaborative purpose. Unlike single-user or purely competitive environments, an MCM service is defined by coordinated participation: its intended outcome cannot be achieved by a single user acting alone. The project defines general requirements, service classification, and a gap analysis against existing standards.", + "keywords": [ + "MCM", + "metaverse", + "shared virtual space", + "coordinated participation", + "service classification" + ], + "standardsTrack": "IEC/TC 100/WG 12 supported by KEIT", + "standardsOrg": "IEC TC100", + "period": "2026 ~ Present", + "deliverables": [] + }, + { + "slug": "vlc-iot", + "title": "MVQM", + "abstract": "Management of Visual Quality in Metaverse Systems (MVQM) is a conceptual and functional approach for managing visual quality by dynamically adapting visual data delivery in response to user context, device capability, and network conditions. It emphasizes user-centric, context-aware quality management over static system-centric optimization, covering hybrid visual assets, level of detail, and area of interest adaptation.", + "keywords": [ + "MVQM", + "visual quality", + "hybrid visual assets", + "level of detail", + "area of interest" + ], + "standardsTrack": "IEC/TC 100/WG 12 supported by KEIT", + "standardsOrg": "IEC TC100", + "period": "2026 ~ Present", + "deliverables": [] + } +] \ No newline at end of file diff --git a/backend/seed/data/standards.json b/backend/seed/data/standards.json new file mode 100644 index 0000000..368e3a3 --- /dev/null +++ b/backend/seed/data/standards.json @@ -0,0 +1,384 @@ +[ + { + "org": "IEC TC100", + "full": "Multimedia Systems and Equipment", + "scope": "international", + "period": "2018 ~ Present", + "role": "Convenor", + "projects": [ + { + "wg": "WG12", + "name": "Multimedia Systems and Equipment for Metaverse (IEC 63614)", + "documents": [ + { + "title": "Multimedia Systems and Equipment for Metaverse - Part 1: Genaral", + "ref": "IEC TR 63614-1 (May 2026)", + "status": "TR", + "publishedAt": "2026-05" + }, + { + "title": "Multimedia Systems and Equipment for Metaverse - Part 2: Classification", + "ref": "IEC TS 63614-2 (May 2026)", + "status": "TS", + "publishedAt": "2026-05" + }, + { + "title": "Multimedia Systems and Equipment for Metaverse - Part 3: Gap Analysis", + "ref": "IEC TR 63614-3 (March 2026)", + "status": "TR", + "publishedAt": "2026-03" + }, + { + "title": "Multimedia Systems and Equipment for Metaverse - Part 4: AI Use Cases", + "ref": "IEC WDTR 63614-4 (In Progress)", + "status": "InProgress" + } + ] + }, + { + "wg": "WG11(Convenor)", + "name": "User's QoE for Multimedia Conference Services (IEC 63478)", + "documents": [ + { + "title": "User's QoE for Multimedia Conference Services - Part 1: General", + "ref": "IEC TR 63478-1 (November 2023)", + "status": "TR", + "publishedAt": "2023-11" + }, + { + "title": "User's QoE for Multimedia Conference Services - Part 2: Requirments", + "ref": "IEC IS 63478-2 (October 2025)", + "status": "IS", + "publishedAt": "2025-10" + }, + { + "title": "User's QoE for Multimedia Conference Services - Part 3: Measurement Methods", + "ref": "IEC CDV 63478-3 (In Progress)", + "status": "InProgress" + } + ] + }, + { + "wg": "WG30(TA17)", + "name": "Infotainment Services for Public Vehicles (IEC 63479)", + "documents": [ + { + "title": "Infotainment Services for Public Vehicles (PVIS) - Part 1: General", + "ref": "IEC TR 63479-1 (November 2023)", + "status": "TR", + "publishedAt": "2023-11" + }, + { + "title": "Infotainment Services for Public Vehicles (PVIS) - Part 2: Requirements", + "ref": "IEC IS 63479-2 (February 2026)", + "status": "IS", + "publishedAt": "2026-02" + }, + { + "title": "Infotainment Services for Public Vehicles (PVIS) - Part 3: Framework", + "ref": "IEC IS 63479-3 (January 2026)", + "status": "IS", + "publishedAt": "2026-01" + } + ] + }, + { + "wg": "WG30(TA17)", + "name": "Configurable Car Infotainment Services (IEC 63246)", + "documents": [ + { + "title": "Configurable Car Infotainment Services (CCIS) - Part 1: General", + "ref": "IEC 63246-1 (August 2021)", + "status": "IS", + "publishedAt": "2021-08" + }, + { + "title": "Configurable Car Infotainment Services (CCIS) - Part 2: Requirements", + "ref": "IEC 63246-2 (January 2022)", + "status": "IS", + "publishedAt": "2022-01" + }, + { + "title": "Configurable Car Infotainment Services (CCIS) - Part 3: Framework", + "ref": "IEC 63246-3 (January 2022)", + "status": "IS", + "publishedAt": "2022-01" + }, + { + "title": "Configurable Car Infotainment Services (CCIS) - Part 4: Protocol", + "ref": "IEC TR 63246-4 (December 2022)", + "status": "TR", + "publishedAt": "2022-12" + } + ] + } + ] + }, + { + "org": "ISO/IEC JTC1/SC41", + "full": "Internet of Things and Digital Twin", + "scope": "international", + "period": "2020 ~ Present", + "projects": [ + { + "wg": "WG", + "name": "(WG5) IoT-based Management of Tangible Cultural Heritage Assets (ISO/IEC TR 30189)", + "documents": [ + { + "title": "Part 1: Framework", + "ref": "ISO/IEC TR 30189-1 (March 2025)", + "status": "TR", + "publishedAt": "2025-03" + }, + { + "title": "Part 2: Use Cases", + "ref": "ISO/IEC CDTR 30189-2 (In Progress)", + "status": "InProgress" + } + ] + } + ] + }, + { + "org": "ITU-T SG20", + "full": "IoT Services based on VLC", + "scope": "international", + "period": "2018 ~ 2020", + "projects": [ + { + "wg": "Main", + "name": "IoT Services based on VLC", + "documents": [ + { + "title": "Framework of IoT Services based on Visible Light Communications (VLC)", + "ref": "ITU-T Recommendation Y.4465 (January 2020)", + "status": "IS", + "publishedAt": "2020-01" + }, + { + "title": "Functional Architecture for IoT Services based on VLC", + "ref": "ITU-T Recommendation Y.4474 (August 2020)", + "status": "IS", + "publishedAt": "2020-08" + } + ] + } + ] + }, + { + "org": "TTA/PG425", + "full": "가시광 통신 기반 사물인터넷 서비스", + "scope": "domestic", + "period": "2018 ~ 2020", + "projects": [ + { + "wg": "Main", + "name": "가시광 통신 기반 사물인터넷 서비스", + "documents": [ + { + "title": "가시광 통신 기반 사물인터넷 서비스 - 제 1 부: 네트워크 모델 및 요구사항", + "ref": "TTAK.KO-10.1158-part1 (2019년 12월)", + "status": "IS", + "publishedAt": "2019-12" + }, + { + "title": "가시광 통신 기반 사물인터넷 서비스 - 제 2 부: 프레임워크", + "ref": "TTAK.KO-10.1158-part2 (2020년 12월)", + "status": "IS", + "publishedAt": "2020-12" + }, + { + "title": "가시광 통신 기반 사물인터넷 서비스 - 제 3 부: 프로토콜", + "ref": "TTAK.KO-10.1158-part3 (2020년 12월)", + "status": "IS", + "publishedAt": "2020-12" + } + ] + } + ] + }, + { + "org": "ITU-T SG13", + "full": "Mobility Management", + "scope": "international", + "period": "2002 ~ 2012", + "projects": [ + { + "wg": "Main", + "name": "Mobility Management", + "documents": [ + { + "title": "NNI Mobility Management Requirements for SBI2K", + "ref": "ITU-T Supplement to Recommendation Q.Sup52 (December 2004)", + "status": "IS", + "publishedAt": "2004-12" + }, + { + "title": "Mobility Management Requirements for Next-Generation Networks", + "ref": "ITU-T Recommendation Q.1706/Y.2801 (July 2006)", + "status": "IS", + "publishedAt": "2006-07" + }, + { + "title": "Framework of IPv6 Multi-homing for NGN", + "ref": "ITU-T Recommendation Y.2052 (Feb. 2008)", + "status": "IS", + "publishedAt": "2008-02" + }, + { + "title": "Generic Framework of Mobility Management for Next-Generation Networks", + "ref": "ITU-T Recommendation Q.1707/Y.2804 (Feb. 2008)", + "status": "IS", + "publishedAt": "2008-02" + }, + { + "title": "Framework of Location Management for Next-Generation Networks", + "ref": "ITU-T Recommendation Q.1708/Y.2805 (October 2008)", + "status": "IS", + "publishedAt": "2008-10" + }, + { + "title": "Framework of Handover Control for Next-Generation Networks", + "ref": "ITU-T Recommendation Q.1709/Y.2806 (October 2008)", + "status": "IS", + "publishedAt": "2008-10" + }, + { + "title": "Framework of Mobility Management in Service Stratum for NGN", + "ref": "ITU-T Recommendation Y.2809 (November 2011)", + "status": "IS", + "publishedAt": "2011-11" + } + ] + } + ] + }, + { + "org": "ISO/IEC JTC1/SC6", + "full": "WG7: Network and Transport", + "scope": "international", + "period": "2000 ~ 2014", + "projects": [ + { + "wg": "Enhanced Communication Transport Protocol (ECTP)", + "name": "ISO/IEC 14476", + "documents": [ + { + "title": "ECTP-1: Specification of Simplex Multicast Transport", + "ref": "ITU-T Recommendation X.606 (October 2001) ISO/IEC IS 14476-1 (April 2002)", + "status": "IS", + "publishedAt": "2001-10" + }, + { + "title": "ECTP-2: Specification of QoS Management for Simplex Multicast Transport", + "ref": "ITU-T Recommendation X.606.1 (February 2003) ISO/IEC IS 14476-2 (June 2003)", + "status": "IS", + "publishedAt": "2003-02" + }, + { + "title": "ECTP-3: Specification of Duplex Multicast Transport", + "ref": "ITU-T Recommendation X.607 (February 2007) ISO/IEC IS 14476-3 (August 2008)", + "status": "IS", + "publishedAt": "2007-02" + }, + { + "title": "ECTP-4: Specification of QoS Management for Duplex Multicast Transport", + "ref": "ITU-T Recommendation X.607.1 (November 2008) ISO/IEC IS 14476-4 (April 2010)", + "status": "IS", + "publishedAt": "2008-11" + }, + { + "title": "ECTP-5: Specification of N-plex Multicast Transport", + "ref": "ITU-T Recommendation X.608 (February 2007) ISO/IEC IS 14476-5 (August 2008)", + "status": "IS", + "publishedAt": "2007-02" + }, + { + "title": "ECTP-6: Specification of QoS Management for N-plex Multicast Transport", + "ref": "ITU-T Recommendation X.608.1 (November 2008) ISO/IEC IS 14476-6 (April 2010)", + "status": "IS", + "publishedAt": "2008-11" + } + ] + }, + { + "wg": "Relayed Multicast Protocol (RMCP)", + "name": "ISO/IEC 16512", + "documents": [ + { + "title": "RMCP-1: Framework", + "ref": "ITU-T Recommendation X.603 (April 2004) ISO/IEC IS 16512-1", + "status": "IS", + "publishedAt": "2004-04" + }, + { + "title": "RMCP-2: Specification of Simplex Group Applications", + "ref": "ITU-T Recommendation X.603.1 (February 2007) ISO/IEC IS 16512-2", + "status": "IS", + "publishedAt": "2007-02" + }, + { + "title": "RMCP-3: Specification of N-plex Group Applications", + "ref": "ITU-T Recommendation X.603.2 (September 2010) ISO/IEC IS 16512-3", + "status": "IS", + "publishedAt": "2010-09" + } + ] + }, + { + "wg": "Mobile Multicast Communications (MMC)", + "name": "ISO/IEC 24793", + "documents": [ + { + "title": "MMC-1: MMC Framework", + "ref": "ITU-T Recommendation X.604 (March 2010) ISO/IEC IS 24793-1", + "status": "IS", + "publishedAt": "2010-03" + }, + { + "title": "MMC-2: MMC Protocol over Native IP Multicast Networks", + "ref": "ITU-T Recommendation X.604.1 (March 2010) ISO/IEC IS 24793-2", + "status": "IS", + "publishedAt": "2010-03" + }, + { + "title": "MMC-3: MMC Protocol over Overlay Multicast Networks", + "ref": "ITU-T Recommendation X.604.2 (September 2010) ISO/IEC IS 24793-3", + "status": "IS", + "publishedAt": "2010-09" + } + ] + }, + { + "wg": "Future Network", + "name": "Problem Statement and Requirements (FN-PSR): ISO/IEC TR 29181", + "documents": [ + { + "title": "Part 1: Overall Aspects", + "ref": "ISO/IEC TR 29181-1 (September 2012)", + "status": "TR", + "publishedAt": "2012-09" + }, + { + "title": "Part 2: Naming and Addressing", + "ref": "ISO/IEC TR 29181-2 (December 2014)", + "status": "TR", + "publishedAt": "2014-12" + }, + { + "title": "Part 3: Switching and Routing", + "ref": "ISO/IEC TR 29181-3 (April 2013)", + "status": "TR", + "publishedAt": "2013-04" + }, + { + "title": "Part 4: Mobility", + "ref": "ISO/IEC TR 29181-4 (December 2013)", + "status": "TR", + "publishedAt": "2013-12" + } + ] + } + ] + } +] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..6f80940 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ +services: + anl-backend: + build: + context: ./backend + dockerfile: Dockerfile + container_name: anl-backend-api + restart: unless-stopped + ports: + - "8080:8080" + environment: + - HOST=0.0.0.0 + - PORT=8080 + - DB_PATH=/app/data/anl.db + - GIN_MODE=release + - CORS_ALLOW_ORIGINS=* + - AUTO_MIGRATE=true + volumes: + - anl-db-data:/app/data + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/health"] + interval: 30s + timeout: 3s + retries: 3 + +volumes: + anl-db-data: + name: anl-sqlite-storage diff --git a/refer_landing_page/app/publications/page.tsx b/refer_landing_page/app/publications/page.tsx index ae24fad..3c23ce7 100644 --- a/refer_landing_page/app/publications/page.tsx +++ b/refer_landing_page/app/publications/page.tsx @@ -7,21 +7,9 @@ export const metadata: Metadata = { description: "AI Agent Networking Lab (ANL) research publications and patents overview", }; -const REPRESENTATIVE_HIGHLIGHT_TITLES = [ - "Globally Integrated Trust Authority (GITA) for Resource-Constrained Edge Devices in IoT and 6G", - "Application Level Trust Authority (APPLETA) for Resource-Constrained Edge Devices in IoT and 6G", - "mQUIC: Use of QUIC for Handover Support with Connection Migration in Wireless/Mobile Networks", - "Use of QUIC for CoAP Transport in IoT Networks", - "Use of QUIC for Mobile-Oriented Future Internet (Q-MOFI)", -]; - export default function PublicationsIndexPage() { - // Selected 5 representative publications - const highlights = REPRESENTATIVE_HIGHLIGHT_TITLES.map((title) => - publications.find( - (p) => p.title.trim().toLowerCase() === title.trim().toLowerCase() - ) - ).filter((p): p is (typeof publications)[0] => Boolean(p)); + // Selected representative publications (curated via database isHighlight flag) + const highlights = publications.filter((p) => p.isHighlight); return (
diff --git a/refer_landing_page/content/lectures.ts b/refer_landing_page/content/lectures.ts index 15e6748..862963c 100644 --- a/refer_landing_page/content/lectures.ts +++ b/refer_landing_page/content/lectures.ts @@ -1,4 +1,4 @@ -// AUTO-GENERATED by scripts/extract/generate_all.py — DO NOT EDIT BY HAND +// AUTO-GENERATED by backend/cmd/export-content — DO NOT EDIT BY HAND import { Semester } from "./types"; export const semesters: Semester[] = [ diff --git a/refer_landing_page/content/members.ts b/refer_landing_page/content/members.ts index b859730..aad978e 100644 --- a/refer_landing_page/content/members.ts +++ b/refer_landing_page/content/members.ts @@ -1,4 +1,4 @@ -// AUTO-GENERATED by scripts/extract/generate_all.py — DO NOT EDIT BY HAND +// AUTO-GENERATED by backend/cmd/export-content — DO NOT EDIT BY HAND import { Member, Alumnus } from "./types"; export const activeMembers: Member[] = [ diff --git a/refer_landing_page/content/projects.ts b/refer_landing_page/content/projects.ts index a84a576..864d9e4 100644 --- a/refer_landing_page/content/projects.ts +++ b/refer_landing_page/content/projects.ts @@ -1,4 +1,4 @@ -// AUTO-GENERATED by scripts/extract/generate_all.py — DO NOT EDIT BY HAND +// AUTO-GENERATED by backend/cmd/export-content — DO NOT EDIT BY HAND import { ResearchProject } from "./types"; export const researchProjects: ResearchProject[] = [ diff --git a/refer_landing_page/content/publications.ts b/refer_landing_page/content/publications.ts index b060c53..0bba6f3 100644 --- a/refer_landing_page/content/publications.ts +++ b/refer_landing_page/content/publications.ts @@ -1,27 +1,101 @@ -// AUTO-GENERATED by scripts/extract/generate_all.py — DO NOT EDIT BY HAND +// AUTO-GENERATED by backend/cmd/export-content — DO NOT EDIT BY HAND import { Publication, Patent } from "./types"; export const publications: Publication[] = [ + { + "category": "domestic-journal-conf", + "title": "다기관 데이터 기반 도메인 일반화를 적용한 소아청소년 뼈나이 자동 예측 딥러닝 모델의 개발 및 외부 검증", + "venue": "한국IT서비스학회지", + "volume": "제 25권 제 3호, pp. 75 ~ 87, 2026년 6월 (KCI)", + "publishedAt": "2026-06", + "kci": true + }, + { + "category": "domestic-journal-conf", + "title": "골반 X-ray 영상에서 딥러닝 기반 Risser Grade 자동 분류의 다기관 외부 검증 및 도메인 시프트 분석 : AI 의료기기 상용화 전략에 대한 시사점", + "venue": "경영컨설팅연구", + "volume": "제 26권 제 3호, pp. 337 ~ 348, 2026년 6월 (KCI)", + "publishedAt": "2026-06", + "kci": true + }, { "category": "intl-journal-conf", "title": "Globally Integrated Trust Authority (GITA) for Resource-Constrained Edge Devices in IoT and 6G", "venue": "IEEE Transactions on Network and Service Management", "volume": "Vol. 23, pp. 4490~4505, April 2026", - "publishedAt": "2026-04" + "publishedAt": "2026-04", + "isHighlight": true + }, + { + "category": "domestic-journal-conf", + "title": "엣지 장치용 경량 LLM 한국어 스팸 탐지 추론 성능 비교", + "venue": "사물인터넷융복합논문지", + "volume": "제 12권 제 2호, pp. 95 ~ 101, 2026년 4월 (KCI)", + "publishedAt": "2026-04", + "kci": true + }, + { + "category": "domestic-journal-conf", + "title": "성장클리닉 진단 보조를 위한 지식 그래프 및 대규모 언어 모델 융합 뉴로-심볼릭 임상의사결정 지원 시스템 설계", + "venue": "한국IT서비스학회지", + "volume": "제 25권 제 1호, pp. 63 ~ 73, 2026년 2월 (KCI)", + "publishedAt": "2026-02", + "kci": true + }, + { + "category": "domestic-journal-conf", + "title": "분산형 하이브리드 AI 기반 모바일 RPG NPC 시스템의 구현", + "venue": "사물인터넷융복합논문지", + "volume": "제 11권 제 6호, pp. 83 ~ 90, 2025년 12월 (KCI)", + "publishedAt": "2025-12", + "kci": true + }, + { + "category": "domestic-journal-conf", + "title": "관심 영역을 활용한 딥러닝 기반 해무 탐지 시스템", + "venue": "한국통신학회논문지", + "volume": "제 50권 제 7호, pp. 1133 ~ 1142, 2025년 7월 (SCOPUS & KCI)", + "publishedAt": "2025-07" + }, + { + "category": "domestic-journal-conf", + "title": "FSM과 강화학습 기반의 지능형 NPC AI: 2D 모바일 자동 진행 RPG 게임의 구현 연구", + "venue": "정보처리학회논문지", + "volume": "제 14권 제 6호, pp. 480 ~ 488, 2025년 6월 (KCI)", + "publishedAt": "2025-06", + "kci": true }, { "category": "intl-journal-conf", "title": "Application Level Trust Authority (APPLETA) for Resource-Constrained Edge Devices in IoT and 6G", "venue": "IEEE Transactions on Consumer Electronics", "volume": "Vol. 71, No. 2, pp. 4934~4948, May 2025", - "publishedAt": "2025-05" + "publishedAt": "2025-05", + "isHighlight": true + }, + { + "category": "domestic-journal-conf", + "title": "공공기관 IT시스템 보안 강화를 위한 사이버 위협 점검/수집 시스템", + "venue": "한국IT서비스학회지", + "volume": "제 24권 제 2호, pp. 31 ~ 46, 2025년 4월 (KCI)", + "publishedAt": "2025-04", + "kci": true + }, + { + "category": "domestic-journal-conf", + "title": "QUIC 프로토콜의 혼잡제어 성능 비교 분석", + "venue": "정보처리학회논문지", + "volume": "제 14권 제 1호, pp. 9 ~ 13, 2025년 1월 (KCI)", + "publishedAt": "2025-01", + "kci": true }, { "category": "intl-journal-conf", "title": "mQUIC: Use of QUIC for Handover Support with Connection Migration in Wireless/Mobile Networks", "venue": "IEEE Communications Magazine", "volume": "Vol. 62, Issue 4, pp. 128~134, April 2024", - "publishedAt": "2024-04" + "publishedAt": "2024-04", + "isHighlight": true }, { "category": "intl-journal-conf", @@ -35,14 +109,16 @@ export const publications: Publication[] = [ "title": "Use of QUIC for Mobile-Oriented Future Internet (Q-MOFI)", "venue": "Electronics", "volume": "Vol. 13, Article No. 13020431, pp. 1~20, January 2024", - "publishedAt": "2024-01" + "publishedAt": "2024-01", + "isHighlight": true }, { "category": "intl-journal-conf", "title": "Use of QUIC for CoAP Transport in IoT Networks", "venue": "Internet of Things (ISSN: 2543-1536)", "volume": "Vol. 24, pp. 1~16, Article No. 100905, December 2023", - "publishedAt": "2023-12" + "publishedAt": "2023-12", + "isHighlight": true }, { "category": "intl-journal-conf", @@ -51,6 +127,20 @@ export const publications: Publication[] = [ "volume": "pp. 1394~1396, October 2023", "publishedAt": "2023-10" }, + { + "category": "domestic-journal-conf", + "title": "멀티미디어 영상회의 서비스를 위한 사용자 체감 품질 측정 방법 표준 기술 동향", + "venue": "한국컴퓨터통신연구회(OSIA) S&TR Journal", + "volume": "제 36권 제 2호, pp. 15 ~ 20, 2023년 9월", + "publishedAt": "2023-09" + }, + { + "category": "domestic-journal-conf", + "title": "차량용 인포테인먼트 서비스 표준화 동향", + "venue": "정보과학회지", + "volume": "제 41권 제 9호, pp. 25 ~ 29, 2023년 9월", + "publishedAt": "2023-09" + }, { "category": "intl-journal-conf", "title": "Performance Evaluation of AMQP over QUIC in the Internet-of-Thing Networks", @@ -93,6 +183,13 @@ export const publications: Publication[] = [ "volume": "Vol. 9, pp. 154194~154203, November 2021", "publishedAt": "2021-11" }, + { + "category": "domestic-journal-conf", + "title": "NAT 기반 사물인터넷 환경에서 실시간 통신 지원을 위한 MQTT-CoAP 혼합 기법", + "venue": "한국통신학회논문지", + "volume": "제 46권 제 11호, pp. 1822 ~ 1833, 2021년 11월 (SCOPUS & KCI)", + "publishedAt": "2021-11" + }, { "category": "intl-journal-conf", "title": "Proxy-based Adaptive Transmission of MP-QUIC in Internet-of-Things Environment", @@ -100,6 +197,14 @@ export const publications: Publication[] = [ "volume": "Vol. 10, Article No. 10172175, pp. 1~14, September 2021", "publishedAt": "2021-09" }, + { + "category": "domestic-journal-conf", + "title": "웹 및 스트리밍 서비스에 대한 QUIC 프로토콜 성능 분석", + "venue": "정보처리학회논문지: 컴퓨터 및 통신 시스템", + "volume": "제 10권 제 5호, pp. 137 ~ 144, 2021년 5월 (KCI)", + "publishedAt": "2021-05", + "kci": true + }, { "category": "intl-journal-conf", "title": "Digital Certificate Verification Scheme for Smart Grid Using Fog Computing (FONICA)", @@ -142,6 +247,14 @@ export const publications: Publication[] = [ "volume": "Vol. 9, Article No. 9010058, pp. 1~26, January 2020", "publishedAt": "2020-01" }, + { + "category": "domestic-journal-conf", + "title": "가시광 통신 기반 출결 관리 시스템 설계 및 구현", + "venue": "한국통신학회논문지", + "volume": "제 44권 제 7호, pp. 1381 ~ 1390, 2019년 7월 (KCI)", + "publishedAt": "2019-07", + "kci": true + }, { "category": "intl-journal-conf", "title": "Mobile-Oriented Future Internet: Implementation and Experimentations over EU-Korea Testbed", @@ -184,6 +297,14 @@ export const publications: Publication[] = [ "volume": "Vol. 18, Article No. s18082741, August 2018", "publishedAt": "2018-08" }, + { + "category": "domestic-journal-conf", + "title": "In-Vehicle Infotainment 시스템에서 Configuration Protocol의 설계 및 구현", + "venue": "한국통신학회논문지", + "volume": "제 43권 제 7호, pp. 1140 ~ 1151, 2018년 7월 (KCI)", + "publishedAt": "2018-07", + "kci": true + }, { "category": "intl-journal-conf", "title": "Enhanced group communication in constrained application protocol-based Internet-of-things networks", @@ -233,6 +354,14 @@ export const publications: Publication[] = [ "volume": "Vol. 12, No. 2, pp. 196~213, June 2016 (SCOPUS)", "publishedAt": "2016-06" }, + { + "category": "domestic-journal-conf", + "title": "BLE 네트워크 상에서 사물인터넷 서비스 제공을 위한 CoAP과 6LoWPAN 구현", + "venue": "방송공학회논문지", + "volume": "제 21권 제 3호, pp. 298 ~ 306, 2016년 5월 (KCI)", + "publishedAt": "2016-05", + "kci": true + }, { "category": "intl-journal-conf", "title": "TRILL-Based Mobile Packet Core Network for 5G Mobile Communication Systems", @@ -247,6 +376,14 @@ export const publications: Publication[] = [ "volume": "Vol. 11, Issue 10, 12 pages, October 2015", "publishedAt": "2015-10" }, + { + "category": "domestic-journal-conf", + "title": "A Comparative Analysis of Centralized and Distributed Mobility Management in IP-Based Mobile Networks", + "venue": "Telecommunications Review", + "volume": "제 25권 제 4호, pp. 656 ~ 671, 2015년 8월 (KCI)", + "publishedAt": "2015-08", + "kci": true + }, { "category": "intl-journal-conf", "title": "An ID/Locator Separation Based Group Mobility Management in Wireless Body Area Network", @@ -254,6 +391,21 @@ export const publications: Publication[] = [ "volume": "Vol. 2015, Open Access Article (Article ID 537205), 12 pages, July 2015", "publishedAt": "2015-07" }, + { + "category": "domestic-journal-conf", + "title": "IoT(사물기반 인터넷) 기반 헬스케어 서비스: 일상 생활습관 ‧ 건강관리 중심으로", + "venue": "생명공학정책연구센터(BioINpro)", + "volume": "BioINpro 제 13호, pp. 1 ~ 12, 2015년 6월", + "publishedAt": "2015-06" + }, + { + "category": "domestic-journal-conf", + "title": "Mobility Support Using Locator-Identifier Separation Protocol in 4G Mobile Communication Networks", + "venue": "Telecommunications Review", + "volume": "제 25권 제 2호, pp. 337 ~ 355, 2015년 4월 (KCI)", + "publishedAt": "2015-04", + "kci": true + }, { "category": "intl-journal-conf", "title": "Fast Device Discovery for Remote Device Management in Lighting Control Networks", @@ -261,6 +413,36 @@ export const publications: Publication[] = [ "volume": "Vol. 11, No. 1, pp. 125~133, March 2015 (SCOPUS)", "publishedAt": "2015-03" }, + { + "category": "domestic-journal-conf", + "title": "사물인터넷 기반 헬스케어 서비스 및 플랫폼 동향", + "venue": "한국통신학회지(정보와통신)", + "volume": "제 31권 제 12호, pp. 25 ~ 30, 2014년 12월", + "publishedAt": "2014-12" + }, + { + "category": "domestic-journal-conf", + "title": "모바일 중심 미래 인터넷: OpenFlow 기반 구현 및 KOREN 테스트베드 실험", + "venue": "정보과학회논문지: 정보통신", + "volume": "제 41권 제 4호, pp. 167 ~ 176, 2014년 8월 (KCI)", + "publishedAt": "2014-08", + "kci": true + }, + { + "category": "domestic-journal-conf", + "title": "Load Balancing for Proxy Mobile IPv6 in SAE-based Mobile Networks", + "venue": "Telecommunications Review", + "volume": "제 24권 제 3호, pp. 433 ~ 448, 2014년 6월 (KCI)", + "publishedAt": "2014-06", + "kci": true + }, + { + "category": "domestic-journal-conf", + "title": "LED 기반 조명 제어를 위한 PLASA 표준 프로토콜 기술", + "venue": "조명전기설비학회지", + "volume": "제 28권 제 3호, pp. 9 ~ 21, 2014년 5월", + "publishedAt": "2014-05" + }, { "category": "intl-journal-conf", "title": "Performance Analysis of Distributed Mapping System in ID/Locator Separation Architectures", @@ -296,6 +478,13 @@ export const publications: Publication[] = [ "volume": "Vol. 72, No. 1, pp. 565~579, September 2013", "publishedAt": "2013-09" }, + { + "category": "domestic-journal-conf", + "title": "5세대 이동통신에서의 네트워크 이슈", + "venue": "정보과학회지", + "volume": "제 31권 제 9호, pp. 20 ~ 26, 2013년 9월", + "publishedAt": "2013-09" + }, { "category": "intl-journal-conf", "title": "Mobile Oriented Future Internet (MOFI): Architectural Design and Implementations", @@ -303,6 +492,52 @@ export const publications: Publication[] = [ "volume": "Vol. 35, No. 4, pp. 666~676, August 2013", "publishedAt": "2013-08" }, + { + "category": "domestic-journal-conf", + "title": "무선 인터넷 환경에서 SCTP 프로토콜의 성능 최적화 방안", + "venue": "Telecommunications Review", + "volume": "제 23권 제 3호, pp. 381 ~ 392, 2013년 6월 (KCI)< 무선 네트워크 환경에서 안드로이드 기반 SCTP 프로토콜의 성능 분석 정보과학회논문지: 시스템 및 이론, 제 40권 제 2호, pp. 105 ~ 110, 2013년 4월 (KCI)", + "publishedAt": "2013-06", + "kci": true + }, + { + "category": "domestic-journal-conf", + "title": "조명 제어 네트워크에서 디바이스 관리를 위한 표준 프로토콜 기술 동향", + "venue": "조명전기설비학회지", + "volume": "제 27권 제 2호, pp. 56 ~ 65, 2013년 3월", + "publishedAt": "2013-03" + }, + { + "category": "domestic-journal-conf", + "title": "ID-LOC 분리 기반 인터넷 구조에서 분산형 매핑 시스템의 구현 및 평가", + "venue": "한국통신학회논문지", + "volume": "제 37B권(네트워크 및 서비스) 제 11호, pp. 984 ~ 992, 2012년 11월 (KCI)", + "publishedAt": "2012-11", + "kci": true + }, + { + "category": "domestic-journal-conf", + "title": "이동통신 로밍 환경에서 빠른 홈망 복귀를 위한 망탐색 알고리즘", + "venue": "정보처리학회논문지", + "volume": "제 19-C권 제 2호, pp. 149 ~ 152, 2012년 4월 (KCI)", + "publishedAt": "2012-04", + "kci": true + }, + { + "category": "domestic-journal-conf", + "title": "미래 인터넷의 이동 네트워크 구조 및 연구동향", + "venue": "한국통신학회지(정보와통신)", + "volume": "제 29권 제 3호, pp. 41 ~ 48, 2012년 3월", + "publishedAt": "2012-03" + }, + { + "category": "domestic-journal-conf", + "title": "모바일 단말 환경에서 웹브라우저의 로딩속도 개선 기법", + "venue": "Telecommunications Review", + "volume": "제 22권 제 1호, pp. 139 ~ 152, 2012년 2월 (KCI)", + "publishedAt": "2012-02", + "kci": true + }, { "category": "intl-journal-conf", "title": "Network-Based Distributed Mobility Control in Localized Mobile LISP Networks", @@ -317,6 +552,22 @@ export const publications: Publication[] = [ "volume": "Vol. 7, No. 4, pp. 627~634, December 2011 (SCOPUS)", "publishedAt": "2011-12" }, + { + "category": "domestic-journal-conf", + "title": "Binding Query를 활용한 Proxy Mobile IPv6의 성능 향상 기법", + "venue": "한국통신학회논문지", + "volume": "제 36권 제 11호(네트워크 및 융합서비스), pp. 1269 ~ 1276, 2011년 11월 (KCI)", + "publishedAt": "2011-11", + "kci": true + }, + { + "category": "domestic-journal-conf", + "title": "이동 LISP망에서 네트워크 기반 이동성 제어 기법", + "venue": "정보처리학회논문지", + "volume": "제 18-C권 제 5호, pp. 339 ~ 342, 2011년 10월 (KCI)", + "publishedAt": "2011-10", + "kci": true + }, { "category": "intl-journal-conf", "title": "Distributed Mobility Control in Proxy Mobile IPv6 Networks", @@ -331,6 +582,36 @@ export const publications: Publication[] = [ "volume": "Vol. 57, No. 4, pp. 707~725, April 2011", "publishedAt": "2011-04" }, + { + "category": "domestic-journal-conf", + "title": "MOFI: Future Internet Architecture with Address-free Hosts for Mobile Environments", + "venue": "Telecommunications Review", + "volume": "제 21권 제 2호, pp. 343 ~ 358, 2011년 4월 (KCI)", + "publishedAt": "2011-04", + "kci": true + }, + { + "category": "domestic-journal-conf", + "title": "미래 인터넷을 위한 네이밍과 어드레싱을 위한 연구", + "venue": "정보과학회지", + "volume": "제 29권 제 3호, pp. 53 ~ 65, 2011년 3월", + "publishedAt": "2011-03" + }, + { + "category": "domestic-journal-conf", + "title": "Mobile Oriented Future Internet (MOFI): Design Considerations and Architecture", + "venue": "OSIA Standards & Technology Review (ISSN:1738-9887)", + "volume": "Vol. 24, No. 1, pp. 61 ~ 77, 2011년 3월", + "publishedAt": "2011-03" + }, + { + "category": "domestic-journal-conf", + "title": "Fast Tree Join for Seamless Multicast Handover in FMIPv6-based Mobile Networks", + "venue": "Telecommunications Review", + "volume": "제 20권 제 6호, pp. 993 ~ 1003, 2010년 12월 (KCI)", + "publishedAt": "2010-12", + "kci": true + }, { "category": "intl-journal-conf", "title": "Multicast Handover Agents for Fast Handover in Wireless Multicast Networks", @@ -352,435 +633,26 @@ export const publications: Publication[] = [ "volume": "Vol. 22, No. 12, pp. 1573~1591, December 2009", "publishedAt": "2009-12" }, - { - "category": "intl-journal-conf", - "title": "Corruption-aware Adaptive Increase and Adaptive Decrease Algorithm for TCP Error and Congestion Controls in Wireless Networks", - "venue": "International Journal of Communication Systems", - "volume": "Vol. 22, No. 5, pp. 543~564, May 2009", - "publishedAt": "2009-05" - }, - { - "category": "intl-journal-conf", - "title": "Partial CRC Checksum of SCTP for Error Control over Wireless Networks", - "venue": "Wireless Personal Communications", - "volume": "Vol. 48, No. 2, pp. 247~260, January 2009", - "publishedAt": "2009-01" - }, - { - "category": "intl-journal-conf", - "title": "Analysis of Handover Latency for Mobile IPv6 and mSCTP", - "venue": "Journal of Information Processing Systems", - "volume": "Vol. 4, No. 3, pp. 87~96, September 2008 (SCOPUS)", - "publishedAt": "2008-09" - }, - { - "category": "intl-journal-conf", - "title": "mSIP: Extension of SIP for Soft Handover with Bicasting", - "venue": "IEEE Communications Letters", - "volume": "Vol. 12, No. 7, pp. 532~534, July 2008", - "publishedAt": "2008-07" - }, - { - "category": "intl-journal-conf", - "title": "Chunk Checksum of SCTP for Throughput Enhancement", - "venue": "IEEE Communications Letters", - "volume": "Vol. 10, No. 11, pp. 796~798, November 2006", - "publishedAt": "2006-11" - }, - { - "category": "intl-journal-conf", - "title": "Mobility Management Requirements and Framework for Systems Beyond IMT-2000", - "venue": "Journal of Communications and Networks", - "volume": "Vol. 7, No. 2, pp. 171~177, June 2005", - "publishedAt": "2005-06" - }, - { - "category": "intl-journal-conf", - "title": "Transport Layer Mobility Support Utilizing Link Signal Strength Information", - "venue": "IEICE Transactions on Communications", - "volume": "Vol. E87-B, No. 9, pp. 2548~2556, September 2004", - "publishedAt": "2004-09" - }, - { - "category": "intl-journal-conf", - "title": "Limiting the Length of BET for Tunnel-Based IP Fast Handover", - "venue": "IEICE Transactions on Fundamentals of Electronics Communications and Computer Sciences", - "volume": "Vol. E87-A, No. 6, pp. 1527~1530, June 2004", - "publishedAt": "2004-06" - }, - { - "category": "intl-journal-conf", - "title": "mSCTP for Soft Handover in Transport Layer", - "venue": "IEEE Communications Letters", - "volume": "Vol. 8, No. 3, pp. 189~191, March 2004", - "publishedAt": "2004-03" - }, - { - "category": "intl-journal-conf", - "title": "Configuration of ACK Trees for Multicast Transport Protocols", - "venue": "ETRI Journal", - "volume": "Vol. 23, No. 3, pp. 111~120, September 2001", - "publishedAt": "2001-09" - }, - { - "category": "intl-journal-conf", - "title": "Assignment of ADM Rings and DCS Mesh in Telecommunication Networks", - "venue": "Journal of the O.R. Society", - "volume": "Vol. 52, No. 4, pp. 440~448, April 2001", - "publishedAt": "2001-04" - }, - { - "category": "intl-journal-conf", - "title": "Multicast Delivery Based on Unicast and Subnet Multicast", - "venue": "IEEE Communications Letters", - "volume": "Vol. 5, No. 4, pp. 181~183, April 2001", - "publishedAt": "2001-04" - }, - { - "category": "intl-journal-conf", - "title": "Dynamic Bandwidth Allocation Scheme for Multiple Real-time VBR Videos over ATM Networks", - "venue": "Telecommunications Systems", - "volume": "Vol. 15, pp.359~380, December 2000", - "publishedAt": "2000-12" - }, - { - "category": "intl-journal-conf", - "title": "Minimizing Cost and Delay in Shared Multicast Trees", - "venue": "ETRI Journal", - "volume": "Vol. 22, No. 1, pp.30~37, March 2000", - "publishedAt": "2000-03" - }, - { - "category": "intl-journal-conf", - "title": "Non-Core Based Shared Tree Architecture for IP Multicasting", - "venue": "Electronics Letters", - "volume": "Vol. 35, No. 11, pp. 872~873, May 1999", - "publishedAt": "1999-05" - }, - { - "category": "intl-journal-conf", - "title": "A Design of the Self-Healing ATM Networks Based on the Backup Virtual Path", - "venue": "Computers and Operations Research", - "volume": "Vol. 25, No. 7/8, pp. 595~609, July 1998", - "publishedAt": "1998-07" - }, - { - "category": "intl-journal-conf", - "title": "A Design of the Minimum Cost Ring-Chain Network with Dual-Homing Survivability: Tabu Search Approach", - "venue": "Computers and Operations Research", - "volume": "Vol. 24, No. 9, pp. 883~897, September 1997", - "publishedAt": "1997-09" - }, - { - "category": "intl-journal-conf", - "title": "A Tabu Search for the Survivable Fiber Optic Communication Network Design", - "venue": "Computers and Industrial Engineering", - "volume": "Vol. 28, Issue 4, pp. 689~700, October 1995", - "publishedAt": "1995-10" - }, - { - "category": "domestic-journal-conf", - "title": "다기관 데이터 기반 도메인 일반화를 적용한 소아청소년 뼈나이 자동 예측 딥러닝 모델의 개발 및 외부 검증", - "venue": "한국IT서비스학회지", - "volume": "제 25권 제 3호, pp. 75 ~ 87, 2026년 6월 (KCI)", - "publishedAt": "2026-06", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "골반 X-ray 영상에서 딥러닝 기반 Risser Grade 자동 분류의 다기관 외부 검증 및 도메인 시프트 분석 : AI 의료기기 상용화 전략에 대한 시사점", - "venue": "경영컨설팅연구", - "volume": "제 26권 제 3호, pp. 337 ~ 348, 2026년 6월 (KCI)", - "publishedAt": "2026-06", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "엣지 장치용 경량 LLM 한국어 스팸 탐지 추론 성능 비교", - "venue": "사물인터넷융복합논문지", - "volume": "제 12권 제 2호, pp. 95 ~ 101, 2026년 4월 (KCI)", - "publishedAt": "2026-04", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "성장클리닉 진단 보조를 위한 지식 그래프 및 대규모 언어 모델 융합 뉴로-심볼릭 임상의사결정 지원 시스템 설계", - "venue": "한국IT서비스학회지", - "volume": "제 25권 제 1호, pp. 63 ~ 73, 2026년 2월 (KCI)", - "publishedAt": "2026-02", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "분산형 하이브리드 AI 기반 모바일 RPG NPC 시스템의 구현", - "venue": "사물인터넷융복합논문지", - "volume": "제 11권 제 6호, pp. 83 ~ 90, 2025년 12월 (KCI)", - "publishedAt": "2025-12", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "관심 영역을 활용한 딥러닝 기반 해무 탐지 시스템", - "venue": "한국통신학회논문지", - "volume": "제 50권 제 7호, pp. 1133 ~ 1142, 2025년 7월 (SCOPUS & KCI)", - "publishedAt": "2025-07", - "kci": false - }, - { - "category": "domestic-journal-conf", - "title": "FSM과 강화학습 기반의 지능형 NPC AI: 2D 모바일 자동 진행 RPG 게임의 구현 연구", - "venue": "정보처리학회논문지", - "volume": "제 14권 제 6호, pp. 480 ~ 488, 2025년 6월 (KCI)", - "publishedAt": "2025-06", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "공공기관 IT시스템 보안 강화를 위한 사이버 위협 점검/수집 시스템", - "venue": "한국IT서비스학회지", - "volume": "제 24권 제 2호, pp. 31 ~ 46, 2025년 4월 (KCI)", - "publishedAt": "2025-04", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "QUIC 프로토콜의 혼잡제어 성능 비교 분석", - "venue": "정보처리학회논문지", - "volume": "제 14권 제 1호, pp. 9 ~ 13, 2025년 1월 (KCI)", - "publishedAt": "2025-01", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "멀티미디어 영상회의 서비스를 위한 사용자 체감 품질 측정 방법 표준 기술 동향", - "venue": "한국컴퓨터통신연구회(OSIA) S&TR Journal", - "volume": "제 36권 제 2호, pp. 15 ~ 20, 2023년 9월", - "publishedAt": "2023-09", - "kci": false - }, - { - "category": "domestic-journal-conf", - "title": "차량용 인포테인먼트 서비스 표준화 동향", - "venue": "정보과학회지", - "volume": "제 41권 제 9호, pp. 25 ~ 29, 2023년 9월", - "publishedAt": "2023-09", - "kci": false - }, - { - "category": "domestic-journal-conf", - "title": "NAT 기반 사물인터넷 환경에서 실시간 통신 지원을 위한 MQTT-CoAP 혼합 기법", - "venue": "한국통신학회논문지", - "volume": "제 46권 제 11호, pp. 1822 ~ 1833, 2021년 11월 (SCOPUS & KCI)", - "publishedAt": "2021-11", - "kci": false - }, - { - "category": "domestic-journal-conf", - "title": "웹 및 스트리밍 서비스에 대한 QUIC 프로토콜 성능 분석", - "venue": "정보처리학회논문지: 컴퓨터 및 통신 시스템", - "volume": "제 10권 제 5호, pp. 137 ~ 144, 2021년 5월 (KCI)", - "publishedAt": "2021-05", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "가시광 통신 기반 출결 관리 시스템 설계 및 구현", - "venue": "한국통신학회논문지", - "volume": "제 44권 제 7호, pp. 1381 ~ 1390, 2019년 7월 (KCI)", - "publishedAt": "2019-07", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "In-Vehicle Infotainment 시스템에서 Configuration Protocol의 설계 및 구현", - "venue": "한국통신학회논문지", - "volume": "제 43권 제 7호, pp. 1140 ~ 1151, 2018년 7월 (KCI)", - "publishedAt": "2018-07", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "BLE 네트워크 상에서 사물인터넷 서비스 제공을 위한 CoAP과 6LoWPAN 구현", - "venue": "방송공학회논문지", - "volume": "제 21권 제 3호, pp. 298 ~ 306, 2016년 5월 (KCI)", - "publishedAt": "2016-05", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "A Comparative Analysis of Centralized and Distributed Mobility Management in IP-Based Mobile Networks", - "venue": "Telecommunications Review", - "volume": "제 25권 제 4호, pp. 656 ~ 671, 2015년 8월 (KCI)", - "publishedAt": "2015-08", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "IoT(사물기반 인터넷) 기반 헬스케어 서비스: 일상 생활습관 ‧ 건강관리 중심으로", - "venue": "생명공학정책연구센터(BioINpro)", - "volume": "BioINpro 제 13호, pp. 1 ~ 12, 2015년 6월", - "publishedAt": "2015-06", - "kci": false - }, - { - "category": "domestic-journal-conf", - "title": "Mobility Support Using Locator-Identifier Separation Protocol in 4G Mobile Communication Networks", - "venue": "Telecommunications Review", - "volume": "제 25권 제 2호, pp. 337 ~ 355, 2015년 4월 (KCI)", - "publishedAt": "2015-04", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "사물인터넷 기반 헬스케어 서비스 및 플랫폼 동향", - "venue": "한국통신학회지(정보와통신)", - "volume": "제 31권 제 12호, pp. 25 ~ 30, 2014년 12월", - "publishedAt": "2014-12", - "kci": false - }, - { - "category": "domestic-journal-conf", - "title": "모바일 중심 미래 인터넷: OpenFlow 기반 구현 및 KOREN 테스트베드 실험", - "venue": "정보과학회논문지: 정보통신", - "volume": "제 41권 제 4호, pp. 167 ~ 176, 2014년 8월 (KCI)", - "publishedAt": "2014-08", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "Load Balancing for Proxy Mobile IPv6 in SAE-based Mobile Networks", - "venue": "Telecommunications Review", - "volume": "제 24권 제 3호, pp. 433 ~ 448, 2014년 6월 (KCI)", - "publishedAt": "2014-06", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "LED 기반 조명 제어를 위한 PLASA 표준 프로토콜 기술", - "venue": "조명전기설비학회지", - "volume": "제 28권 제 3호, pp. 9 ~ 21, 2014년 5월", - "publishedAt": "2014-05", - "kci": false - }, - { - "category": "domestic-journal-conf", - "title": "5세대 이동통신에서의 네트워크 이슈", - "venue": "정보과학회지", - "volume": "제 31권 제 9호, pp. 20 ~ 26, 2013년 9월", - "publishedAt": "2013-09", - "kci": false - }, - { - "category": "domestic-journal-conf", - "title": "무선 인터넷 환경에서 SCTP 프로토콜의 성능 최적화 방안", - "venue": "Telecommunications Review", - "volume": "제 23권 제 3호, pp. 381 ~ 392, 2013년 6월 (KCI)< 무선 네트워크 환경에서 안드로이드 기반 SCTP 프로토콜의 성능 분석 정보과학회논문지: 시스템 및 이론, 제 40권 제 2호, pp. 105 ~ 110, 2013년 4월 (KCI)", - "publishedAt": "2013-06", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "조명 제어 네트워크에서 디바이스 관리를 위한 표준 프로토콜 기술 동향", - "venue": "조명전기설비학회지", - "volume": "제 27권 제 2호, pp. 56 ~ 65, 2013년 3월", - "publishedAt": "2013-03", - "kci": false - }, - { - "category": "domestic-journal-conf", - "title": "ID-LOC 분리 기반 인터넷 구조에서 분산형 매핑 시스템의 구현 및 평가", - "venue": "한국통신학회논문지", - "volume": "제 37B권(네트워크 및 서비스) 제 11호, pp. 984 ~ 992, 2012년 11월 (KCI)", - "publishedAt": "2012-11", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "이동통신 로밍 환경에서 빠른 홈망 복귀를 위한 망탐색 알고리즘", - "venue": "정보처리학회논문지", - "volume": "제 19-C권 제 2호, pp. 149 ~ 152, 2012년 4월 (KCI)", - "publishedAt": "2012-04", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "미래 인터넷의 이동 네트워크 구조 및 연구동향", - "venue": "한국통신학회지(정보와통신)", - "volume": "제 29권 제 3호, pp. 41 ~ 48, 2012년 3월", - "publishedAt": "2012-03", - "kci": false - }, - { - "category": "domestic-journal-conf", - "title": "모바일 단말 환경에서 웹브라우저의 로딩속도 개선 기법", - "venue": "Telecommunications Review", - "volume": "제 22권 제 1호, pp. 139 ~ 152, 2012년 2월 (KCI)", - "publishedAt": "2012-02", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "Binding Query를 활용한 Proxy Mobile IPv6의 성능 향상 기법", - "venue": "한국통신학회논문지", - "volume": "제 36권 제 11호(네트워크 및 융합서비스), pp. 1269 ~ 1276, 2011년 11월 (KCI)", - "publishedAt": "2011-11", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "이동 LISP망에서 네트워크 기반 이동성 제어 기법", - "venue": "정보처리학회논문지", - "volume": "제 18-C권 제 5호, pp. 339 ~ 342, 2011년 10월 (KCI)", - "publishedAt": "2011-10", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "MOFI: Future Internet Architecture with Address-free Hosts for Mobile Environments", - "venue": "Telecommunications Review", - "volume": "제 21권 제 2호, pp. 343 ~ 358, 2011년 4월 (KCI)", - "publishedAt": "2011-04", - "kci": true - }, - { - "category": "domestic-journal-conf", - "title": "미래 인터넷을 위한 네이밍과 어드레싱을 위한 연구", - "venue": "정보과학회지", - "volume": "제 29권 제 3호, pp. 53 ~ 65, 2011년 3월", - "publishedAt": "2011-03", - "kci": false - }, - { - "category": "domestic-journal-conf", - "title": "Mobile Oriented Future Internet (MOFI): Design Considerations and Architecture", - "venue": "OSIA Standards & Technology Review (ISSN:1738-9887)", - "volume": "Vol. 24, No. 1, pp. 61 ~ 77, 2011년 3월", - "publishedAt": "2011-03", - "kci": false - }, - { - "category": "domestic-journal-conf", - "title": "Fast Tree Join for Seamless Multicast Handover in FMIPv6-based Mobile Networks", - "venue": "Telecommunications Review", - "volume": "제 20권 제 6호, pp. 993 ~ 1003, 2010년 12월 (KCI)", - "publishedAt": "2010-12", - "kci": true - }, { "category": "domestic-journal-conf", "title": "모바일 IPTV 멀티캐스트 전송 및 서비스 기술 동향", "venue": "정보과학회지", "volume": "제 27권 제 8호, pp. 67 ~ 73, 2009년 8월", - "publishedAt": "2009-08", - "kci": false + "publishedAt": "2009-08" }, { "category": "domestic-journal-conf", "title": "이동통신망에서의 모바일 IPTV 표준기술", "venue": "개방형컴퓨터통신연구회(OSIA) Standards & Technology Review", "volume": "2009년 제 2호, pp. 49 ~ 59, 2009년 6월", - "publishedAt": "2009-06", - "kci": false + "publishedAt": "2009-06" + }, + { + "category": "intl-journal-conf", + "title": "Corruption-aware Adaptive Increase and Adaptive Decrease Algorithm for TCP Error and Congestion Controls in Wireless Networks", + "venue": "International Journal of Communication Systems", + "volume": "Vol. 22, No. 5, pp. 543~564, May 2009", + "publishedAt": "2009-05" }, { "category": "domestic-journal-conf", @@ -790,6 +662,13 @@ export const publications: Publication[] = [ "publishedAt": "2009-02", "kci": true }, + { + "category": "intl-journal-conf", + "title": "Partial CRC Checksum of SCTP for Error Control over Wireless Networks", + "venue": "Wireless Personal Communications", + "volume": "Vol. 48, No. 2, pp. 247~260, January 2009", + "publishedAt": "2009-01" + }, { "category": "domestic-journal-conf", "title": "A Cross-layer Approach for Throughput Enhancement in Unsteady Satellite Networks", @@ -806,6 +685,13 @@ export const publications: Publication[] = [ "publishedAt": "2008-10", "kci": true }, + { + "category": "intl-journal-conf", + "title": "Analysis of Handover Latency for Mobile IPv6 and mSCTP", + "venue": "Journal of Information Processing Systems", + "volume": "Vol. 4, No. 3, pp. 87~96, September 2008 (SCOPUS)", + "publishedAt": "2008-09" + }, { "category": "domestic-journal-conf", "title": "리눅스 환경에서 SCTP와 TCP 프로토콜의 성능 비교", @@ -830,6 +716,13 @@ export const publications: Publication[] = [ "publishedAt": "2008-08", "kci": true }, + { + "category": "intl-journal-conf", + "title": "mSIP: Extension of SIP for Soft Handover with Bicasting", + "venue": "IEEE Communications Letters", + "volume": "Vol. 12, No. 7, pp. 532~534, July 2008", + "publishedAt": "2008-07" + }, { "category": "domestic-journal-conf", "title": "Standardization on Mobility Management Architectures and Protocols for All-IP Mobile Networks", @@ -843,8 +736,7 @@ export const publications: Publication[] = [ "title": "ITU-T NGN-GSI 이동성 관리 표준개발 동향", "venue": "개방형컴퓨터통신연구회(OSIA) Standards & Technology Review", "volume": "2008년 제 1호, pp. 37 ~ 44, 2008년 3월", - "publishedAt": "2008-03", - "kci": false + "publishedAt": "2008-03" }, { "category": "domestic-journal-conf", @@ -859,24 +751,28 @@ export const publications: Publication[] = [ "title": "ITU-T SG19 이동성 관리기술 표준화 동향", "venue": "개방형컴퓨터통신연구회(OSIA) Standards & Technology Review", "volume": "2007년 제 2호, pp. 13 ~ 26, 2007년 6월", - "publishedAt": "2007-06", - "kci": false + "publishedAt": "2007-06" }, { "category": "domestic-journal-conf", "title": "SCTP 기반 수송계층 이동성 기술", "venue": "정보과학회 정보통신기술(정보통신연구회)", "volume": "제 20권 제 1호, pp. 64 ~ 79, 2007년 5월", - "publishedAt": "2007-05", - "kci": false + "publishedAt": "2007-05" }, { "category": "domestic-journal-conf", "title": "IP 핸드오버: 망기반 기법 versus 종단간 기법", "venue": "한국통신학회지(정보와통신)", "volume": "제 24권 제 4호, pp. 106 ~ 115, 2007년 4월", - "publishedAt": "2007-04", - "kci": false + "publishedAt": "2007-04" + }, + { + "category": "intl-journal-conf", + "title": "Chunk Checksum of SCTP for Throughput Enhancement", + "venue": "IEEE Communications Letters", + "volume": "Vol. 10, No. 11, pp. 796~798, November 2006", + "publishedAt": "2006-11" }, { "category": "domestic-journal-conf", @@ -894,6 +790,20 @@ export const publications: Publication[] = [ "publishedAt": "2006-04", "kci": true }, + { + "category": "intl-journal-conf", + "title": "Mobility Management Requirements and Framework for Systems Beyond IMT-2000", + "venue": "Journal of Communications and Networks", + "volume": "Vol. 7, No. 2, pp. 171~177, June 2005", + "publishedAt": "2005-06" + }, + { + "category": "intl-journal-conf", + "title": "Transport Layer Mobility Support Utilizing Link Signal Strength Information", + "venue": "IEICE Transactions on Communications", + "volume": "Vol. E87-B, No. 9, pp. 2548~2556, September 2004", + "publishedAt": "2004-09" + }, { "category": "domestic-journal-conf", "title": "mSCTP를 이용한 종단간 이동성 지원 방안", @@ -902,6 +812,13 @@ export const publications: Publication[] = [ "publishedAt": "2004-08", "kci": true }, + { + "category": "intl-journal-conf", + "title": "Limiting the Length of BET for Tunnel-Based IP Fast Handover", + "venue": "IEICE Transactions on Fundamentals of Electronics Communications and Computer Sciences", + "volume": "Vol. E87-A, No. 6, pp. 1527~1530, June 2004", + "publishedAt": "2004-06" + }, { "category": "domestic-journal-conf", "title": "SCTP의 멀티호밍 특성에 대한 성능 평가", @@ -910,6 +827,13 @@ export const publications: Publication[] = [ "publishedAt": "2004-04", "kci": true }, + { + "category": "intl-journal-conf", + "title": "mSCTP for Soft Handover in Transport Layer", + "venue": "IEEE Communications Letters", + "volume": "Vol. 8, No. 3, pp. 189~191, March 2004", + "publishedAt": "2004-03" + }, { "category": "domestic-journal-conf", "title": "ECTP 멀티캐스트 전송 프로토콜 : 구현 및 성능분석", @@ -923,32 +847,28 @@ export const publications: Publication[] = [ "title": "3G-WLAN 연동기술 동향", "venue": "ETRI 전자통신동향분석", "volume": "제 18권 4호 (통권 82호), pp. 1 - 10, 2003년 8월", - "publishedAt": "2003-08", - "kci": false + "publishedAt": "2003-08" }, { "category": "domestic-journal-conf", "title": "SCTP 표준기술 분석 및 전망", "venue": "ETRI 전자통신동향분석", "volume": "제 18권 3호 (통권 81호), pp. 11 - 21, 2003년 6월", - "publishedAt": "2003-06", - "kci": false + "publishedAt": "2003-06" }, { "category": "domestic-journal-conf", "title": "인터넷 멀티캐스트 현황 및 전망", "venue": "주간기술동향", "volume": "제 1090호, pp. 1 - 15, 2003년 4월", - "publishedAt": "2003-04", - "kci": false + "publishedAt": "2003-04" }, { "category": "domestic-journal-conf", "title": "IP 멀티캐스트 시장 전망에 대한 고찰", "venue": "한국통신학회지(정보통신)", "volume": "제 19권 제 10호, pp. 1577 ~ 1590, 2002년 10월", - "publishedAt": "2002-10", - "kci": false + "publishedAt": "2002-10" }, { "category": "domestic-journal-conf", @@ -963,16 +883,14 @@ export const publications: Publication[] = [ "title": "인터넷방송을 위한 멀티캐스트 기술 동향", "venue": "ETRI 전자통신동향분석", "volume": "제 17권 3호 (통권 75호), 2002년 6월", - "publishedAt": "2002-06", - "kci": false + "publishedAt": "2002-06" }, { "category": "domestic-journal-conf", "title": "종단간 서비스품질 표준기술 동향", "venue": "주간기술동향", "volume": "제 1049호, 2002년 6월", - "publishedAt": "2002-06", - "kci": false + "publishedAt": "2002-06" }, { "category": "domestic-journal-conf", @@ -987,8 +905,14 @@ export const publications: Publication[] = [ "title": "종단간 멀티캐스트 전송을 위한 ECTP 표준 프로토콜", "venue": "주간기술동향", "volume": "제 1016호, 2001년 10월", - "publishedAt": "2001-10", - "kci": false + "publishedAt": "2001-10" + }, + { + "category": "intl-journal-conf", + "title": "Configuration of ACK Trees for Multicast Transport Protocols", + "venue": "ETRI Journal", + "volume": "Vol. 23, No. 3, pp. 111~120, September 2001", + "publishedAt": "2001-09" }, { "category": "domestic-journal-conf", @@ -1006,45 +930,68 @@ export const publications: Publication[] = [ "publishedAt": "2001-05", "kci": true }, + { + "category": "intl-journal-conf", + "title": "Assignment of ADM Rings and DCS Mesh in Telecommunication Networks", + "venue": "Journal of the O.R. Society", + "volume": "Vol. 52, No. 4, pp. 440~448, April 2001", + "publishedAt": "2001-04" + }, + { + "category": "intl-journal-conf", + "title": "Multicast Delivery Based on Unicast and Subnet Multicast", + "venue": "IEEE Communications Letters", + "volume": "Vol. 5, No. 4, pp. 181~183, April 2001", + "publishedAt": "2001-04" + }, { "category": "domestic-journal-conf", "title": "인터넷 멀티캐스트 신기술 동향", "venue": "ETRI 전자통신동향분석", "volume": "제 16권 제 2호, pp. 1-9, 2001년 4월", - "publishedAt": "2001-04", - "kci": false + "publishedAt": "2001-04" + }, + { + "category": "intl-journal-conf", + "title": "Dynamic Bandwidth Allocation Scheme for Multiple Real-time VBR Videos over ATM Networks", + "venue": "Telecommunications Systems", + "volume": "Vol. 15, pp.359~380, December 2000", + "publishedAt": "2000-12" }, { "category": "domestic-journal-conf", "title": "차세대 인터넷 멀티캐스팅 기술 동향", "venue": "한국통신학회지(정보통신)", "volume": "제 17권 제 9호, pp. 168-187, 2000년 9월", - "publishedAt": "2000-09", - "kci": false + "publishedAt": "2000-09" }, { "category": "domestic-journal-conf", "title": "인터넷 멀티캐스트 라우팅 기술 동향", "venue": "ETRI 전자통신동향분석", "volume": "제 15권 제 3호, pp. 28-41, 2000년 6월", - "publishedAt": "2000-06", - "kci": false + "publishedAt": "2000-06" }, { "category": "domestic-journal-conf", "title": "멀티캐스트 신뢰전송 기술 및 표준화 동향", "venue": "주간기술동향", "volume": "제 944호, pp. 16 - 33, 2000년 5월", - "publishedAt": "2000-05", - "kci": false + "publishedAt": "2000-05" }, { "category": "domestic-journal-conf", "title": "인터넷 전화 시장 및 표준화 동향", "venue": "ETRI 전자통신동향분석", "volume": "제15권 2호, pp. 1 - 14, 2000년 4월호", - "publishedAt": "2000-04", - "kci": false + "publishedAt": "2000-04" + }, + { + "category": "intl-journal-conf", + "title": "Minimizing Cost and Delay in Shared Multicast Trees", + "venue": "ETRI Journal", + "volume": "Vol. 22, No. 1, pp.30~37, March 2000", + "publishedAt": "2000-03" }, { "category": "domestic-journal-conf", @@ -1067,24 +1014,14 @@ export const publications: Publication[] = [ "title": "ATM 기반 MPLS 공중망에서의 IP 전송기술", "venue": "한국통신학회지(정보통신)", "volume": "Vol. 16, No. 12, pp. 47 - 58, 1999년 12월", - "publishedAt": "1999-12", - "kci": false + "publishedAt": "1999-12" }, { "category": "domestic-journal-conf", "title": "공중 ATM 망에서의 IP 전송기술 동향", "venue": "주간기술동향", "volume": "924호, pp. 15 - 29, 1999년 12월", - "publishedAt": "1999-12", - "kci": false - }, - { - "category": "domestic-journal-conf", - "title": "인터넷 멀티캐스트 라우팅 프로토콜 분석", - "venue": "ETRI 전자통신동향분석", - "volume": "99년 10월호, pp. 99 - 110, 1999.", - "publishedAt": "1999", - "kci": false + "publishedAt": "1999-12" }, { "category": "domestic-journal-conf", @@ -1094,13 +1031,40 @@ export const publications: Publication[] = [ "publishedAt": "1999-09", "kci": true }, + { + "category": "intl-journal-conf", + "title": "Non-Core Based Shared Tree Architecture for IP Multicasting", + "venue": "Electronics Letters", + "volume": "Vol. 35, No. 11, pp. 872~873, May 1999", + "publishedAt": "1999-05" + }, + { + "category": "domestic-journal-conf", + "title": "인터넷 멀티캐스트 라우팅 프로토콜 분석", + "venue": "ETRI 전자통신동향분석", + "volume": "99년 10월호, pp. 99 - 110, 1999.", + "publishedAt": "1999" + }, { "category": "domestic-journal-conf", "title": "멀티캐스트 전송을 위한 오류제어 기법의 분류", "venue": "ETRI 전자통신동향분석", "volume": "99년 6월호, pp. 76 - 84, 1999.", - "publishedAt": "1999", - "kci": false + "publishedAt": "1999" + }, + { + "category": "intl-journal-conf", + "title": "A Design of the Self-Healing ATM Networks Based on the Backup Virtual Path", + "venue": "Computers and Operations Research", + "volume": "Vol. 25, No. 7/8, pp. 595~609, July 1998", + "publishedAt": "1998-07" + }, + { + "category": "intl-journal-conf", + "title": "A Design of the Minimum Cost Ring-Chain Network with Dual-Homing Survivability: Tabu Search Approach", + "venue": "Computers and Operations Research", + "volume": "Vol. 24, No. 9, pp. 883~897, September 1997", + "publishedAt": "1997-09" }, { "category": "domestic-journal-conf", @@ -1110,6 +1074,13 @@ export const publications: Publication[] = [ "publishedAt": "1997-09", "kci": true }, + { + "category": "intl-journal-conf", + "title": "A Tabu Search for the Survivable Fiber Optic Communication Network Design", + "venue": "Computers and Industrial Engineering", + "volume": "Vol. 28, Issue 4, pp. 689~700, October 1995", + "publishedAt": "1995-10" + }, { "category": "domestic-journal-conf", "title": "Heuristic Aspects of the Branch and Bound Procedure For a Job Scheduling Problem", diff --git a/refer_landing_page/content/standards.ts b/refer_landing_page/content/standards.ts index 5ce1d70..4d53dbf 100644 --- a/refer_landing_page/content/standards.ts +++ b/refer_landing_page/content/standards.ts @@ -1,4 +1,4 @@ -// AUTO-GENERATED by scripts/extract/generate_all.py — DO NOT EDIT BY HAND +// AUTO-GENERATED by backend/cmd/export-content — DO NOT EDIT BY HAND import { StandardsBody } from "./types"; export const standardsBodies: StandardsBody[] = [ diff --git a/refer_landing_page/content/types.ts b/refer_landing_page/content/types.ts index 6c8bbd1..94a35d1 100644 --- a/refer_landing_page/content/types.ts +++ b/refer_landing_page/content/types.ts @@ -31,6 +31,7 @@ export interface Publication { publishedAt: string; // ISO 8601 YYYY-MM or YYYY-MM-DD kci?: boolean; doi?: string; + isHighlight?: boolean; } export interface Patent {