광운대학교 학생회 홈페이지의 백엔드 API 서버입니다.
- 공지사항 관리: CRUD API
- 파일 업로드: 이미지 및 문서 파일 업로드
- 회의록 관리: 회의록 CRUD API
- 승부예측 관리: 학생 승부예측 제출 및 관리 API
- 스포츠 대회 관리: 경기 일정, 순위, 학과/종목 정보 API
- 시스템 검증: 시스템 상태 확인
backend-main/
├── api/
│ ├── index.js # 메인 서버 및 라우터 연결
│ ├── announcements.js # 공지사항 API
│ ├── upload.js # 파일 업로드 API
│ ├── minutes.js # 회의록 API
│ ├── predictions.js # 승부예측 API
│ ├── sports2025.js # 스포츠 대회 API
│ └── verifySystem.js # 시스템 검증 API
├── lib/
│ └── supabaseClient.js # Supabase 클라이언트
├── validators/
│ ├── announcement.js # 공지사항 유효성 검사
│ ├── minutes.js # 회의록 유효성 검사
│ └── prediction.js # 승부예측 유효성 검사
├── supabase_setup.sql # 데이터베이스 테이블 생성 스크립트
├── PREDICTIONS_API_README.md # 승부예측 API 상세 문서
├── SPORTS2025_API_SPEC.md # 스포츠 대회 API 명세서
└── package.json
- README.md: 프로젝트 전체 개요 및 기본 사용법
- PREDICTIONS_API_README.md: 승부예측 API 상세 명세 및 사용법
- Node.js + Express.js
- Supabase (PostgreSQL + Storage)
- Multer (파일 업로드)
- CORS (Cross-Origin Resource Sharing)
- Query Parameters:
page,limit,q(제목 검색) - 응답:
{ page, limit, total, items }
- 응답: 단일 공지사항 정보
- Body:
{ title, content, image, published_at }
- Body:
file(multipart/form-data) - 응답:
{ url, path } - 설명: 기존 STORAGE_BUCKET 사용 또는 MINUTES_BUCKET 환경변수로 별도 버킷 지정 가능
- Query Parameters:
page(기본값: 1, 최소값: 1)limit(기본값: 10, 범위: 1~50)q(제목 검색, 부분 일치)
- 응답:
{ page, limit, total, items } - 정렬: 최신
datedesc,created_atdesc
응답 예시:
{
"page": 1,
"limit": 10,
"total": 25,
"items": [
{
"id": 1,
"title": "2025학년도 제1차 학생대표자회의",
"file_url": "https://.../storage/v1/object/public/minutes/2025-03-02.pdf",
"date": "2025-03-02",
"created_at": "2025-03-02T10:00:00Z"
}
]
}- 응답: 단일 회의록 정보
- 404: 회의록을 찾을 수 없을 때
응답 예시:
{
"id": 1,
"title": "2025학년도 제1차 학생대표자회의",
"file_url": "https://.../storage/v1/object/public/minutes/2025-03-02.pdf",
"date": "2025-03-02",
"created_at": "2025-03-02T10:00:00Z"
}- Body:
{ title, file_url, date } - 유효성 검사:
title: non-emptyfile_url: non-empty URL stringdate: YYYY-MM-DD 형식 유효성
- 응답: 생성된 회의록 정보
요청 예시:
{
"title": "2025학년도 제1차 학생대표자회의",
"file_url": "https://.../storage/v1/object/public/minutes/2025-03-02.pdf",
"date": "2025-03-02"
}- Body:
{ name, student_id, phone, first_place, second_place, third_place } - 유효성 검사:
name: 필수, 공백 제거 후 1자 이상student_id: 필수, 정확히 10자리 숫자, 중복 제출 불가phone: 필수, 전화번호 형식 (010-XXXX-XXXX)first_place,second_place,third_place: 필수, 모두 다른 학과
- 응답: 생성된 승부예측 정보
요청 예시:
{
"name": "홍길동",
"student_id": "2024200072",
"phone": "010-1234-5678",
"first_place": "컴퓨터공학과",
"second_place": "전자공학과",
"third_place": "기계공학과"
}- Headers:
X-API-Key(관리자 API 키) - Query Parameters:
page,limit - 응답: 승부예측 목록 (페이지네이션)
- Headers:
X-API-Key(관리자 API 키) - 응답: 단일 승부예측 정보
상세 문서: PREDICTIONS_API_README.md
SUPABASE_URL=your_supabase_url
SUPABASE_ANON_KEY=your_supabase_anon_key
STORAGE_BUCKET=announcements
ADMIN_API_KEY=your_secure_admin_api_key # 승부예측 관리자 API 키MINUTES_BUCKET=minutes # 회의록 전용 파일 버킷 (선택사항)
PORT=3000 # 서버 포트 (기본값: 3000)# 의존성 설치
npm install
# 개발 서버 실행
npm start
# 또는 직접 실행
node api/index.jsCREATE TABLE minutes (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
file_url TEXT NOT NULL,
date DATE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);CREATE TABLE predictions (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
student_id TEXT NOT NULL UNIQUE,
phone TEXT NOT NULL,
first_place TEXT NOT NULL,
second_place TEXT NOT NULL,
third_place TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);전체 스키마: supabase_setup.sql 파일 참조
허용된 도메인:
https://kwucouncil.github.iohttp://localhost:8080https://www.kwu-studentcouncil52.com
- 승부예측 조회: 관리자 API 키 인증 필요 (
X-API-Key헤더) - API 키 관리: 환경변수로 관리, 정기적 변경 권장
- 데이터 보호: 개인정보는 관리자만 조회 가능
모든 API는 에러 발생 시 다음 형식으로 응답:
{
"message": "에러 메시지",
"error": "상세 에러 정보"
}- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request