AriAri는 동아리 생태계의 구조적 문제를 해결하기 위해 기획된 동아리 전용 통합 플랫폼입니다.
2024년 1월부터 12월까지 약 1년간 실제 유저 유입을 목표로 개발 및 운영되었으며, 동아리 모집부터 운영 관리까지 전 과정을 디지털화하여 효율성을 극대화하는 것을 목표로 했습니다.
-
체계적인 모집 프로세스
- 구직 사이트와 유사한 지원서 시스템
- 전형 단계별 관리 (서류 심사 → 면접 → 최종 합격)
- 자동화된 합격/불합격 통지
-
효율적인 동아리 운영
- 멤버 및 권한 관리
- 일정 관리 & 출석 체크
- 회계 내역 투명 관리
-
커뮤니티 활성화
- 활동 후기 및 합격 후기 공유
- Q&A 및 FAQ를 통한 정보 교류
- 댓글 및 좋아요 기능
-
데이터 기반 의사결정
- 모집공고 조회수 및 스크랩 수 통계
- 지원자 현황 및 전형별 데이터 분석
- 동아리 활동 및 회계 내역 추적
-
정보 파편화
- 동아리 홍보가 여전히 오프라인 포스터, 에브리타임 게시글에 의존
- 정보가 분산되어 있어 통합적인 탐색이 어려움
- 검색 및 필터링 기능 부재
- 대학교 교내 동아리 탐색이 어려움
-
비효율적인 지원 프로세스
- 카카오톡 채널, 구글 폼 등 파편화된 도구 사용
- 지원서 양식 표준화 부재
- 전형 진행 상황 추적 어려움
-
동아리 관리 도구 부재
- 멤버 관리, 일정 관리, 회계 관리가 각각 다른 도구로 진행
- 권한 및 직책 관리 체계 미흡
- 데이터 기반 의사결정 불가능
-
체계적인 매칭 시스템 부족
- 지원자와 동아리를 연결하는 플랫폼 부재
- 합격 후기, 활동 후기 등 정보 공유 채널 미흡
AriAri는 다음과 같은 방식으로 문제를 해결합니다:
- 다차원 필터링: 활동분야(8개), 활동지역(10개), 활동대상(3개), 소속(2개)
- 정렬 옵션: 최신순, 조회수순, 스크랩순, 마감일순
- 학교 연동: 학교 등록 시 교내 동아리 필터링 가능
- 즐겨찾기 & 스크랩: 관심 동아리 북마크
- 커스터마이징된 지원서: 각 동아리가 설정한 질문에 응답
- 임시 저장: 작성 중인 지원서를 안전하게 보관
- 지원 현황 추적: 서류 심사 → 면접 → 최종 합격까지 실시간 확인
- 지원서 보관: 마감일로부터 6개월간 보관
- 활동 후기 열람: 동아리의 실제 활동 내용 확인
- 합격 후기 열람: 선배들의 합격 팁 및 경험담
- Q&A: 동아리에 궁금한 점 질문
- 직책 체계: 관리자(1명), 스탭(다수), 일반 멤버(다수)
- 활동 상태 관리: 활동중, 활동 종료, 탈퇴
- 권한 위임: 관리자 권한을 다른 멤버에게 위임
- 초대 시스템: 아리아리 초대링크 or 동아리 초대링크
- 모집공고 작성: 포스터 업로드, 카테고리 설정, 마감일 지정
- 지원서 양식 커스터마이징: 드롭다운, 텍스트 입력 등 자유롭게 설정
- 지원자 관리: 서류/면접 단계별로 지원자 관리
- 합격/불합격 처리: 개별 or 일괄 처리
- 모집공고 승인 시스템: 관리자 승인 후 게시 (최대 2일 소요)
- 일정 관리: 일정 등록 및 출석 체크 링크 생성
- 회계 관리: 입출금 내역 기록, 잔고 자동 계산
- 공지사항: 고정 공지 최대 3개, 일반 공지 최대 10개
- FAQ 관리: 자주 묻는 질문 등록
- Q&A 답변: 일반 멤버의 질문에 답변
- 활동분야: 문화예술, 봉사, 학술, 창업, 취업, 체육, 친목, 기타
- 활동지역: 지역제한없음, 수도권, 충청/대전, 경남/부산/울산, 경북/대구, 전남/광주, 강원, 전북, 제주, 해외
- 활동대상: 대학생, 대학원생, 직장인/일반인
- 소속: 교내, 연합
- 카테고리 뱃지 (소속, 활동분야, 지역, 대상)
- 모집 포스터 이미지
- 동아리 이름 & 모집공고 제목
- D-Day 표시 & 스크랩 수
- 동아리 프로필 & 즐겨찾기
- 모집 포스터 & 내용
- 카테고리 요약
- 지난 모집공고 목록
- 합격 후기 목록
- 지원 방식 선택 (아리아리 내 지원 or 타 서비스 지원)
- 동아리가 설정한 커스텀 질문에 응답
- 드롭다운, 텍스트 입력, 파일 첨부 등 다양한 형식 지원
- 임시 저장 기능
- 필수 동의사항 (정보 제공 동의, 서비스 이용제한 동의)
- 전체/작성중/전형 진행중/최종발표 완료 탭으로 분류
- 전형 상태별 지원서 확인
- 작성중
- 서류 심사중
- 서류 합격/불합격
- 최종 합격/불합격
- 작성중 & 최종발표 완료된 지원서만 삭제 가능
- 직책별 권한 차등 부여
- 활동 상태 변경 (활동중, 활동 종료, 탈퇴)
- 회원 초대 (아리아리 초대링크 or 동아리 초대링크)
- 관리자 권한 위임 (동아리당 관리자 1명만 존재)
- 모집공고 작성/수정/삭제
- 지원서 양식 커스터마이징
- 지원자 관리 (서류/면접 단계별)
- 합격/불합격 처리 (개별 or 일괄)
- 활성화 가능한 공고는 오직 1개
- 일정 등록 (제목, 날짜, 시간, 참석 대상)
- 출석 체크 링크 생성 (향후 QR 코드 시스템 검토)
- 출석 현황 확인
- 입출금 내역 기록
- 잔고 자동 계산
- 동아리 회원 모두 확인 가능 (투명성)
- 고정 공지 최대 3개
- 일반 공지 최대 10개 (초과 시 자동 삭제)
- 비회원에게는 미노출
- 텍스트 & 사진 (최대 10개) 업로드
- 공개 범위 설정 (전체공개 or 동아리원)
- 댓글 & 답글 기능
- 좋아요 기능
- 차단 사용자 댓글 상호 미노출
- 일반 멤버: 질문 작성
- 관리자/스탭: 답변 가능
- 작성 후 수정/삭제 불가
- 신고 기능 제공
- 관리자만 작성
- 태그 기능 (카테고리 분류)
- 작성 후 수정/삭제 불가
- 카카오 OAuth 2.0 연동
- JWT 기반 인증 (Access Token + Refresh Token)
- 프로필 사진 (동물 캐릭터 중 선택)
- 닉네임 (최대 8자)
- 학교 등록 (웹메일 인증, 등록 후 수정 불가)
- 전형 상태 변경 알림
- 동아리 공지사항 알림
- 댓글/답글 알림
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 | - | 보일러플레이트 코드 제거 |
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 | 터치 슬라이더 |
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)│
└─────────────┘ └─────────────┘ └─────────────┘
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│ 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 문제 해결
- 기본 정보: 이메일, 닉네임, 프로필 이미지
- 학교 정보: 학교 ID (FK), 학교 이름
- 소셜 로그인: 카카오 OAuth ID
- 상태: 활성화 여부, 탈퇴 여부
- 기본 정보: 동아리 이름, 프로필 이미지, 소개
- 카테고리: 활동분야, 활동지역, 활동대상, 소속
- 통계: 조회수, 스크랩 수
- 상태: 활성화 여부, 폐쇄 여부
- 동아리 ID (FK)
- 모집 정보: 제목, 내용, 포스터 이미지
- 카테고리: 활동분야, 활동지역, 활동대상, 소속
- 기간: 시작일, 마감일
- 지원 방식: 아리아리 내 지원 or 외부 링크
- 상태: 승인 대기, 승인 완료, 게시 중, 마감, 종료
- 통계: 조회수, 스크랩 수
- 회원 ID (FK), 모집공고 ID (FK)
- 지원일시
- 전형 상태: 작성중, 서류 심사중, 서류 합격/불합격, 최종 합격/불합격
- 지원 답변:
ApplyAnswer엔티티와 1:N 관계
- 동아리 ID (FK)
- 질문 목록:
ApplyQuestion엔티티와 1:N 관계 - 질문 유형: 드롭다운, 텍스트 입력, 파일 첨부
- 동아리 ID (FK), 회원 ID (FK)
- 직책: 관리자, 스탭, 일반 멤버
- 활동 상태: 활동중, 활동 종료, 탈퇴
- 가입일, 탈퇴일
- 동아리 ID (FK)
- 작성자 ID (FK)
- 내용, 이미지 목록
- 공개 범위: 전체공개, 동아리원
- 댓글 목록:
ClubActivityComment엔티티와 1:N 관계 - 좋아요 수
- 동아리 ID (FK)
- 작성자 ID (FK)
- 제목, 내용
- 태그 목록
- 좋아요 수
- 동아리 ID (FK), 모집공고 ID (FK)
- 작성자 ID (FK)
- 제목, 내용
- 합격 기수
- 좋아요 수
- 동아리 ID (FK)
- 날짜, 내용
- 입금액, 출금액, 잔고
User ──< ClubMember >── Club
│ │
│ ├──< Recruitment ──< Apply
│ │
│ ├──< ClubActivity
│ │
│ ├──< ClubNotice
│ │
│ ├──< ClubQuestion (Q&A)
│ │
│ ├──< ClubFaq
│ │
│ └──< FinancialRecord
Recruitment ──< RecruitmentBookmark >── User
Recruitment ──< PassReview
Club ──< ClubBookmark >── User
Club ──< ClubReview
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 이미지 빌드
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 설정
- 활동분야 (8개): 문화예술, 봉사, 학술, 창업, 취업, 체육, 친목, 기타
- 활동지역 (10개): 지역제한없음, 수도권, 충청/대전, 경남/부산/울산, 경북/대구, 전남/광주, 강원, 전북, 제주, 해외
- 활동대상 (3개): 대학생, 대학원생, 직장인/일반인
- 소속 (2개): 교내, 연합
- 학교 미등록 사용자가 "교내" 선택 시 → "회원 정보 수정-학교 등록이 필요합니다." 안내
- 최신 순 (기본값)
- 조회수 순
- 스크랩 순
- 오래된 순
- 마감일 순
┌──────────────────────────────┐
│ [교내] [학술] │
│ [수도권] [대학생] │
│ │
│ [모집 포스터 이미지] │
│ │
│ 동아리 이름 │
│ 모집공고 제목 │
│ D-7 ♡ 24 │
└──────────────────────────────┘
동아리 관리자가 설정한 커스텀 양식 제공
입력 항목 예시
Q1. 성별을 선택해주세요.
[드롭다운: 남자 / 여자]
Q2. 지원 동기를 입력해주세요.
[텍스트 입력창]
(0 / 500자)
Q3. 포트폴리오 (선택)
[파일 첨부] or [링크 입력]
- 정보 제공 동의: 지원서는 마감일로부터 6개월간 보관 후 영구삭제
- 서비스 이용제한 동의: 거짓 정보 기재 시 서비스 이용 제한
- 제출 버튼 클릭
- 확인 팝업: "제출 후에는 수정이 불가합니다."
- 완료 팝업: "제출이 완료되었습니다."
- [동아리 지원으로 이동]
- [모집공고 계속 보기]
작성 → 관리자 승인 대기 (최대 2일) → 승인 → 게시 → 마감/종료
제약사항
- 활성화 가능한 공고는 오직 1개
- 승인된 공고는 수정 불가
- 수정 필요 시: 기존 공고 종료 후 재작성
지원서 제출 → 서류 심사 → 면접 → 최종 합격/불합격
관리 기능
- 지원서 상세 열람
- 개별 처리 (합격/불합격)
- 면접 상태 변경 시 자동 알림
- 일괄 처리 기능 제공
┌──────────────────────────────┐
│ 활동 내용 텍스트... │
│ │
│ [사진1] [사진2] ... (최대10개)│
│ │
│ 공개 범위: [전체공개/동아리원] │
│ │
│ [댓글 보기 ▼] │
│ └─ 멤버A: 댓글 내용 │
│ └─ 답글 │
│ │
│ [수정] [삭제] │
└──────────────────────────────┘
특징
- 댓글 기본 접힌 상태
- 차단 사용자 댓글은 서로 미노출
- 사용자 이름 = 동아리 내 이름
┌──────────────────────────────┐
│ 날짜 내용 입금 출금 잔고 │
├──────────────────────────────┤
│ 2024.11.15 회비 +50,000 50,000│
│ 2024.11.20 MT비용 -30,000 20,000│
└──────────────────────────────┘
- 동아리 회원 모두 확인 가능
- 단순 입출금 기록
- 잔고 자동 계산
┌──────────────────────────────┐
│ 2024.11.25 (월) 19:00 │
│ 정기 모임 │
│ │
│ 참석 대상: 전체 멤버 │
│ │
│ [출석 체크 링크 생성] │
│ [출석 현황 보기] │
└──────────────────────────────┘
출석 관리
- 현재: 링크 시스템
- 향후: QR 코드 시스템 검토
| 권한 | 관리자 | 스탭 | 일반 멤버 |
|---|---|---|---|
| 멤버 관리 | ✅ | ✅ | ❌ |
| 활동 상태 변경 | ✅ | ✅ | ❌ |
| 직책 변경 | ✅ | ❌ | ❌ |
| 모집공고 작성 | ✅ | ✅ | ❌ |
| 지원자 관리 | ✅ | ✅ | ❌ |
| 공지사항 작성 | ✅ | ✅ | ❌ |
| 활동 내역 작성 | ✅ | ✅ | ✅ |
| Q&A 답변 | ✅ | ✅ | ❌ |
| FAQ 작성 | ✅ | ❌ | ❌ |
| 동아리 폐쇄 | ✅ | ❌ | ❌ |
- 활동중: 현재 활동 중인 멤버
- 활동 종료: 활동은 끝났으나 멤버로 유지
- 탈퇴: 동아리에서 완전히 나감
- 관리자가 일반 멤버에게 관리자 권한 위임
- 위임 시 기존 관리자는 일반 멤버로 전환
- 동아리당 관리자는 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 정보 삭제
- Rate Limiting: 과도한 요청 차단
- 입력 검증: Bean Validation 및 커스텀 검증
- 에러 메시지 마스킹: 민감한 정보 노출 방지
- 마감일로부터 6개월 보관 후 영구 삭제
- 삭제 전 이메일 알림 발송
- 물리적 삭제로 복구 불가능
- 즉시 삭제: 개인정보 (이메일, 전화번호, 학교 정보 등)
- 유지: 활동 후기, 합격 후기, 댓글 (신고로 삭제 가능)
- 익명화: 작성자 이름을 "탈퇴한 회원"으로 변경
신고 가능 대상
- 활동 후기
- 합격 후기
- Q&A
- 댓글/답글
처리 프로세스
- 신고 접수
- 관리자 검토
- 논리 삭제 처리 (
deleted_at설정) - 3개월 후 물리 삭제
소프트웨어 요구사항:
- Java: 17 이상
- Node.js: 18 이상
- MySQL/MariaDB: 8.0 이상
- Redis: 6.0 이상
- Docker: (선택사항) 컨테이너 배포 시
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}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 캐시 히트율 모니터링
문제: JPA에서 연관관계 조회 시 N+1 쿼리 발생 해결:
- QueryDSL을 활용한 Fetch Join
@EntityGraph어노테이션 사용- DTO 프로젝션으로 필요한 데이터만 조회
- 일부 복잡한 로직은 Mybatis로 배치 처리
문제: 서버 메모리 부족 및 업로드 시간 지연 해결:
- AWS S3 직접 업로드 (Presigned URL)
- 이미지 압축 및 리사이징 (Sharp.js)
- 멀티파트 업로드로 대용량 파일 처리
문제: 모집공고 지원 시 동시 요청으로 중복 지원 발생 해결:
- 데이터베이스 유니크 제약조건 설정
- Redis 분산 락 (Redisson)
- 낙관적 락 (
@Version) 활용
문제: Access Token 만료 시 사용자 경험 저하 해결:
- Refresh Token 자동 갱신 로직
- Axios Interceptor로 토큰 만료 시 자동 재발급
- 무한 루프 방지 로직
문제: 모집공고 필터링 시 느린 쿼리 속도 해결:
- 데이터베이스 인덱스 최적화
- QueryDSL 동적 쿼리로 불필요한 조인 제거
- Redis 캐싱으로 자주 조회되는 데이터 저장
이 프로젝트는 실제 유저 유입을 목적으로 진행한 사이드 프로젝트였지만, 여러 현실적인 요건으로 2025년 12월을 마지막으로 종료하였습니다.
- 실제 서비스 런칭: AWS에 인프라를 구축하여 유저 유입 후 계속 서비스 고도화
- 유저 유입: SNS 홍보 및 대학 커뮤니티 마케팅
- 지속적인 운영: 피드백 수집 및 기능 개선
- 풀스택 개발 경험: 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
"동아리 생태계의 디지털 전환을 꿈꾸며"