Skip to content

AriAri-Dong/ariari-backend

Repository files navigation

🎯 AriAri (아리아리)

동아리 운영을 위한 종합 플랫폼

동아리 모집부터 관리까지, 하나의 플랫폼에서


Project Status License Last Updated


📖 목차

  1. 프로젝트 개요
  2. 배경 및 문제 정의
  3. 솔루션
  4. 핵심 기능
  5. 기술 스택
  6. 아키텍처
  7. 주요 도메인 모델
  8. 프로젝트 구조
  9. 주요 기능 상세
  10. 권한 체계
  11. 보안
  12. 데이터 정책
  13. 시작하기
  14. 프로젝트 회고

📖 프로젝트 개요

AriAri는 동아리 생태계의 구조적 문제를 해결하기 위해 기획된 동아리 전용 통합 플랫폼입니다.

2024년 1월부터 12월까지 약 1년간 실제 유저 유입을 목표로 개발 및 운영되었으며, 동아리 모집부터 운영 관리까지 전 과정을 디지털화하여 효율성을 극대화하는 것을 목표로 했습니다.

🎯 핵심 가치

  1. 체계적인 모집 프로세스

    • 구직 사이트와 유사한 지원서 시스템
    • 전형 단계별 관리 (서류 심사 → 면접 → 최종 합격)
    • 자동화된 합격/불합격 통지
  2. 효율적인 동아리 운영

    • 멤버 및 권한 관리
    • 일정 관리 & 출석 체크
    • 회계 내역 투명 관리
  3. 커뮤니티 활성화

    • 활동 후기 및 합격 후기 공유
    • Q&A 및 FAQ를 통한 정보 교류
    • 댓글 및 좋아요 기능
  4. 데이터 기반 의사결정

    • 모집공고 조회수 및 스크랩 수 통계
    • 지원자 현황 및 전형별 데이터 분석
    • 동아리 활동 및 회계 내역 추적

🔍 배경 및 문제 정의

현재 동아리 생태계의 문제점

  1. 정보 파편화

    • 동아리 홍보가 여전히 오프라인 포스터, 에브리타임 게시글에 의존
    • 정보가 분산되어 있어 통합적인 탐색이 어려움
    • 검색 및 필터링 기능 부재
    • 대학교 교내 동아리 탐색이 어려움
  2. 비효율적인 지원 프로세스

    • 카카오톡 채널, 구글 폼 등 파편화된 도구 사용
    • 지원서 양식 표준화 부재
    • 전형 진행 상황 추적 어려움
  3. 동아리 관리 도구 부재

    • 멤버 관리, 일정 관리, 회계 관리가 각각 다른 도구로 진행
    • 권한 및 직책 관리 체계 미흡
    • 데이터 기반 의사결정 불가능
  4. 체계적인 매칭 시스템 부족

    • 지원자와 동아리를 연결하는 플랫폼 부재
    • 합격 후기, 활동 후기 등 정보 공유 채널 미흡

💡 솔루션

AriAri는 다음과 같은 방식으로 문제를 해결합니다:

For 지원자 (일반 회원)

🔍 체계적인 동아리 탐색

  • 다차원 필터링: 활동분야(8개), 활동지역(10개), 활동대상(3개), 소속(2개)
  • 정렬 옵션: 최신순, 조회수순, 스크랩순, 마감일순
  • 학교 연동: 학교 등록 시 교내 동아리 필터링 가능
  • 즐겨찾기 & 스크랩: 관심 동아리 북마크

📝 맞춤형 지원 시스템

  • 커스터마이징된 지원서: 각 동아리가 설정한 질문에 응답
  • 임시 저장: 작성 중인 지원서를 안전하게 보관
  • 지원 현황 추적: 서류 심사 → 면접 → 최종 합격까지 실시간 확인
  • 지원서 보관: 마감일로부터 6개월간 보관

💬 커뮤니티 참여

  • 활동 후기 열람: 동아리의 실제 활동 내용 확인
  • 합격 후기 열람: 선배들의 합격 팁 및 경험담
  • Q&A: 동아리에 궁금한 점 질문

For 운영진 (동아리 관리자)

👥 멤버 관리

  • 직책 체계: 관리자(1명), 스탭(다수), 일반 멤버(다수)
  • 활동 상태 관리: 활동중, 활동 종료, 탈퇴
  • 권한 위임: 관리자 권한을 다른 멤버에게 위임
  • 초대 시스템: 아리아리 초대링크 or 동아리 초대링크

📢 모집 관리

  • 모집공고 작성: 포스터 업로드, 카테고리 설정, 마감일 지정
  • 지원서 양식 커스터마이징: 드롭다운, 텍스트 입력 등 자유롭게 설정
  • 지원자 관리: 서류/면접 단계별로 지원자 관리
  • 합격/불합격 처리: 개별 or 일괄 처리
  • 모집공고 승인 시스템: 관리자 승인 후 게시 (최대 2일 소요)

