Cutshion Groupware ERP
커션(Cutshion) 사내 임직원이 업무 전반을 하나의 플랫폼에서 처리할 수 있도록 구축한 그룹웨어 + ERP 통합 시스템입니다. 전자결재·발주·휴가·출결·프로젝트·AI 어시스턴트·캘린더 리마인더·내부 메일 등 핵심 업무 기능을 멀티테넌시 기반으로 제공하며, 회사 구조에 맞게 커스터마이징할 수 있도록 설계했습니다.
- •기간: 2026년 1월 ~ 진행 중 (사내 베타 운영)
- •유형: 사내 전용 그룹웨어 + ERP (멀티테넌시)
- •규모: 업무 모듈 29개 · 화면 라우트 76개 · REST API 220여 개
- •역할: 3인 팀 · 프론트엔드 담당 (백엔드·인프라 일부 설계·참여)
담당 역할
프론트엔드를 중심으로 핵심 업무 화면과 클라이언트 로직을 구현했고, 담당 화면에 필요한 REST API 명세 정의와 FastAPI 엔드포인트 구현에도 참여했습니다. 전자결재를 중심축으로 발주·휴가·초과근무 등 주변 모듈을 연결하고, 실시간 알림·권한·감사 흐름이 같은 기준으로 동작하도록 정리했습니다.
- •전자결재 워크플로우와 발주 상태 머신 설계
- •SSE 기반 실시간 알림 인프라 및 대시보드 위젯 시스템
- •휴가 동시성 제어 및 APScheduler 자동 부여
- •AI 어시스턴트 (로컬 LLM 스트리밍 + 기안서 프리필)
- •캘린더/할 일 리마인더 시스템 (분 단위 스케줄러 + 브라우저 OS 알림)
- •프로젝트 다대다 멤버 구조 재편 및 부서 트리 일괄 추가
- •멀티테넌시 데이터 모델 및 RBAC 권한 체계
기술 스택
Frontend
| 기술 | 역할 |
| Next.js 16+ (App Router) | SSR/CSR 렌더링 |
| React 19+ / TypeScript 5+ | UI 컴포넌트, 타입 안정성 |
| TailwindCSS 4 / shadcn/ui | 스타일링 및 UI 컴포넌트 |
| TanStack Query 5 | 서버 상태 관리 및 캐싱 |
| Zustand 5 | 전역 클라이언트 상태 |
| React Hook Form + Zod | 폼 상태·유효성 검사 |
| @dnd-kit | 대시보드 위젯 드래그 앤 드롭 |
Backend
| 기술 | 역할 |
| Python 3.12+ / FastAPI 0.115+ | 비동기 REST API 서버 |
| SQLModel + Alembic | ORM 및 스키마 마이그레이션 |
| asyncpg | PostgreSQL 비동기 드라이버 |
| APScheduler | 스케줄러 (휴가 자동 부여 등) |
| PyJWT | JWT 인증 |
| uv | Python 패키지 관리 |
인프라
| 기술 | 역할 |
| Docker / Docker Compose | 컨테이너 오케스트레이션 |
| PostgreSQL 16 | 메인 데이터베이스 |
| llama.cpp (Gemma 4 E2B) | 로컬 LLM 서버, OpenAI 호환 API |
| SSE (Server-Sent Events) | 실시간 알림 스트리밍 |
| Service Worker / Notification API | 브라우저 OS 알림 (백그라운드 탭 포함) |
핵심 기능
전자결재 · 발주 통합 워크플로우
기안서 작성 → 결재선 설정 → 승인/반려/회수 → 재상신까지의 전자결재 흐름과, 발주 품의서를 상태 머신으로 연동한 구조입니다. 결재 승인 여부가 발주 상태(초안 → 결재 대기 → 승인 → 발주 완료 → 입고 완료)에 자동 반영되고, 결재선 템플릿 저장·재사용, 부서 기반 참조자 분리, 발주 번호 자동 생성(PO-YYYY-NNNN), 부분 입고 처리까지 포함합니다. 기안서는 여러 프로젝트에 동시 연결할 수 있도록 N:M(document_project_links) 구조로 재편해, 한 건의 결재가 복수 프로젝트에 걸치는 실무 케이스를 반영했습니다.
휴가 · 출결 · 일정 · 리마인더
근로기준법 기준 8종 휴가 유형을 APScheduler가 매일 새벽 자동 부여합니다. 전자결재 승인에 연동해 휴가 상태가 자동 전환되고, 팀/전사 휴가 캘린더, 공휴일 연동(holidays 라이브러리), 시간 단위 휴가 계산, 주말·공휴일만 선택된 신청 차단(3-Layer 방어)까지 지원합니다. 출결은 시간 역행·더블클릭 방지를 서버에서 검증하고, 회의·출장·컨퍼런스 등 일정을 공개 범위별로 관리합니다. 일정·할 일에는 5분~1일 전 리마인더를 설정할 수 있고, APScheduler가 매 분 미발송 건을 잠금 처리해(SELECT ... FOR UPDATE SKIP LOCKED) 토스트와 브라우저 OS 알림(Service Worker)을 동시 발송합니다. 일정 위치·거래처·회사 정보에는 Daum Postcode 기반 주소 검색을 통합했습니다.
실시간 알림 (SSE)
결재 상신·중간 승인·최종 승인/반려·게시판 댓글·메일 수신·일정/할 일 리마인더 등 업무 이벤트를 SSE로 스트리밍해 새로고침 없이 즉시 반영합니다. 실시간 토스트, 말풍선, 드롭다운 알림 목록을 함께 제공하며, 여러 탭에서 동시에 접속해도 모든 탭에 알림이 전달됩니다. 토큰 만료·네트워크 끊김에 대비해 지수 백오프 자동 재연결을 적용했고, visibilitychange 핸들러로 탭 복귀 시 즉시 재연결합니다.
AI 어시스턴트
llama.cpp + Gemma 4 E2B 로컬 LLM을 SSE 스트리밍 방식으로 연동합니다. 사용자가 업무 내용을 입력하면 기안서 유형(초과근무·경비·사직서·발주·일반)을 자동 분류하고, 해당 폼에 내용을 프리필해 이동시킵니다. 채팅 정지 버튼, 스마트 리마인더 스누즈도 제공합니다.
대시보드
역할(super_admin · tenant_admin · manager · user)별로 다른 위젯 카탈로그를 제공하고, 사용자가 원하는 위젯만 선택·정렬할 수 있습니다. DnD 기반 bento 그리드로 위젯 순서를 변경하며, 구성은 localStorage에 영속화됩니다.
조직 · 권한 관리
멀티테넌시로 테넌트별 데이터를 분리하고, RBAC 4단계(super_admin / tenant_admin / manager / user)로 권한을 관리합니다. document_number·order_number 같은 시퀀스도 테넌트 단위 복합 unique로 분리하며, 모듈 단위 활성화, 조직도 차트뷰, 부서 계층 관리, 테넌트 로고·컬러 커스터마이징을 지원합니다.
프로젝트 관리
초기에는 department_id FK로 단일 담당부서만 연결하던 구조였으나, 실무에서 여러 부서가 협업하는 경우가 많아 다대다 멤버 기반(ProjectMember)으로 재편했습니다. 부서 트리에서 해당 부서 + 모든 자손 부서의 활성 사용자를 클라이언트 한 번의 호출로 일괄 추가할 수 있고, 참여 부서는 멤버의 부서를 통해 동적 산출됩니다. 매니저 위임, 부서/역할별 접근 제어, 캘린더와 프로젝트 일정 통합 표시, 프로젝트 단위 에러 리포트 등록까지 포함합니다.
협업 (게시판 · 내부 메일)
전사/부서 게시판, 댓글·대댓글(depth 2), 비밀 댓글(서버사이드 마스킹), 첨부파일 드래그앤드롭 업로드(총 1GB), 조회수 원자적 증가, 고유 열람자 기반 미읽음 배지를 제공합니다. 게시판 카테고리는 살아있는 행에만 적용되는 partial unique index로 소프트딜리트 후 동일 이름 재생성을 허용합니다. 사내 임직원 간 내부 메일은 발신/수신 측 삭제 상태를 분리한 모델(Mail + MailRecipient)로 설계해 한쪽이 삭제해도 상대방 쪽 사본이 유지되며, 받은메일함·보낸메일함·임시저장·중요메일·휴지통 폴더와 mail_received SSE 알림으로 일반 메일 서비스에 익숙한 흐름을 구현했습니다. 메일 수신 시에는 토스트뿐 아니라 알림벨에 영구 알림을 남기고, 수신자(to)와 참조(cc)를 문구로 구분해 표시합니다.
성과
- •사내 임직원 전용 시스템으로 실 운영 적용
- •기존에 개별 관리하던 결재·발주·휴가·출결 프로세스를 하나의 플랫폼으로 통합
- •전자결재와 발주·휴가·초과근무 연동으로 불필요한 이중 입력 제거
- •AI 어시스턴트를 통한 기안서 작성 진입점 자동 안내
- •멀티테넌시 구조로 타 조직 배포를 고려한 확장 기반 마련
