AIM AJOU는 아주대학교 구성원들의 프로젝트 결과물을 체계적으로 관리하고, 외부에 효과적으로 공개할 수 있도록 지원하는 반응형 웹 기반 SaaS 플랫폼입니다.
- 📌 학생들의 포트폴리오를 체계적으로 관리하고 취업 경쟁력 강화
- 🔍 교수 및 연구실의 연구 성과 관리 및 홍보
- 🤝 기업과 대학 간 산학협력 연계 강화
- 💻 모든 디바이스에서 최적화된 사용자 경험 제공
❌ 학생들의 프로젝트 결과물이 체계적으로 관리되지 않아 졸업 후 사장됨
❌ 기업이 우수한 인재를 발굴하는 데 어려움
❌ 포트폴리오 관리를 위한 통합 플랫폼 부재
|
|
|
|
- 소프트콘 프로젝트 자동 크롤링 (Cheerio 활용)
- 학기별/카테고리별 데이터 수집
- 실시간 크롤링 진행 상황 모니터링
- Firestore 자동 저장
1️⃣ Google 계정으로 로그인 (아주대 이메일)
2️⃣ 마크다운 에디터로 프로젝트 작성
3️⃣ 이미지, PDF 등 파일 첨부
4️⃣ 키워드 태그 설정
5️⃣ 게시 및 공유
1️⃣ 연구실 정보 등록
2️⃣ 학생 포트폴리오 검색 및 검토
3️⃣ 댓글로 피드백 제공
4️⃣ 연구 성과 공유
1️⃣ 기업 정보 등록
2️⃣ 기술 스택/프로젝트 경험 기반 인재 검색
3️⃣ 관심 학생에게 직접 컨택
4️⃣ 산학협력 프로젝트 매칭
1️⃣ 사용자 권한 관리 (차단/해제)
2️⃣ 콘텐츠 관리 및 승인
3️⃣ 소프트콘 자동 크롤링 실행
4️⃣ 공지사항 발행
📆 2025년 1학기 (16주)
🗓️ 2025년 3월 ~ 2025년 6월
| 주차 | 단계 | 주요 내용 |
|---|---|---|
| 1-3주 | 기획 및 설계 | 요구사항 분석, UI/UX 디자인, 개발 환경 구축 |
| 4-7주 | 핵심 기능 구현 | 인증 시스템, 기본 UI, 포트폴리오 CRUD |
| 8-10주 | 고급 기능 구현 | 검색/필터링, 마크다운 에디터, 댓글/좋아요 |
| 11-13주 | 관리자 & 안정화 | 관리자 페이지, 사용자 테스트, 성능 최적화 |
| 14-16주 | 최종 완성 & 배포 | 반응형 디자인, 프로덕션 배포, 최종 발표 |
graph TB
A[클라이언트<br/>React 18 + Material-UI] --> B[Firebase Hosting]
B --> C[Firebase Authentication<br/>Google OAuth]
B --> D[Firestore Database<br/>NoSQL]
B --> E[Firebase Storage<br/>파일 저장]
B --> F[Cloud Functions<br/>서버 로직]
F --> G[크롤링 시스템<br/>Cheerio + Axios]
F --> H[이메일 알림<br/>Nodemailer]
style A fill:#1E40AF
style B fill:#FFCA28
style C fill:#4285F4
style D fill:#FFA611
style E fill:#34A853
style F fill:#EA4335
style G fill:#E88C1B
style H fill:#339933
![]() 권세빈 202220781 💻 Full-Stack Developer 📧 a856412@gmail.com |
![]() 한지원 202220786 💻 Full-Stack Developer nowijnah@ajou.ac.kr |
최재영 교수님 (mobilechoi@ajou.ac.kr)
- 김정훈 (라인플러스)
- 이승윤 (쿠팡)
- ✨ Firebase 서버리스 아키텍처 완전 구현
- 🚀 50개 이상 재사용 가능한 React 컴포넌트 개발
- 📝 마크다운 기반 리치 텍스트 에디터 시스템 구축
- 💬 실시간 댓글 및 좋아요 커뮤니티 플랫폼 구현
- 🤖 자동화된 크롤링 및 데이터 관리 시스템 개발
- 📱 모든 디바이스 최적화 반응형 디자인 구현
- ⚡ 페이지 로딩 시간: 3.2초 → 1.8초 (44% 개선)
- 🖼️ 이미지 로딩: 2.1초 → 0.9초 (57% 개선)
- 🔍 검색 응답 시간: 1.5초 → 0.6초 (60% 개선)
ajouproject/
├── public/ # 정적 파일
├── src/
│ ├── components/ # React 컴포넌트
│ │ ├── auth/ # 인증 (AuthContext, ProtectedRoute)
│ │ ├── card/ # 콘텐츠 카드
│ │ ├── common/ # 공통 컴포넌트
│ │ ├── home/ # 홈페이지
│ │ ├── posts/ # 게시물 (MarkdownEditor, FileUploader)
│ │ └── settings/ # 설정
│ ├── pages/ # 페이지
│ │ ├── admin/ # 관리자
│ │ ├── portfolios/ # 포트폴리오
│ │ ├── labs/ # 연구실
│ │ └── companies/ # 기업
│ ├── firebase.js # Firebase 설정
│ ├── App.js # 메인 앱
│ └── index.js # 엔트리 포인트
├── functions/ # Firebase Cloud Functions
│ ├── index.js # 크롤링, 이메일 알림
│ └── package.json
├── webpack.config.js # Webpack 설정
└── package.json # 의존성 관리
- Node.js 20.x 이상
- npm 또는 yarn
- Firebase 계정
# 1. 저장소 클론
git clone https://github.com/nowijnah/ajouproject.git
cd ajouproject
# 2. 의존성 설치
npm install
# 3. Firebase 설정
# firebase.js에 Firebase 설정 추가
# 4. 개발 서버 실행
npm start
# 5. 프로덕션 빌드
npm run build
# 6. Firebase Functions 배포
cd functions
npm install
firebase deploy --only functionsREACT_APP_FIREBASE_API_KEY=your_api_key
REACT_APP_FIREBASE_AUTH_DOMAIN=your_auth_domain
REACT_APP_FIREBASE_PROJECT_ID=your_project_id
REACT_APP_FIREBASE_STORAGE_BUCKET=your_storage_bucket
REACT_APP_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
REACT_APP_FIREBASE_APP_ID=your_app_id// AuthContext.js - Google OAuth 인증
export const AuthProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState(null);
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, async (user) => {
if (user) {
const userDoc = await getDoc(doc(db, 'users', user.uid));
const userData = userDoc.data();
setCurrentUser({ ...user, role: userData?.role });
}
setLoading(false);
});
return unsubscribe;
}, []);
};// functions/index.js - 소프트콘 크롤링
exports.crawlSoftconData = functions.https.onCall(async (data, context) => {
const { term, category } = data;
const $ = await getHtml(url);
// 프로젝트 목록 추출
$("li.vw_close").each((_, el) => {
const uid = extractUID($(el));
const thumbnail = extractThumbnail($(el));
const title = extractTitle($(el));
projects.push({ uid, thumbnail, title });
});
// Firestore에 저장
await docRef.set(transformForFirestore(detail, term, category));
});// 실시간 댓글 구독
useEffect(() => {
const unsubscribe = onSnapshot(
query(collection(db, `${collectionName}_comments`),
where('postId', '==', postId),
orderBy('createdAt', 'desc')),
(snapshot) => setComments(snapshot.docs.map(doc => ({
id: doc.id, ...doc.data()
})))
);
return unsubscribe;
}, [postId]);이 프로젝트는 MIT License를 따릅니다.
프로젝트에 대한 문의사항이나 제안이 있으시면 아래로 연락 주세요:
- Email: a856412@gmail.com
- Website: https://portfolio.ajou.sw.kr
- GitHub Issues: 프로젝트 이슈
본 프로젝트는 아주대학교 소프트웨어학과 2025-1학기 자기주도 프로젝트로 진행되었습니다.
- 지도교수: 최재영 교수님
- 멘토: 김정훈 (라인플러스), 이승윤 (쿠팡)
- 베타 테스터: 아주대학교 소프트웨어학과 학우 20명