📅 편의 기능

  • 일정 관리: 일정 등록 및 출석 체크 링크 생성
  • 회계 관리: 입출금 내역 기록, 잔고 자동 계산
  • 공지사항: 고정 공지 최대 3개, 일반 공지 최대 10개
  • FAQ 관리: 자주 묻는 질문 등록
  • Q&A 답변: 일반 멤버의 질문에 답변

🚀 핵심 기능

1️⃣ 모집 공고 시스템

필터 & 정렬

  • 활동분야: 문화예술, 봉사, 학술, 창업, 취업, 체육, 친목, 기타
  • 활동지역: 지역제한없음, 수도권, 충청/대전, 경남/부산/울산, 경북/대구, 전남/광주, 강원, 전북, 제주, 해외
  • 활동대상: 대학생, 대학원생, 직장인/일반인
  • 소속: 교내, 연합

모집공고 카드

  • 카테고리 뱃지 (소속, 활동분야, 지역, 대상)
  • 모집 포스터 이미지
  • 동아리 이름 & 모집공고 제목
  • D-Day 표시 & 스크랩 수

모집공고 상세페이지

  • 동아리 프로필 & 즐겨찾기
  • 모집 포스터 & 내용
  • 카테고리 요약
  • 지난 모집공고 목록
  • 합격 후기 목록
  • 지원 방식 선택 (아리아리 내 지원 or 타 서비스 지원)

2️⃣ 지원서 시스템

지원서 작성

  • 동아리가 설정한 커스텀 질문에 응답
  • 드롭다운, 텍스트 입력, 파일 첨부 등 다양한 형식 지원
  • 임시 저장 기능
  • 필수 동의사항 (정보 제공 동의, 서비스 이용제한 동의)

지원서 관리

  • 전체/작성중/전형 진행중/최종발표 완료 탭으로 분류
  • 전형 상태별 지원서 확인
    • 작성중
    • 서류 심사중
    • 서류 합격/불합격
    • 최종 합격/불합격
  • 작성중 & 최종발표 완료된 지원서만 삭제 가능

3️⃣ 동아리 관리 시스템

멤버 관리

  • 직책별 권한 차등 부여
  • 활동 상태 변경 (활동중, 활동 종료, 탈퇴)
  • 회원 초대 (아리아리 초대링크 or 동아리 초대링크)
  • 관리자 권한 위임 (동아리당 관리자 1명만 존재)

모집 관리

  • 모집공고 작성/수정/삭제
  • 지원서 양식 커스터마이징
  • 지원자 관리 (서류/면접 단계별)
  • 합격/불합격 처리 (개별 or 일괄)
  • 활성화 가능한 공고는 오직 1개

일정 관리

  • 일정 등록 (제목, 날짜, 시간, 참석 대상)
  • 출석 체크 링크 생성 (향후 QR 코드 시스템 검토)
  • 출석 현황 확인

회계 관리

  • 입출금 내역 기록
  • 잔고 자동 계산
  • 동아리 회원 모두 확인 가능 (투명성)

4️⃣ 커뮤니티 시스템

공지사항

  • 고정 공지 최대 3개
  • 일반 공지 최대 10개 (초과 시 자동 삭제)
  • 비회원에게는 미노출

활동 내역

  • 텍스트 & 사진 (최대 10개) 업로드
  • 공개 범위 설정 (전체공개 or 동아리원)
  • 댓글 & 답글 기능
  • 좋아요 기능
  • 차단 사용자 댓글 상호 미노출

Q&A

  • 일반 멤버: 질문 작성
  • 관리자/스탭: 답변 가능
  • 작성 후 수정/삭제 불가
  • 신고 기능 제공

FAQ

  • 관리자만 작성
  • 태그 기능 (카테고리 분류)
  • 작성 후 수정/삭제 불가

5️⃣ 회원 시스템

소셜 로그인

  • 카카오 OAuth 2.0 연동
  • JWT 기반 인증 (Access Token + Refresh Token)

프로필 관리

  • 프로필 사진 (동물 캐릭터 중 선택)
  • 닉네임 (최대 8자)
  • 학교 등록 (웹메일 인증, 등록 후 수정 불가)

알림 시스템

  • 전형 상태 변경 알림
  • 동아리 공지사항 알림
  • 댓글/답글 알림

🛠 기술 스택

Backend

Spring Boot 3.3.4
├─ Java 17
├─ Spring Security + JWT
├─ Spring Data JPA + QueryDSL
├─ MySQL/MariaDB
├─ Redis
├─ AWS S3
├─ Sentry
└─ MyBatis

주요 의존성 및 역할

의존성 버전 역할
Spring Boot 3.3.4 애플리케이션 프레임워크
Java 17 프로그래밍 언어
Spring Security - 인증/인가 처리
JJWT 0.12.3 JWT 토큰 생성 및 검증
Spring Data JPA - ORM 및 데이터 접근
QueryDSL 5.0.0 타입 안전한 동적 쿼리
MySQL Connector - MySQL 데이터베이스 드라이버
MariaDB 3.3.2 MariaDB 데이터베이스 드라이버
Redis 3.3.4 캐싱 및 토큰 블랙리스트
AWS S3 SDK 1.12.767 이미지 스토리지
SpringDoc OpenAPI 2.2.0 API 문서 자동화 (Swagger)
Sentry 8.11.1 에러 트래킹 및 모니터링
MyBatis 3.0.3 SQL 매핑 프레임워크
Thymeleaf - 이메일 템플릿 엔진
Lombok - 보일러플레이트 코드 제거

Frontend

Next.js 14
├─ React 18
├─ TypeScript
├─ Tailwind CSS
├─ Zustand (클라이언트 상태관리)
├─ React Query (서버 상태관리)
└─ Axios (HTTP 클라이언트)

주요 의존성 및 역할

의존성 버전 역할
Next.js 14.2.21 React 프레임워크 (App Router)
React 18 UI 라이브러리
TypeScript 5 타입 안전성
Tailwind CSS 3.4.1 유틸리티 우선 CSS 프레임워크
Zustand 5.0.0-rc.2 경량 상태 관리
@tanstack/react-query 5.66.11 서버 상태 관리 및 캐싱
Axios 1.8.2 HTTP 클라이언트
Framer Motion 12.6.3 애니메이션 라이브러리
React Icons 5.3.0 아이콘 라이브러리
React Datepicker 7.6.0 날짜 선택 UI
React Markdown 10.1.0 마크다운 렌더링
Day.js 1.11.13 날짜/시간 유틸리티
Lottie React 2.4.1 애니메이션 렌더링
Swiper 11.2.6 터치 슬라이더

Infrastructure & DevOps

AWS EC2 (Always Free Tier)
├─ Nginx (Reverse Proxy)
├─ Docker (컨테이너화)
├─ GitHub Actions (CI/CD)
└─ Sentry (에러 모니터링)

🏗 아키텍처

시스템 아키텍처

┌─────────────────┐
│   Client        │
│  (Next.js 14)   │
└────────┬────────┘
         │ HTTPS
         ▼
┌─────────────────┐
│   Nginx         │
│ (Reverse Proxy) │
└────────┬────────┘
         │
         ▼
┌─────────────────┐      ┌─────────────┐
│  Spring Boot    │──────│   Redis     │
│    Backend      │      │  (Cache)    │
└────────┬────────┘      └─────────────┘
         │
         ├─────────────────┬─────────────────┐
         ▼                 ▼                 ▼
┌─────────────┐   ┌─────────────┐   ┌─────────────┐
│   MySQL/    │   │   AWS S3    │   │   Sentry    │
│  MariaDB    │   │  (Images)   │   │ (Monitoring)│
└─────────────┘   └─────────────┘   └─────────────┘

인증 흐름 (OAuth 2.0 + JWT)

┌────────┐        ┌────────┐        ┌────────┐        ┌────────┐
│ Client │        │ Server │        │ Kakao  │        │ Redis  │
└───┬────┘        └───┬────┘        └───┬────┘        └───┬────┘
    │ 1. 카카오 로그인  │                │                │
    │─────────────────>│                │                │
    │                  │ 2. 인가 코드 요청│                │
    │                  │───────────────>│                │
    │                  │ 3. 인가 코드    │                │
    │                  │<───────────────│                │
    │                  │ 4. Access Token │                │
    │                  │───────────────>│                │
    │                  │ 5. 사용자 정보   │                │
    │                  │<───────────────│                │
    │                  │ 6. JWT 생성     │                │
    │ 7. JWT 토큰      │                │                │
    │<─────────────────│                │                │
    │ 8. API 요청 + JWT│                │                │
    │─────────────────>│                │                │
    │                  │ 9. 토큰 검증    │                │
    │                  │────────────────────────────────>│
    │                  │10. 검증 결과    │                │
    │                  │<────────────────────────────────│
    │11. API 응답      │                │                │
    │<─────────────────│                │                │

데이터베이스 설계 철학

  • 정규화: 3NF 준수
  • 논리적 삭제: 중요 데이터는 deleted_at 컬럼을 통한 논리적 삭제
  • 감사 추적: BaseEntity를 통한 생성일/수정일 자동 관리
  • 관계 매핑: JPA를 통한 엔티티 간 관계 관리
  • 쿼리 최적화: QueryDSL을 활용한 동적 쿼리 및 N+1 문제 해결

📊 주요 도메인 모델

핵심 엔티티

