Skip to content

hanjm-github/beomseo.in

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

90 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

beomseo.in MIT 로고

범서고등학교 17대 학생회 정보기술부 범서고등학교 정보기술부 인스타그램

🏫 beomseo.in

범서고등학교 학생 커뮤니티 플랫폼
"지혜로운 눈으로 꿈을 이루고, 따뜻한 가슴으로 인류에 봉사하자"

Flask 3.1 React 19 Vite 7 MariaDB Redis FastAPI GPL-3.0


📋 목차


🌟 프로젝트 소개

beomseo.in은 범서고등학교 17대 학생회 정보기술부에서 기획·개발한 학생 커뮤니티 웹 플랫폼입니다.

학생들이 학교 생활에서 필요한 정보를 한곳에서 쉽게 찾고, 서로 소통할 수 있는 공간을 만들기 위해 시작되었습니다. 학교/학생회 공지와 예산 공개 게시판 확인부터 자유 게시판, 동아리 모집, 학생 청원, 설문조사, 실시간 투표, 분실물 게시판, 교내 중고거래, 수학여행 반별 미션 게시판, 그리고 학교 생활 정보 허브 안의 스포츠리그 문자중계·팀별 라인업·개인별 순위까지 — 범서고 학생이라면 누구나 참여할 수 있습니다.

개발 철학

  1. 첫째도 개발의 편리함, 둘째도 학생들의 편리함 🛠️
  2. 복잡하게 만들지 않는다. 단순하지만 완성도 있게 ✅

🌲 학교 상징

상징 설명
🎯 교훈 지혜로운 눈으로 꿈을 이루고 따뜻한 가슴으로 인류에 봉사하자
🎯 목표 지적 능력과 고운 인성이 조화로운 인간으로 성장시킨다
🌲 교목 곰솔나무 — 끈기와 장수, 장대함을 상징
🌺 교화 모란 — 부귀와 번영, 행복을 상징

✨ 주요 기능

📢 공지·소통

  • 학교/학생회 공지 — 카테고리별 CRUD, 댓글, 반응
  • 예산 공개 게시판 — 회계연도(3월~다음 해 2월) 기준 월별 예산 공개, 댓글/반응/첨부 재사용
  • 자유 게시판 — 북마크, 승인 시스템
  • 인성 가치 PICK! — 역량/실천 다짐 공유, 승인 기반 운영, 반응/댓글
  • 학생 청원 — 투표 + 학생회 답변

🗳️ 참여·활동

  • 설문 교환 — 크레딧 기반 설문 시스템
  • 실시간 투표 — 즉석 투표 생성 & 참여
  • 동아리 모집 — 학년별 모집 공고 + 승인
  • 수학여행 미션 보드 — 반별 비밀번호 확인, 익명/로그인 글 작성, 점수판 운영

🔍 생활 편의

  • 분실물 게시판 — 사진 첨부, 댓글
  • 곰솔 마켓 — 교내 중고거래 플랫폼
  • 과목 변경 매칭 — 과목 교환 요청 & 상태 관리
  • 학교 생활 정보 허브 — 시간표 다운로드, 학사 캘린더, 급식 조회/평점/PWA 알림, 스포츠리그 문자중계/라인업/개인 순위

🔒 보안·인프라

  • Cookie JWT + CSRF — HttpOnly 쿠키 인증
  • IP 기반 가입 제한 — 교내 네트워크 가입 제어
  • 3중 업로드 검증 — 확장자 + MIME + 시그니처

