
기술스팩 TG CRM 기술 스펙
TG CRM 시스템 기술 스펙 문서
Technical Specification Document v1.0
1. 개발 환경 및 도구
1.1 필수 소프트웨어
Node.js: v18.x LTS npm: v9.x SQLite: v3.x (파일 기반 데이터베이스) Git: v2.x VS Code: 최신 버전 (권장 IDE)
1.2 개발 도구 및 확장
VS Code Extensions: - ES7+ React/Redux/React-Native snippets - Prettier - Code formatter - ESLint - TypeScript Importer - SQLite Viewer - REST Client
2. 기술 스택 상세
2.1 Frontend Stack
// 핵심 라이브러리 { "react": "^18.2.0", "react-dom": "^18.2.0", "typescript": "^5.0.0", "vite": "^4.4.0" } // UI 및 스타일링 { "tailwindcss": "^3.3.0", "@headlessui/react": "^1.7.0", "@heroicons/react": "^2.0.0", "react-hot-toast": "^2.4.0" } // 상태 관리 및 폼 { "react-hook-form": "^7.45.0", "@hookform/resolvers": "^3.1.0", "zod": "^3.21.0" } // HTTP 클라이언트 및 유틸리티 { "axios": "^1.4.0", "date-fns": "^2.30.0", "react-router-dom": "^6.14.0" }
2.2 Backend Stack
// 핵심 프레임워크 { "express": "^4.18.0", "typescript": "^5.0.0", "ts-node": "^10.9.0", "nodemon": "^3.0.0" } // 데이터베이스 및 ORM { "sqlite3": "^5.1.6", "typeorm": "^0.3.17", "better-sqlite3": "^8.7.0" } // 인증 및 보안 { "jsonwebtoken": "^9.0.0", "bcryptjs": "^2.4.3", "helmet": "^7.0.0", "cors": "^2.8.5", "express-rate-limit": "^6.8.0" } // 파일 처리 및 API { "multer": "^1.4.5", "nodemailer": "^6.9.0", "xlsx": "^0.18.5" } // 개발 및 테스트 { "jest": "^29.6.0", "@types/jest": "^29.5.0", "supertest": "^6.3.0" }
3. 데이터베이스 스키마 상세
3.1 고객 관리 테이블
-- 고객 기본 정보 CREATE TABLE customers ( id INTEGER PRIMARY KEY AUTOINCREMENT, original_sequence INTEGER, -- 기존 Excel 순번 company_name TEXT NOT NULL, -- 고객명/회사명 industry TEXT, -- 업종/분야 region TEXT, -- 지역 category TEXT, -- 구분 phone1 TEXT, -- 전화번호1 phone2 TEXT, -- 전화번호2 contact_person TEXT, -- 담당자명 extension TEXT, -- 내선 email TEXT, -- 이메일 address TEXT, -- 주소 website TEXT, -- 웹사이트 notes TEXT, -- 메모 is_active BOOLEAN DEFAULT 1, -- 활성 상태 assigned_to INTEGER, -- 담당 직원 ID created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, created_by INTEGER, -- 등록자 ID updated_by INTEGER -- 수정자 ID ); -- 인덱스 생성 CREATE INDEX idx_customers_company_name ON customers(company_name); CREATE INDEX idx_customers_industry ON customers(industry); CREATE INDEX idx_customers_region ON customers(region); CREATE INDEX idx_customers_category ON customers(category); CREATE INDEX idx_customers_assigned_to ON customers(assigned_to); CREATE INDEX idx_customers_is_active ON customers(is_active); -- 고객 태그 시스템 CREATE TABLE customer_tags ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, color TEXT DEFAULT '#3B82F6', created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE customer_tag_relations ( customer_id INTEGER, tag_id INTEGER, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (customer_id, tag_id), FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE, FOREIGN KEY (tag_id) REFERENCES customer_tags(id) ON DELETE CASCADE );
3.2 사용자 및 권한 관리
-- 사용자 테이블 CREATE TABLE users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, email TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, full_name TEXT NOT NULL, role TEXT DEFAULT 'staff' CHECK (role IN ('admin', 'manager', 'staff')), department TEXT, phone TEXT, is_active BOOLEAN DEFAULT 1, last_login_at DATETIME, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 인덱스 생성 CREATE INDEX idx_users_username ON users(username); CREATE INDEX idx_users_email ON users(email); CREATE INDEX idx_users_role ON users(role); -- 세션 관리 CREATE TABLE user_sessions ( id TEXT PRIMARY KEY, user_id INTEGER NOT NULL, expires_at DATETIME NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ); CREATE INDEX idx_sessions_user_id ON user_sessions(user_id); CREATE INDEX idx_sessions_expires_at ON user_sessions(expires_at);
3.3 커뮤니케이션 시스템
-- 커뮤니케이션 로그 CREATE TABLE communication_logs ( id INTEGER PRIMARY KEY AUTOINCREMENT, customer_id INTEGER NOT NULL, user_id INTEGER NOT NULL, type TEXT NOT NULL CHECK (type IN ('email', 'sms', 'kakao', 'call', 'meeting', 'note')), subject TEXT, content TEXT, status TEXT DEFAULT 'pending' CHECK (status IN ('pending', 'sent', 'delivered', 'read', 'failed', 'completed')), sent_at DATETIME, delivered_at DATETIME, read_at DATETIME, metadata TEXT, -- JSON 문자열로 저장 created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES users(id) ); -- 인덱스 생성 CREATE INDEX idx_comm_logs_customer_id ON communication_logs(customer_id); CREATE INDEX idx_comm_logs_user_id ON communication_logs(user_id); CREATE INDEX idx_comm_logs_type ON communication_logs(type); CREATE INDEX idx_comm_logs_status ON communication_logs(status); CREATE INDEX idx_comm_logs_sent_at ON communication_logs(sent_at); -- 이메일 템플릿 CREATE TABLE email_templates ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, subject TEXT NOT NULL, content TEXT NOT NULL, variables TEXT, -- JSON 문자열로 저장 is_active BOOLEAN DEFAULT 1, created_by INTEGER, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (created_by) REFERENCES users(id) ); CREATE INDEX idx_email_templates_name ON email_templates(name); CREATE INDEX idx_email_templates_is_active ON email_templates(is_active); -- SMS 템플릿 CREATE TABLE sms_templates ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, content TEXT NOT NULL, variables TEXT, -- JSON 문자열로 저장 is_active BOOLEAN DEFAULT 1, created_by INTEGER, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (created_by) REFERENCES users(id) ); CREATE INDEX idx_sms_templates_name ON sms_templates(name); CREATE INDEX idx_sms_templates_is_active ON sms_templates(is_active);
3.4 시스템 로그 및 감사
-- 활동 로그 CREATE TABLE activity_logs ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, action TEXT NOT NULL, target_type TEXT, -- 대상 타입 (customer, user, etc.) target_id INTEGER, -- 대상 ID details TEXT, -- JSON 문자열로 저장 ip_address TEXT, user_agent TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) ); -- 인덱스 생성 CREATE INDEX idx_activity_logs_user_id ON activity_logs(user_id); CREATE INDEX idx_activity_logs_action ON activity_logs(action); CREATE INDEX idx_activity_logs_target ON activity_logs(target_type, target_id); CREATE INDEX idx_activity_logs_created_at ON activity_logs(created_at); -- 시스템 설정 CREATE TABLE system_settings ( id INTEGER PRIMARY KEY AUTOINCREMENT, key_name TEXT NOT NULL UNIQUE, value TEXT, description TEXT, updated_by INTEGER, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (updated_by) REFERENCES users(id) ); CREATE INDEX idx_system_settings_key_name ON system_settings(key_name);
4. API 설계
4.1 인증 API
// 인증 엔드포인트 POST /api/auth/login POST /api/auth/logout POST /api/auth/refresh GET /api/auth/me // 요청/응답 인터페이스 interface LoginRequest { username: string; password: string; } interface AuthResponse { user: { id: number; username: string; email: string; fullName: string; role: 'admin' | 'manager' | 'staff'; }; token: string; expiresAt: string; }
4.2 고객 관리 API
// 고객 관리 엔드포인트 GET /api/customers?page=1&limit=20&search=&industry=®ion= POST /api/customers GET /api/customers/:id PUT /api/customers/:id DELETE /api/customers/:id POST /api/customers/import GET /api/customers/export // 고객 데이터 인터페이스 interface Customer { id?: number; originalSequence?: number; companyName: string; industry?: string; region?: string; category?: string; phone1?: string; phone2?: string; contactPerson?: string; extension?: string; email?: string; address?: string; website?: string; notes?: string; isActive: boolean; assignedTo?: number; tags?: number[]; }
4.3 커뮤니케이션 API
// 커뮤니케이션 엔드포인트 POST /api/communications/email POST /api/communications/sms POST /api/communications/kakao POST /api/communications/call-log GET /api/communications/logs/:customerId GET /api/communications/templates/email GET /api/communications/templates/sms // 이메일 발송 인터페이스 interface EmailRequest { customerIds: number[]; templateId?: number; subject: string; content: string; attachments?: File[]; scheduledAt?: string; }
5. 프로젝트 구조
5.1 Frontend 구조
src/ ├── components/ # 재사용 가능한 컴포넌트 │ ├── ui/ # 기본 UI 컴포넌트 │ ├── forms/ # 폼 컴포넌트 │ └── layout/ # 레이아웃 컴포넌트 ├── pages/ # 페이지 컴포넌트 │ ├── auth/ # 인증 관련 페이지 │ ├── customers/ # 고객 관리 페이지 │ ├── communications/ # 커뮤니케이션 페이지 │ └── dashboard/ # 대시보드 ├── hooks/ # 커스텀 훅 ├── services/ # API 서비스 ├── store/ # 상태 관리 ├── types/ # TypeScript 타입 정의 ├── utils/ # 유틸리티 함수 └── assets/ # 정적 자원
5.2 Backend 구조
src/ ├── controllers/ # 컨트롤러 (요청 처리) ├── services/ # 비즈니스 로직 ├── models/ # 데이터 모델 (TypeORM 엔티티) ├── middlewares/ # 미들웨어 ├── routes/ # 라우트 정의 ├── config/ # 설정 파일 ├── utils/ # 유틸리티 함수 ├── types/ # 타입 정의 └── tests/ # 테스트 파일
6. 환경 설정
6.1 Environment Variables
# Database (SQLite) DB_PATH=./data/tg_crm.db DB_BACKUP_PATH=./data/backups/ # JWT JWT_SECRET=your-secret-key-here JWT_EXPIRES_IN=7d # Email Service EMAIL_HOST=smtp.gmail.com EMAIL_PORT=587 EMAIL_USER=your-email@gmail.com EMAIL_PASSWORD=your-app-password # SMS API SMS_API_KEY=your-sms-api-key SMS_API_SECRET=your-sms-api-secret # KakaoTalk API KAKAO_API_KEY=your-kakao-api-key # Application PORT=3000 NODE_ENV=development CORS_ORIGIN=http://localhost:5173 # File Upload UPLOAD_PATH=./uploads/ MAX_FILE_SIZE=10485760
6.2 개발 환경 스크립트
// package.json scripts { "scripts": { "dev": "concurrently \"npm run server:dev\" \"npm run client:dev\"", "server:dev": "cd backend && npm run dev", "client:dev": "cd frontend && npm run dev", "build": "npm run client:build && npm run server:build", "test": "npm run server:test && npm run client:test", "db:migrate": "cd backend && npm run migration:run", "db:seed": "cd backend && npm run seed:run" } }
7. 보안 구현
7.1 인증 및 권한
- JWT 토큰 기반 인증
- 역할 기반 접근 제어 (RBAC)
- 비밀번호 해싱 (bcrypt)
- 세션 만료 관리
7.2 데이터 보안
- SQL Injection 방지 (TypeORM 사용)
- XSS 방지 (입력 데이터 검증)
- CSRF 토큰
- HTTPS 강제 사용
7.3 API 보안
- Rate Limiting
- CORS 정책
- 입력 데이터 검증 (Zod)
- 로깅 및 모니터링
8. 성능 최적화
8.1 데이터베이스 최적화
- 적절한 인덱스 설정
- 쿼리 최적화
- 커넥션 풀 관리
- 데이터 페이지네이션
8.2 프론트엔드 최적화
- 코드 스플리팅
- 이미지 최적화
- 번들 크기 최소화
- 메모이제이션 활용
8.3 캐싱 전략
- 메모리 내 세션 캐시
- API 응답 캐시 (Node.js 메모리)
- 정적 자원 캐시
- SQLite 쿼리 최적화 및 인덱스 활용
본 문서는 TG CRM 시스템의 기술적 구현을 위한 상세 스펙을 제공합니다.