1. User (회원)

  • 기본 정보: 이메일, 닉네임, 프로필 이미지
  • 학교 정보: 학교 ID (FK), 학교 이름
  • 소셜 로그인: 카카오 OAuth ID
  • 상태: 활성화 여부, 탈퇴 여부

2. Club (동아리)

  • 기본 정보: 동아리 이름, 프로필 이미지, 소개
  • 카테고리: 활동분야, 활동지역, 활동대상, 소속
  • 통계: 조회수, 스크랩 수
  • 상태: 활성화 여부, 폐쇄 여부

3. Recruitment (모집공고)

  • 동아리 ID (FK)
  • 모집 정보: 제목, 내용, 포스터 이미지
  • 카테고리: 활동분야, 활동지역, 활동대상, 소속
  • 기간: 시작일, 마감일
  • 지원 방식: 아리아리 내 지원 or 외부 링크
  • 상태: 승인 대기, 승인 완료, 게시 중, 마감, 종료
  • 통계: 조회수, 스크랩 수

4. Apply (지원서)

  • 회원 ID (FK), 모집공고 ID (FK)
  • 지원일시
  • 전형 상태: 작성중, 서류 심사중, 서류 합격/불합격, 최종 합격/불합격
  • 지원 답변: ApplyAnswer 엔티티와 1:N 관계

5. ApplyForm (지원서 양식)

  • 동아리 ID (FK)
  • 질문 목록: ApplyQuestion 엔티티와 1:N 관계
  • 질문 유형: 드롭다운, 텍스트 입력, 파일 첨부

6. ClubMember (동아리 멤버)

  • 동아리 ID (FK), 회원 ID (FK)
  • 직책: 관리자, 스탭, 일반 멤버
  • 활동 상태: 활동중, 활동 종료, 탈퇴
  • 가입일, 탈퇴일

7. ClubActivity (활동 내역)

  • 동아리 ID (FK)
  • 작성자 ID (FK)
  • 내용, 이미지 목록
  • 공개 범위: 전체공개, 동아리원
  • 댓글 목록: ClubActivityComment 엔티티와 1:N 관계
  • 좋아요 수

8. ClubReview (활동 후기)

  • 동아리 ID (FK)
  • 작성자 ID (FK)
  • 제목, 내용
  • 태그 목록
  • 좋아요 수

9. PassReview (합격 후기)

  • 동아리 ID (FK), 모집공고 ID (FK)
  • 작성자 ID (FK)
  • 제목, 내용
  • 합격 기수
  • 좋아요 수

10. FinancialRecord (회계 내역)

  • 동아리 ID (FK)
  • 날짜, 내용
  • 입금액, 출금액, 잔고

엔티티 관계도 (ERD 개요)

User ──< ClubMember >── Club
  │                       │
  │                       ├──< Recruitment ──< Apply
  │                       │
  │                       ├──< ClubActivity
  │                       │
  │                       ├──< ClubNotice
  │                       │
  │                       ├──< ClubQuestion (Q&A)
  │                       │
  │                       ├──< ClubFaq
  │                       │
  │                       └──< FinancialRecord

Recruitment ──< RecruitmentBookmark >── User
Recruitment ──< PassReview
Club ──< ClubBookmark >── User
Club ──< ClubReview

📁 프로젝트 구조

Backend (Spring Boot)

ariari-backend/
├── src/main/java/com/ariari/ariari/
│   ├── AriariApplication.java              # 메인 애플리케이션
│   │
│   └── commons/                             # 공통 모듈
│       ├── auth/                            # 인증/인가
│       │   ├── AuthController.java         # 인증 API
│       │   ├── AuthService.java            # 인증 비즈니스 로직
│       │   ├── oauth/                       # OAuth 2.0
│       │   │   ├── KakaoAuthManager.java   # 카카오 OAuth
│       │   │   └── OAuthSignUpManager.java # OAuth 회원가입
│       │   └── springsecurity/              # Spring Security 설정
│       │       ├── JwtAuthenticationFilter.java
│       │       ├── JwtAuthenticationProvider.java
│       │       └── CustomUserDetailsService.java
│       │
│       ├── entity/                          # JPA 엔티티
│       │   ├── User.java
│       │   ├── Club.java
│       │   ├── Recruitment.java
│       │   ├── Apply.java
│       │   ├── ApplyForm.java
│       │   ├── ApplyQuestion.java
│       │   ├── ApplyAnswer.java
│       │   ├── ClubMember.java
│       │   ├── ClubActivity.java
│       │   ├── ClubActivityComment.java
│       │   ├── ClubNotice.java
│       │   ├── ClubQuestion.java
│       │   ├── ClubAnswer.java
│       │   ├── ClubFaq.java
│       │   ├── ClubReview.java
│       │   ├── PassReview.java
│       │   ├── FinancialRecord.java
│       │   ├── Attendance.java
│       │   ├── ClubEvent.java
│       │   └── ...
│       │
│       ├── commonentity/                    # 공통 엔티티
│       │   ├── BaseEntity.java             # 생성일/수정일
│       │   ├── LogicalDeleteEntity.java    # 논리적 삭제
│       │   ├── image/                       # 이미지 엔티티
│       │   └── report/                      # 신고 엔티티
│       │
│       ├── exception/                       # 예외 처리
│       │   ├── CustomException.java
│       │   ├── ExceptionControllerAdvice.java
│       │   └── exceptions/
│       │       ├── NotFoundEntityException.java
│       │       ├── NotAuthenticatedException.java
│       │       ├── DuplicateDataCreateException.java
│       │       └── ...
│       │
│       └── manager/                         # 비즈니스 로직 매니저
│           ├── ClubManager.java
│           ├── RecruitmentManager.java
│           ├── ApplyManager.java
│           └── ...
│
├── src/main/resources/
│   ├── application.yml                      # 애플리케이션 설정
│   └── templates/                           # Thymeleaf 템플릿
│
├── build.gradle                             # Gradle 빌드 설정
└── Dockerfile                               # Docker 이미지 빌드