공지 라우팅 메모

  • /notices/*는 학교/학생회 공지용 NoticeCenterPage와 예산 공개용 BudgetBoardPage로 분기됩니다.
  • /notices/budget 진입 시 백엔드 GET /api/notices/budget/settings 응답의 기본 연/월로 리다이렉트됩니다.
  • 예산 공개는 BUDGET_BOARD_START_YEAR ~ BUDGET_BOARD_END_YEAR 범위의 활성 회계연도만 노출합니다.

🛠️ 기술 스택

백엔드

구분 기술 비고
언어 Python
프레임워크 Flask 3.1 앱 팩토리 패턴 (메인 API)
FastAPI 스포츠리그 + 수학여행 전용 비동기 서버
ASGI 서버 Uvicorn FastAPI 런타임
ORM Flask-SQLAlchemy / async SQLAlchemy Flask·FastAPI 공유 DB
DB MariaDB (PyMySQL / aiomysql)
캐시 Redis + Flask-Caching 장애 시 NullCache fallback
인증 Flask-JWT-Extended / PyJWT Cookie + CSRF 이중 보호
비밀번호 bcrypt
레이트리밋 Flask-Limiter 사용자ID/IP 기반
푸시 알림 firebase-admin 급식 Web Push sender 스크립트

프론트엔드

구분 기술 비고
라이브러리 React 19
번들러 Vite 7
라우팅 React Router DOM 7 lazy loading
HTTP Axios withCredentials 쿠키 인증
차트 Recharts
폼 빌더 react-form-builder2 설문 빌더
아이콘 Lucide React
XSS 방어 DOMPurify
푸시/알림 Firebase Web Push 설치형 PWA 급식 알림
분석 Cloudflare Zaraz + GA4 민감 키 자동 필터링

🏗️ 시스템 아키텍처

flowchart TB
    subgraph Client["🖥️ 클라이언트"]
        Browser["웹 브라우저"]
    end

    subgraph Frontend["⚛️ 프론트엔드 (React / Vite)"]
        SPA["SPA (React Router)"]
        API_Layer["API Layer (Axios)"]
        Security["Security (sanitize / policy)"]
        Analytics["Analytics (Zaraz)"]
    end

    subgraph Backend["🐍 백엔드 (Flask)"]
        App["App Factory"]
        Auth["인증 (JWT Cookie)"]
        Routes["블루프린트 ×11"]
        Models["SQLAlchemy Models"]
        Utils["Utils (보안/캐시/업로드)"]
    end

    subgraph FastAPIServer["⚡ 실시간/이벤트/급식 서버 (FastAPI)"]
        FastApp["FastAPI App"]
        AsyncRoutes["비동기 라우트"]
        SSE["SSE 스트리밍"]
    end

    subgraph Infra["🗄️ 인프라"]
        MariaDB[("MariaDB")]
        Redis[("Redis")]
        Uploads["📁 uploads/"]
    end

    Browser --> SPA
    SPA --> API_Layer
    API_Layer -->|"HTTPS + Cookie JWT + CSRF"| App
    API_Layer -->|"HTTPS + Cookie JWT + CSRF"| FastApp
    App --> Auth
    App --> Routes
    Routes --> Models
    FastApp --> AsyncRoutes
    AsyncRoutes --> SSE
    Models --> MariaDB
    AsyncRoutes --> MariaDB
    Utils --> Redis
    Utils --> Uploads
    SSE --> Redis
    SPA --> Security
    SPA --> Analytics
Loading

런타임 메모

  • 프론트 앱은 ThemeProvider → NetworkStatusProvider → PwaInstallProvider → AuthProvider 순서로 전역 상태를 감쌉니다.
  • 인증/일반 API 요청에서 transport 계열 네트워크 실패가 발생하면 app:network-request-failed 이벤트를 통해 OfflineGate 전체 화면 오버레이가 열립니다.
  • PWA 설치 UI는 beforeinstallprompt가 지원되는 브라우저와 iOS Safari 수동 설치 경로를 분리해서 처리합니다.
  • FastAPI 서버는 스포츠리그와 수학여행 게시판뿐 아니라 급식 조회, 급식 평점, 급식 알림 구독 API도 함께 제공합니다.
  • 급식 조회 요청은 MySQL에 저장된 데이터만 읽고, 실제 NEIS 호출은 동기화 스크립트에서만 수행합니다.

요청 라이프사이클

[일반 요청]
사용자 클릭 → React Component → Axios (withCredentials) → Flask 라우터
    → 미들웨어(JWT 검증, CSRF, Rate Limit)
    → 블루프린트 핸들러
    → SQLAlchemy ORM → MariaDB
    → JSON 응답 → React 렌더링

[FastAPI 요청]
사용자 클릭 → React Component → fastapiApi / sportsApi (withCredentials) → FastAPI 라우터
    → JWT 쿠키 검증 (PyJWT)
    → 비동기 핸들러
    → async SQLAlchemy → MariaDB
    → JSON / SSE 스트림 응답 → React 렌더링

📂 프로젝트 구조

beomseo.in/
├── 📄 README.md              ← 지금 읽고 있는 이 문서
├── 📄 LICENSE                 ← GNU GPL-3.0
├── 📄 TODO.md                 ← 개발 로드맵 & 아이디어
├── 📄 .gitignore
│
├── 🐍 backend/                ← Flask API 서버
│   ├── app.py                 # 앱 팩토리 + 미들웨어
│   ├── config.py              # 환경별 설정 (보안/캐시/레이트리밋)
│   ├── requirements.txt
│   ├── requirements_fastapi.txt  # FastAPI 전용 의존성
│   ├── .env.example
│   ├── routes/                # 11개 블루프린트 (기능별 API)
│   │   ├── auth.py            #   인증/회원
│   │   ├── notices.py         #   공지 + 예산 공개 설정/CRUD
│   │   ├── free.py            #   자유게시판
│   │   ├── value_pick.py      #   인성 가치 PICK!
│   │   ├── club_recruit.py    #   동아리 모집
│   │   ├── subject_changes.py #   과목변경
│   │   ├── petitions.py       #   학생 청원
│   │   ├── surveys.py         #   설문 교환
│   │   ├── votes.py           #   실시간 투표
│   │   ├── lost_found.py      #   분실물
│   │   └── gomsol_market.py   #   곰솔 마켓
│   ├── fastapi_app/           # FastAPI 실시간/급식 전용 서버
│   │   ├── main.py            #   앱 팩토리, CORS, 보안 헤더
│   │   ├── config.py          #   Pydantic Settings (동일 .env 공유)
│   │   ├── database.py        #   async SQLAlchemy (aiomysql)
│   │   ├── models.py          #   순수 SQLAlchemy ORM 모델
│   │   ├── schemas.py         #   Pydantic V2 요청/응답 스키마
│   │   ├── deps.py            #   JWT 쿠키 인증 + 역할 검사
│   │   ├── utils.py           #   sanitize, SSE 포맷터
│   │   ├── routes/            #   FastAPI 라우터
│   │   │   ├── sports_league.py  # 문자중계/라인업 CRUD + SSE 스트림 엔드포인트
│   │   │   ├── field_trip.py     # 수학여행 반 게시판/점수판/업로드 엔드포인트
│   │   │   └── meals.py          # 급식 조회/평점/알림 구독 엔드포인트
│   │   └── services/          #   비동기 도메인 로직
│   │       ├── sports_league.py       # 스냅샷, 이벤트 CRUD
│   │       ├── sports_league_players.py  # 선수 라인업/개인기록 CRUD
│   │       ├── sports_league_realtime.py  # asyncio pub/sub
│   │       ├── sports_league_seed.py  # 시드 데이터
│   │       ├── field_trip.py          # 수학여행 게시판/점수판/업로드 로직
│   │       ├── meals.py               # 급식 동기화/조회/평점 로직
│   │       └── meal_notifications.py  # 급식 알림 구독/발송 로직
│   ├── models/                # SQLAlchemy 모델
│   ├── services/              # 도메인 서비스/실시간 보조 로직
│   ├── scripts/               # 운영용 부트스트랩 스크립트
│   │   ├── bootstrap_field_trip.py    # 수학여행 기본 반/비밀번호 시드
│   │   ├── sync_school_meals.py       # NEIS 급식 동기화
│   │   ├── send_school_meal_notifications.py # Firebase 급식 알림 발송
│   │   └── migrate_notice_budget_board.py # 기존 notices 스키마에 예산 공개 컬럼/인덱스 추가
│   ├── utils/                 # 보안·캐시·업로드 유틸
│   ├── uploads/               # 파일 업로드 저장소
│   └── docs/                  # 백엔드 문서
│
└── ⚛️ frontend/               ← React SPA
    ├── index.html
    ├── package.json
    ├── vite.config.js
    ├── .env.example
    ├── src/
    │   ├── App.jsx            # 라우터 + Provider
    │   ├── main.jsx           # 엔트리포인트
    │   ├── api/               # Axios 기반 API 모듈 + FastAPI/급식 알림 클라이언트
    │   ├── components/        # 재사용 컴포넌트 (70개)
    │   ├── features/          # 기능 단위 hook/data/utils 묶음
    │   ├── pages/             # 페이지 컴포넌트 (45개)
    │   ├── context/           # Auth/Theme/NetworkStatus/PWA 컨텍스트
    │   ├── pwa/               # 설치/푸시 알림/오프라인 유틸
    │   ├── security/          # URL/HTML/CSV sanitize
    │   ├── analytics/         # Zaraz 이벤트 래퍼
    │   ├── layout/            # AppLayout
    │   ├── config/            # 환경 설정
    │   ├── styles/            # 글로벌 스타일
    │   └── utils/             # 유틸리티
    └── docs/                  # 프론트엔드 문서

🚀 빠른 시작

사전 요구사항

도구 최소 버전 용도
Python 3.10+ 백엔드 런타임
Node.js 20+ 프론트엔드 런타임
npm 10+ 패키지 관리
MariaDB 10.6+ 데이터베이스
Redis 7.0+ 캐시 & 레이트리밋 (선택사항)

1단계: 저장소 클론

git clone https://github.com/hanjm-github/beomseo.in.git
cd beomseo.in

2단계: 백엔드 설정

cd backend

# 가상환경 생성 & 활성화
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate

# 의존성 설치
pip install -r requirements.txt

# 환경 변수 준비
copy .env.example .env    # Windows
cp .env.example .env      # macOS / Linux
# .env 파일을 열어 DB 접속 정보, JWT_SECRET_KEY,
# BUDGET_BOARD_START_YEAR / BUDGET_BOARD_END_YEAR 등을 수정합니다

# 기존 notices 테이블을 이미 사용 중인 환경이라면 예산 공개 확장 스키마를 먼저 반영합니다
python scripts/migrate_notice_budget_board.py

# 서버 실행
python app.py

💡 기본 개발 서버: http://127.0.0.1:5000

FastAPI 서버 (선택)

cd backend
pip install -r requirements_fastapi.txt
python -m uvicorn fastapi_app.main:app --host 127.0.0.1 --port 8000 --reload

💡 FastAPI 서버: http://127.0.0.1:8000 (Swagger: /docs) 스포츠리그 문자중계와 수학여행 게시판 API를 함께 제공합니다.

3단계: 프론트엔드 설정

cd frontend

# 의존성 설치
npm install

# 환경 변수 준비
copy .env.example .env    # Windows
cp .env.example .env      # macOS / Linux

# 개발 서버 실행
npm run dev

💡 기본 개발 서버: http://localhost:5173

4단계: 동작 확인

# 백엔드 헬스체크
curl http://127.0.0.1:5000/api/health

# 프론트엔드
# 브라우저에서 http://localhost:5173 접속

프로덕션 빌드 (프론트엔드)

cd frontend
npm run build    # dist/ 디렉터리에 빌드 파일 생성
npm run preview  # 빌드된 결과물 미리보기

📖 문서 인덱스

이 프로젝트에는 백엔드와 프론트엔드 각각의 상세 문서가 포함되어 있습니다.

백엔드 문서

문서 설명
backend/README.md 백엔드 종합 가이드
backend/docs/backend_api.md API 레퍼런스
backend/docs/backend_architecture.md 아키텍처 문서
backend/docs/fastapi_deployment.md FastAPI 스포츠리그/수학여행/급식 서버 배포 가이드
backend/docs/school_meals.md 급식 조회 + PWA 급식 알림 문서

프론트엔드 문서

문서 설명
frontend/README.md 프론트엔드 종합 가이드
frontend/docs/frontend-code-map.md 코드 맵
frontend/docs/frontend-architecture.md 아키텍처 문서
frontend/docs/frontend-api-reference.md API 참조
frontend/docs/analytics-tracking.md 분석 트래킹 스펙
frontend/docs/team-checklist.md 팀 체크리스트

프로젝트 전체

문서 설명
TODO.md 개발 로드맵 & 아이디어
LICENSE GNU GPL-3.0 라이선스

📜 라이선스

이 프로젝트는 GNU General Public License v3.0 하에 배포됩니다.

beomseo.in
Copyright (C) 2026  범서고등학교 17대 학생회 정보기술부

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

🌲 곰솔나무처럼 끈기 있게, 모란처럼 아름답게 🌺
범서고등학교 17대 학생회 정보기술부가 만들었습니다.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors