최근 우리 학교에서 발생한 학생회비 횡령 사건은 기존 학생회비 관리 시스템의 문제점을 여실히 드러내는 계기가 되었다. 각 학생회마다 엑셀 파일을 사용하거나, 인스타그램에 게시하거나, 단체 채팅방에 공유하는 등 서로 다른 방식으로 학생회비를 관리하고 있었고, 이는 투명성과 접근성 측면에서 큰 문제점을 안고 있었다. 특히 과거 학생회비 내역을 찾아보기 어렵고, 통합된 관리 플랫폼이 없다는 점이 가장 큰 문제로 대두되었다.
이러한 문제를 해결하기 위해 우리 팀은 "투명지(To MyongJi)"라는 통합 플랫폼을 기획하게 되었다. 투명지라는 이름에는 "명지대학교 학생들을 위해(To MyongJi)"라는 의미와 함께, 학생회비 내역을 투명하게 공개한다는 의미를 담았다. 현대 학생들의 디바이스 사용 패턴을 고려하여, 모바일 환경에 최적화된 반응형 웹 애플리케이션으로 개발을 진행했다.
프로젝트의 프론트엔드는 체계적인 구조로 설계되었다. 먼저 assets 폴더에는 프로젝트에서 사용되는 폰트와 이미지 등의 리소스를 관리하고, components 폴더에는 재사용 가능한 공통 컴포넌트들을 모듈화하여 관리했다. 특히 admin 관련, login 관련, receipt 관련 컴포넌트들과 함께 Home, MyPage, NotFound, NotLogin 등의 주요 컴포넌트들을 체계적으로 구성했다.
프로젝트의 프론트엔드 개발을 전담하면서, 특히 상태 관리에 많은 고민을 했다. 초기에는 React의 Context API를 고려했지만, 더 효율적인 상태 관리를 위해 Zustand를 도입했다. Zustand는 보일러플레이트가 적고, 직관적인 API를 제공하며, 특히 Javascript와 호환성이 뛰어나다는 장점이 있었다.authStore, collegeStore, studentClubStore, userStore 등을 통해 토큰 기반의 인증 정보와 필요한 데이터를 전역으로 관리했다. Utils 폴더에서는 백엔드와의 통신을 담당하는 API 모듈들을 관리했으며, adminAPI, authAPI, receiptAPI, studentClubMemberAPI 등을 통해 효율적인 데이터 통신을 구현했다.
플랫폼의 핵심 기능은 사용자 경험과 접근성에 중점을 두었다. 일반 학생들은 별도의 회원가입 없이도 학생회비 내역을 자유롭게 조회할 수 있도록 했으며, 단과대학과 학과를 쉽게 선택할 수 있는 직관적인 드롭다운 메뉴를 구현했다. 또한 원하는 기간의 학생회비 내역을 날짜, 내용, 입출금 내역 순으로 깔끔하게 확인할 수 있도록 구성했다.
보안과 권한 관리도 철저히 고려했다. 사용자를 일반 학생, 학생회 회장, 학생회 소속원, 관리자로 구분하여 각각 다른 접근 권한을 부여했다. 특히 학생회 임원진의 경우, 소속 인증 시스템을 통해 검증된 사용자만이 회원가입을 할 수 있도록 설계했다. 이를 통해 학생회비 관리의 책임성을 강화했다.
플랫폼의 핵심 기능은 사용자 경험과 접근성에 중점을 두었다. 일반 학생들은 별도의 회원가입 없이도 학생회비 내역을 자유롭게 조회할 수 있도록 했으며, 단과대학과 학과를 쉽게 선택할 수 있는 직관적인 드롭다운 메뉴를 구현했다. 또한 원하는 기간의 학생회비 내역을 날짜, 내용, 입출금 내역 순으로 깔끔하게 확인할 수 있도록 구성했다.
보안과 권한 관리도 철저히 고려했다. 사용자를 일반 학생, 학생회 회장, 학생회 소속원, 관리자로 구분하여 각각 다른 접근 권한을 부여했다. 특히 학생회 임원진의 경우, 소속 인증 시스템을 통해 검증된 사용자만이 회원가입을 할 수 있도록 설계했다. 이를 통해 학생회비 관리의 책임성을 강화했다.
개발 과정에서 마주친 가장 큰 도전은 전역 상태 관리의 복잡성과 CORS 에러였다. 이러한 문제를 해결하기 위해 Zustand를 도입하여 상태 관리를 효율적으로 개선했으며, 프론트엔드와 백엔드 모두를 HTTPS로 배포하여 CORS 문제를 해결했다. 특히 Zustand를 통한 상태 관리는 React의 Context API나 Redux에 비해 더 간단하고 직관적인 방식으로 전역 상태를 관리할 수 있게 해주었다.
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
const useAuthStore = create(
persist(
(set) => ({
authData: null,
setAuthData: (data) => set({ authData: data }),
clearAuthData: () => set({ authData: null }),
}),
{
name: 'auth-storage',
storage: {
getItem: (name) => {
const str = localStorage.getItem(name);
return str ? JSON.parse(str) : null;
},
setItem: (name, value) => localStorage.setItem(name, JSON.stringify(value)),
removeItem: (name) => localStorage.removeItem(name),
},
}
)
);
export default useAuthStore;
현재는 플랫폼의 기능을 더욱 확장하기 위해 새로운 기능들을 개발 중에 있다. CSV 파일을 통한 기존 데이터 마이그레이션 기능은 기존 엑셀로 관리되던 학생회비 데이터를 손쉽게 이전할 수 있게 해줄 것이다. 또한 Naver Clova OCR을 활용한 영수증 자동 인식 기능을 통해 학생회 임원진의 업무 효율성을 크게 향상시킬 수 있을 것으로 기대된다.
프로젝트의 유지보수성과 보안성을 높이기 위해 환경 변수를 적극적으로 활용했다. .env 파일을 통해 API 엔드포인트와 같은 중요한 설정값들을 관리했는데, 이는 개발 환경과 배포 환경에서의 유연한 설정 변경을 가능하게 했다.
# VITE_API_BASE_URL=http://ec2-43-201-18-151.ap-northeast-2.compute.amazonaws.com:8080
# VITE_API_BASE_URL=http://localhost:8080
VITE_API_BASE_URL=https://api.tomyongji.com
이러한 환경 변수 관리는 여러 가지 장점을 제공했다
개발 환경의 유연성: 로컬 개발 환경, EC2 서버, 실제 프로덕션 환경 등 다양한 환경에서 쉽게 API 엔드포인트를 전환할 수 있었다.
보안 강화: API 엔드포인트와 같은 중요한 정보를 소스 코드에 직접 하드코딩하지 않음으로써 보안성을 높였다.
코드 유지보수성: 환경별 설정값을 한 곳에서 관리함으로써 변경 사항 적용이 용이해졌다.
실제로 다음과 같이 코드를 작성했다.
import api, { API_BASE_URL } from './api';
// 특정 학생회 영수증 조회
export const fetchClubReceipts = async (clubId) => {
try {
const response = await api.get(`${API_BASE_URL}/api/receipt/club/${clubId}`);
return response.data;
} catch (error) {
console.error('학생회 영수증 정보를 가져오는 데 실패했습니다:', error);
throw error;
}
};
이러한 환경 변수 관리 방식은 특히 팀 프로젝트에서 큰 장점을 발휘했다. 백엔드 개발자와의 협업 시 API 엔드포인트 변경이 필요한 경우, 소스 코드를 수정할 필요 없이 환경 변수만 변경하면 되어 개발 프로세스가 훨씬 효율적이었다. 또한 배포 환경에서는 보안을 위해 HTTPS가 적용된 도메인을 사용하도록 설정하여, 안전한 데이터 통신을 보장할 수 있었다.
프로젝트의 배포 과정에서도 여러 기술적 도전이 있었다. 초기에는 Vercel을 통해 'tomyongji.vercel.app' 도메인으로 서비스를 제공했지만, 더 전문적인 이미지와 접근성을 위해 AWS를 통해 'tomyongji.com' 도메인을 설정했다. 이 과정에서 도메인 리다이렉션 설정을 통해 기존 Vercel 도메인에서 새로운 도메인으로 자연스러운 전환을 구현했다.
또한 SNS 공유 시 서비스를 더 효과적으로 소개하기 위해 메타 태그를 최적화했다. Open Graph 프로토콜을 활용하여 링크 공유 시 투명지의 로고와 서비스 설명이 미리보기로 표시되도록 구현했다.
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:type" content="website">
<meta property="og:url" content="https://tomyongji.com">
<meta property="og:title" content="투명지">
<meta property="og:image" content="/thumbnail.png">
<meta property="og:description" content="학생회비 사용 내역을 투명하게">
<meta property="og:site_name" content="tomyongji">
<meta property="og:locale" content="ko_KR">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<title>투명지</title>
</head>
프로젝트를 진행하면서 받은 교수님과 학우들의 피드백은 매우 유익했다. 특히 개인정보처리방침의 필요성을 지적받아 PrivacyPolicy.jsx를 추가하여 법적 요구사항을 충족시켰다. 또한 현재는 비로그인 사용자도 조회가 가능하도록 되어있는데, 학교 구성원들끼리만 정보를 공유하는 것이 더 안전할 것이라는 의견을 받아 이에 대한 검토를 진행 중이다.
법대 교수님께 받은 자문에서는 학생회비 공개에 대한 법적 모호성이 지적되었다. 공식적인 행정 기관의 승인 없이는 신고에 따른 법적 문제가 발생할 수 있다는 의견을 받아, 이에 대한 추가적인 법적 검토와 대책 마련이 필요한 상황이다.
iOS 개발자를 희망하는 나에게 있어 웹앱 개발 경험은 매우 중요한 의미를 가진다. 웹 개발을 통해 기본적인 애플리케이션 아키텍처와 사용자 경험 설계를 이해할 수 있었고, 이는 향후 iOS 앱 개발에 큰 도움이 될 것이다. 웹앱과 iOS 앱은 각각의 장단점이 있는데, 웹앱의 경우 빠른 개발과 배포가 가능하고 크로스 플랫폼을 지원한다는 장점이 있다. 반면 iOS 앱은 네이티브 기능을 충분히 활용할 수 있고, 더 나은 성능과 사용자 경험을 제공할 수 있다.
웹 기술을 먼저 익힘으로써 애플리케이션의 진화 과정을 이해하고, 이를 바탕으로 더 나은 iOS 앱을 개발할 수 있을 것으로 기대한다. 특히 웹앱 개발 과정에서 얻은 사용자 인터페이스 설계, 상태 관리, API 통신 등의 경험은 iOS 앱 개발에도 큰 도움이 될 것이다.
이번 프로젝트를 통해 실제 사용자들의 니즈를 파악하고 해결하는 과정을 경험할 수 있었다. 특히 프론트엔드 개발자로서 사용자 경험을 최우선으로 고려하는 개발의 중요성을 깊이 이해하게 되었다. 현재는 웹앱 서비스의 안정화와 함께 iOS 앱 개발을 준비 중이며, 법적 검토도 진행하고 있다. 이 플랫폼이 명지대학교 학생회비 관리의 투명성과 효율성을 크게 향상시킬 것으로 기대하며, 앞으로도 지속적인 개선과 발전을 이어나갈 계획이다.