Frontend (Next.js)

ariari-frontend/
├── app/                                     # Next.js App Router
│   ├── (application)/                       # 지원서 관련 페이지
│   │   ├── application/
│   │   │   ├── [id]/
│   │   │   │   └── page.tsx                # 지원서 작성 페이지
│   │   │   └── page.tsx                    # 지원 현황 페이지
│   │
│   ├── (auth)/                              # 인증 관련 페이지
│   │   ├── login/
│   │   │   └── page.tsx                    # 로그인 페이지
│   │   └── signup/
│   │       └── page.tsx                    # 회원가입 페이지
│   │
│   ├── (club)/                              # 동아리 관련 페이지
│   │   └── club/
│   │       ├── [id]/
│   │       │   ├── page.tsx                # 동아리 상세 페이지
│   │       │   ├── manage/                 # 동아리 관리 페이지
│   │       │   │   ├── member/             # 멤버 관리
│   │       │   │   ├── recruitment/        # 모집 관리
│   │       │   │   ├── applicant/          # 지원자 관리
│   │       │   │   ├── schedule/           # 일정 관리
│   │       │   │   ├── finance/            # 회계 관리
│   │       │   │   └── community/          # 커뮤니티 관리
│   │       │   └── ...
│   │       └── create/
│   │           └── page.tsx                # 동아리 생성 페이지
│   │
│   ├── (community)/                         # 커뮤니티 페이지
│   │   └── community/
│   │       ├── review/                     # 활동 후기
│   │       └── pass-review/                # 합격 후기
│   │
│   ├── (recruitment)/                       # 모집공고 페이지
│   │   └── recruitment/
│   │       ├── page.tsx                    # 모집공고 목록
│   │       └── [id]/
│   │           └── page.tsx                # 모집공고 상세
│   │
│   ├── (user)/                              # 사용자 페이지
│   │   └── user/
│   │       ├── profile/                    # 프로필 수정
│   │       ├── bookmark/                   # 즐겨찾기
│   │       └── alarm/                      # 알림
│   │
│   ├── components/                          # 재사용 컴포넌트
│   │   ├── common/                         # 공통 컴포넌트
│   │   │   ├── Button.tsx
│   │   │   ├── Input.tsx
│   │   │   ├── Modal.tsx
│   │   │   ├── Card.tsx
│   │   │   └── ...
│   │   ├── layout/                         # 레이아웃 컴포넌트
│   │   │   ├── Header.tsx
│   │   │   ├── Footer.tsx
│   │   │   └── Sidebar.tsx
│   │   └── domain/                         # 도메인별 컴포넌트
│   │       ├── recruitment/
│   │       ├── club/
│   │       └── ...
│   │
│   ├── hooks/                               # 커스텀 훅
│   │   ├── useAuth.ts
│   │   ├── useRecruitment.ts
│   │   ├── useClub.ts
│   │   └── ...
│   │
│   ├── stores/                              # Zustand 스토어
│   │   ├── authStore.ts
│   │   ├── userStore.ts
│   │   └── ...
│   │
│   ├── types/                               # TypeScript 타입 정의
│   │   ├── user.ts
│   │   ├── club.ts
│   │   ├── recruitment.ts
│   │   └── ...
│   │
│   ├── utils/                               # 유틸리티 함수
│   │   ├── api.ts                          # API 클라이언트
│   │   ├── format.ts                       # 포맷 유틸리티
│   │   ├── validation.ts                   # 유효성 검사
│   │   └── ...
│   │
│   ├── constants/                           # 상수 정의
│   │   ├── categories.ts                   # 카테고리 상수
│   │   └── ...
│   │
│   ├── layout.tsx                           # 루트 레이아웃
│   ├── page.tsx                             # 홈페이지
│   └── globals.css                          # 글로벌 스타일
│
├── public/                                  # 정적 파일
│   ├── images/
│   └── icons/
│
├── package.json                             # 의존성 관리
├── next.config.mjs                          # Next.js 설정
├── tailwind.config.ts                       # Tailwind 설정
└── tsconfig.json                            # TypeScript 설정

🎨 주요 기능 상세

1. 모집 공고 탐색

필터링 시스템

  • 활동분야 (8개): 문화예술, 봉사, 학술, 창업, 취업, 체육, 친목, 기타
  • 활동지역 (10개): 지역제한없음, 수도권, 충청/대전, 경남/부산/울산, 경북/대구, 전남/광주, 강원, 전북, 제주, 해외
  • 활동대상 (3개): 대학생, 대학원생, 직장인/일반인
  • 소속 (2개): 교내, 연합
  • 학교 미등록 사용자가 "교내" 선택 시 → "회원 정보 수정-학교 등록이 필요합니다." 안내

정렬 옵션

  • 최신 순 (기본값)
  • 조회수 순
  • 스크랩 순
  • 오래된 순
  • 마감일 순

모집공고 카드 UI

┌──────────────────────────────┐
│ [교내] [학술]                │
│ [수도권] [대학생]            │
│                              │
│    [모집 포스터 이미지]       │
│                              │
│  동아리 이름                 │
│  모집공고 제목               │
│  D-7                    ♡ 24 │
└──────────────────────────────┘

2. 지원서 작성

양식 구조

동아리 관리자가 설정한 커스텀 양식 제공

입력 항목 예시

Q1. 성별을 선택해주세요.
   [드롭다운: 남자 / 여자]

Q2. 지원 동기를 입력해주세요.
   [텍스트 입력창]
   (0 / 500자)

Q3. 포트폴리오 (선택)
   [파일 첨부] or [링크 입력]

필수 동의 사항

  • 정보 제공 동의: 지원서는 마감일로부터 6개월간 보관 후 영구삭제
  • 서비스 이용제한 동의: 거짓 정보 기재 시 서비스 이용 제한

제출 프로세스

  1. 제출 버튼 클릭
  2. 확인 팝업: "제출 후에는 수정이 불가합니다."
  3. 완료 팝업: "제출이 완료되었습니다."
    • [동아리 지원으로 이동]
    • [모집공고 계속 보기]

3. 동아리 관리

모집공고 생명주기

작성 → 관리자 승인 대기 (최대 2일) → 승인 → 게시 → 마감/종료

제약사항

  • 활성화 가능한 공고는 오직 1개
  • 승인된 공고는 수정 불가
  • 수정 필요 시: 기존 공고 종료 후 재작성

지원자 관리 전형 단계

지원서 제출 → 서류 심사 → 면접 → 최종 합격/불합격

관리 기능

  • 지원서 상세 열람
  • 개별 처리 (합격/불합격)
  • 면접 상태 변경 시 자동 알림
  • 일괄 처리 기능 제공

활동 내역 UI

┌──────────────────────────────┐
│ 활동 내용 텍스트...           │
│                              │
│ [사진1] [사진2] ... (최대10개)│
│                              │
│ 공개 범위: [전체공개/동아리원] │
│                              │
│ [댓글 보기 ▼]                │
│ └─ 멤버A: 댓글 내용          │
│    └─ 답글                  │
│                              │
│ [수정] [삭제]                │
└──────────────────────────────┘

특징

  • 댓글 기본 접힌 상태
  • 차단 사용자 댓글은 서로 미노출
  • 사용자 이름 = 동아리 내 이름

4. 회계 관리

┌──────────────────────────────┐
│ 날짜       내용    입금  출금  잔고 │
├──────────────────────────────┤
│ 2024.11.15 회비  +50,000    50,000│
│ 2024.11.20 MT비용  -30,000  20,000│
└──────────────────────────────┘
  • 동아리 회원 모두 확인 가능
  • 단순 입출금 기록
  • 잔고 자동 계산

5. 일정 관리 & 출석 체크

┌──────────────────────────────┐
│ 2024.11.25 (월) 19:00        │
│ 정기 모임                     │
│                              │
│ 참석 대상: 전체 멤버           │
│                              │
│ [출석 체크 링크 생성]          │
│ [출석 현황 보기]              │
└──────────────────────────────┘

출석 관리

  • 현재: 링크 시스템
  • 향후: QR 코드 시스템 검토

🔐 권한 체계

동아리 멤버 권한

권한 관리자 스탭 일반 멤버
멤버 관리
활동 상태 변경
직책 변경
모집공고 작성
지원자 관리
공지사항 작성
활동 내역 작성
Q&A 답변
FAQ 작성
동아리 폐쇄

활동 상태

  • 활동중: 현재 활동 중인 멤버
  • 활동 종료: 활동은 끝났으나 멤버로 유지
  • 탈퇴: 동아리에서 완전히 나감

권한 위임

  • 관리자가 일반 멤버에게 관리자 권한 위임
  • 위임 시 기존 관리자는 일반 멤버로 전환
  • 동아리당 관리자는 1명만 존재

회원 초대

2가지 방식

  1. 아리아리 초대링크: 서비스 가입 유도
  2. 동아리 초대링크: 링크로 가입 시 자동 멤버 등록

🔒 보안

인증 & 인가

  • OAuth 2.0: 카카오 소셜 로그인
  • JWT: Access Token (유효기간 2시간) + Refresh Token (유효기간 2주)
  • Spring Security: 엔드포인트별 권한 검증
  • Redis 토큰 블랙리스트: 로그아웃된 토큰 무효화

데이터 보호

  • HTTPS: 모든 통신 암호화
  • AES 암호화: 민감한 데이터 암호화 저장
  • SQL Injection 방지: JPA 및 PreparedStatement 사용
  • XSS 방지: React의 자동 이스케이핑 + 서버 검증
  • CSRF 방지: SameSite Cookie + CSRF 토큰

파일 업로드 보안

  • 파일 타입 검증: 화이트리스트 방식
  • 파일 크기 제한: 최대 10MB
  • S3 저장: 서버 파일 시스템 분리
  • 이미지 메타데이터 제거: EXIF 정보 삭제

API 보안

  • Rate Limiting: 과도한 요청 차단
  • 입력 검증: Bean Validation 및 커스텀 검증
  • 에러 메시지 마스킹: 민감한 정보 노출 방지

📊 데이터 정책

지원서 보관 정책

  • 마감일로부터 6개월 보관 후 영구 삭제
  • 삭제 전 이메일 알림 발송
  • 물리적 삭제로 복구 불가능

탈퇴 회원 데이터 처리

  • 즉시 삭제: 개인정보 (이메일, 전화번호, 학교 정보 등)
  • 유지: 활동 후기, 합격 후기, 댓글 (신고로 삭제 가능)
  • 익명화: 작성자 이름을 "탈퇴한 회원"으로 변경

신고 정책

신고 가능 대상

  • 활동 후기
  • 합격 후기
  • Q&A
  • 댓글/답글

처리 프로세스

  1. 신고 접수
  2. 관리자 검토
  3. 논리 삭제 처리 (deleted_at 설정)
  4. 3개월 후 물리 삭제

🚀 시작하기

Prerequisites

소프트웨어 요구사항:

  • Java: 17 이상
  • Node.js: 18 이상
  • MySQL/MariaDB: 8.0 이상
  • Redis: 6.0 이상
  • Docker: (선택사항) 컨테이너 배포 시

환경 변수 설정

Backend (.env 또는 application.yml)

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/ariari
    username: {your_db_username}
    password: {your_db_password}

  data:
    redis:
      host: localhost
      port: 6379

  security:
    oauth2:
      client:
        registration:
          kakao:
            client-id: {your_kakao_client_id}
            client-secret: {your_kakao_client_secret}
            redirect-uri: {your_redirect_uri}

jwt:
  secret: {your_jwt_secret_key}
  access-token-expiration: 7200000   # 2시간
  refresh-token-expiration: 1209600000  # 2주

aws:
  s3:
    bucket: {your_s3_bucket_name}
    region: {your_s3_region}
    access-key: {your_aws_access_key}
    secret-key: {your_aws_secret_key}

sentry:
  dsn: {your_sentry_dsn}

Frontend (.env.local)

NEXT_PUBLIC_API_URL=http://localhost:8080/api
NEXT_PUBLIC_KAKAO_CLIENT_ID={your_kakao_client_id}

📈 모니터링 & 운영

에러 트래킹

  • Sentry: 실시간 에러 모니터링 및 알림
  • 에러 로그 자동 수집 및 분류
  • 스택 트레이스 및 사용자 컨텍스트 저장

로그 관리

  • Spring Boot Logback: 구조화된 로그 기록
  • 로그 레벨: ERROR, WARN, INFO, DEBUG
  • 로그 파일 로테이션 (일별)

성능 모니터링

  • API 응답 시간 추적
  • 데이터베이스 쿼리 성능 분석
  • Redis 캐시 히트율 모니터링

🛠 개발 챌린지 & 해결 방법

1. N+1 쿼리 문제

문제: JPA에서 연관관계 조회 시 N+1 쿼리 발생 해결:

  • QueryDSL을 활용한 Fetch Join
  • @EntityGraph 어노테이션 사용
  • DTO 프로젝션으로 필요한 데이터만 조회
  • 일부 복잡한 로직은 Mybatis로 배치 처리

2. 대용량 이미지 업로드

문제: 서버 메모리 부족 및 업로드 시간 지연 해결:

  • AWS S3 직접 업로드 (Presigned URL)
  • 이미지 압축 및 리사이징 (Sharp.js)
  • 멀티파트 업로드로 대용량 파일 처리

3. 동시성 이슈

문제: 모집공고 지원 시 동시 요청으로 중복 지원 발생 해결:

  • 데이터베이스 유니크 제약조건 설정
  • Redis 분산 락 (Redisson)
  • 낙관적 락 (@Version) 활용

4. 인증 토큰 관리

문제: Access Token 만료 시 사용자 경험 저하 해결:

  • Refresh Token 자동 갱신 로직
  • Axios Interceptor로 토큰 만료 시 자동 재발급
  • 무한 루프 방지 로직

5. 검색 성능 최적화

문제: 모집공고 필터링 시 느린 쿼리 속도 해결:

  • 데이터베이스 인덱스 최적화
  • QueryDSL 동적 쿼리로 불필요한 조인 제거
  • Redis 캐싱으로 자주 조회되는 데이터 저장

📝 프로젝트 회고

이 프로젝트는 실제 유저 유입을 목적으로 진행한 사이드 프로젝트였지만, 여러 현실적인 요건으로 2025년 12월을 마지막으로 종료하였습니다.

🎯 프로젝트 목표

  1. 실제 서비스 런칭: AWS에 인프라를 구축하여 유저 유입 후 계속 서비스 고도화
  2. 유저 유입: SNS 홍보 및 대학 커뮤니티 마케팅
  3. 지속적인 운영: 피드백 수집 및 기능 개선

✅ 달성한 것들

  • 풀스택 개발 경험: Spring Boot + Next.js로 전체 서비스 구현
  • 실제 배포 및 운영: AWS 인프라 구축, CI/CD 파이프라인 구성
  • 사용자 중심 기획: 실제 동아리 운영진 인터뷰 기반 기능 설계
  • 복잡한 도메인 모델링: 30개 이상의 엔티티 설계 및 관계 매핑
  • 보안 및 인증: OAuth 2.0, JWT, Spring Security 구현
  • 성능 최적화: 쿼리 최적화, 캐싱, 이미지 최적화
  • 팀 협업: Git Flow, 코드 리뷰, 이슈 트래킹
  • 마케팅 시도: 인스타그램 공식 계정을 통한 소액의 광고 주기적으로 진행, 인스타그램 총동연/동아리 계정에 DM으로 접촉하여 유저 유입시도, 유튜브 가이드 영상 업로드

📚 배운 점

기술적 측면

  • Spring Boot 3.x: 최신 Spring 프레임워크 활용
  • Next.js 14 App Router: 서버 컴포넌트 및 클라이언트 컴포넌트 분리
  • TypeScript: 타입 안전성으로 런타임 에러 감소
  • JPA & QueryDSL: ORM 활용 및 동적 쿼리 최적화
  • Redis: 캐싱 및 세션 관리
  • AWS 인프라: EC2, S3, RDS 구축 및 관리
  • Docker: 컨테이너 기반 배포
  • Sentry: 에러 트래킹 및 모니터링

프로젝트 관리

  • 요구사항 분석: 사용자 인터뷰를 통한 실제 니즈 파악
  • 문서화의 중요성: 기획서, API 문서, README의 필요성
  • 일정 관리: 스코프 조정 및 우선순위 설정
  • 기술 부채 관리: 리팩토링과 새 기능 개발의 균형

🚧 아쉬운 점

  • 마케팅 부족: 개발에만 집중하고 홍보 전략 미흡 => 현실적인 여건 파악 부족(정말 가볍고 아이디어가 좋은 서비스가 아니라면, 초기 스타트업 사업 시도처럼 적극적으로 진행해줄 팀원이 필요하였음.)
  • 초기 MVP 설정: MVP로 최대한 줄였으나 그래도 너무 복잡하여 개발이 늘어짐
  • 테스트 커버리지: 개발에 급급하여 단위 테스트 및 통합 테스트 부족

👥 팀 구성

이 프로젝트는 AriAri 기획팀 및 개발팀에 의해 제작되었습니다.

  • 기획: 사용자 리서치, 기능 정의, 와이어프레임
  • 백엔드: Spring Boot, JPA, Redis, AWS 인프라
  • 프론트엔드: Next.js, TypeScript, Tailwind CSS
  • 디자인: UI/UX 디자인, 프로토타이핑

📄 라이선스

이 프로젝트는 비공개 프로젝트입니다.


📞 문의

프로젝트에 대한 문의사항이 있으시면 이슈를 등록해주세요.


Made with ❤️ by AriAri Team

2024.01 - 2025.12

"동아리 생태계의 디지털 전환을 꿈꾸며"

About

✨ 아리아리, 모든 동아리를 한 눈에! ✨

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages