{
  "status": "success",
  "confidence": "high",
  "result": {
    "summary": "WACE ERP 백엔드 전체 아키텍처 분석 완료",
    "details": "Node.js + Express + TypeScript + PostgreSQL Raw Query 기반 멀티테넌시 시스템. 70+ 라우트, 70+ 컨트롤러, 80+ 서비스로 구성된 계층형 아키텍처. JWT 인증, 3단계 권한 체계(SUPER_ADMIN/COMPANY_ADMIN/USER), company_code 기반 완전한 데이터 격리 구현.",
    "files_affected": [
      "docs/backend-architecture-detailed-analysis.md (상세 분석 문서)",
      "docs/backend-architecture-summary.md (요약 문서)",
      "docs/backend-api-route-mapping.md (API 라우트 전체 매핑)"
    ],
    "key_findings": {
      "architecture_pattern": "Layered Architecture (Controller → Service → Database)",
      "tech_stack": {
        "language": "TypeScript",
        "runtime": "Node.js 20.10.0+",
        "framework": "Express.js",
        "database": "PostgreSQL (pg 라이브러리, Raw Query)",
        "authentication": "JWT (jsonwebtoken)",
        "scheduler": "node-cron",
        "external_db_support": ["PostgreSQL", "MySQL", "MSSQL", "Oracle"]
      },
      "directory_structure": {
        "controllers": "70+ 파일 (API 요청 수신, 응답 생성)",
        "services": "80+ 파일 (비즈니스 로직, 트랜잭션 관리)",
        "routes": "70+ 파일 (API 라우팅)",
        "middleware": "4개 (인증, 권한, 슈퍼관리자, 에러핸들러)",
        "types": "26개 (TypeScript 타입 정의)",
        "utils": "유틸리티 함수 (JWT, 암호화, 로거)"
      },
      "middleware_stack": [
        "1. Process Level Exception Handlers",
        "2. Helmet (보안 헤더)",
        "3. Compression (Gzip)",
        "4. Body Parser (10MB limit)",
        "5. Static Files (/uploads)",
        "6. CORS (credentials: true)",
        "7. Rate Limiting (1분 10000회)",
        "8. Token Auto Refresh (1시간 이내 만료 시 갱신)",
        "9. API Routes (70+개)",
        "10. 404 Handler",
        "11. Error Handler"
      ],
      "authentication_flow": {
        "step1": "로그인 요청 → AuthController.login()",
        "step2": "AuthService.processLogin() → loginPwdCheck() (bcrypt 검증)",
        "step3": "getPersonBeanFromSession() → 사용자 정보 조회",
        "step4": "insertLoginAccessLog() → 로그인 이력 저장",
        "step5": "JwtUtils.generateToken() → JWT 토큰 생성",
        "step6": "응답: { token, userInfo, firstMenuPath }"
      },
      "jwt_payload": {
        "userId": "사용자 ID",
        "userName": "사용자명",
        "companyCode": "회사 코드 (멀티테넌시 키)",
        "userType": "권한 레벨 (SUPER_ADMIN/COMPANY_ADMIN/USER)",
        "exp": "만료 시간 (24시간)"
      },
      "permission_levels": {
        "SUPER_ADMIN": {
          "company_code": "*",
          "userType": "SUPER_ADMIN",
          "capabilities": [
            "전체 회사 데이터 접근",
            "DDL 실행",
            "회사 생성/삭제",
            "시스템 설정 변경"
          ]
        },
        "COMPANY_ADMIN": {
          "company_code": "특정 회사 (예: ILSHIN)",
          "userType": "COMPANY_ADMIN",
          "capabilities": [
            "자기 회사 데이터만 접근",
            "자기 회사 사용자 관리",
            "회사 설정 변경"
          ]
        },
        "USER": {
          "company_code": "특정 회사",
          "userType": "USER",
          "capabilities": [
            "자기 회사 데이터만 접근",
            "읽기/쓰기 권한만"
          ]
        }
      },
      "multi_tenancy": {
        "principle": "모든 쿼리에 company_code 필터 필수",
        "pattern": "JWT 토큰에서 company_code 추출 (클라이언트 신뢰 금지)",
        "super_admin_visibility": "일반 회사 사용자에게 슈퍼관리자(company_code='*') 숨김",
        "correct_pattern": "WHERE company_code = $1 AND company_code != '*'",
        "wrong_pattern": "req.body.companyCode 사용 (보안 위험!)"
      },
      "api_routes": {
        "total_count": "200+개",
        "categories": {
          "인증/관리자": "15개",
          "테이블/화면": "40개",
          "플로우": "15개",
          "데이터플로우": "5개",
          "외부 연동": "15개",
          "배치": "10개",
          "메일": "5개",
          "파일": "5개",
          "기타": "90개"
        }
      },
      "business_domains": {
        "관리자": {
          "controller": "adminController.ts",
          "service": "adminService.ts",
          "features": ["사용자 관리", "메뉴 관리", "권한 그룹 관리", "시스템 설정"]
        },
        "테이블/화면": {
          "controller": "tableManagementController.ts, screenManagementController.ts",
          "service": "tableManagementService.ts, screenManagementService.ts",
          "features": ["테이블 메타데이터", "화면 정의", "화면 그룹", "테이블 로그", "엔티티 관계"]
        },
        "플로우": {
          "controller": "flowController.ts",
          "service": "flowExecutionService.ts, flowDefinitionService.ts",
          "features": ["워크플로우 설계", "단계 관리", "데이터 이동", "조건부 이동", "오딧 로그"]
        },
        "데이터플로우": {
          "controller": "dataflowController.ts, dataflowDiagramController.ts",
          "service": "dataflowService.ts, dataflowDiagramService.ts",
          "features": ["테이블 관계 정의", "ERD", "다이어그램 시각화", "관계 실행"]
        },
        "외부 연동": {
          "controller": "externalDbConnectionController.ts, externalRestApiConnectionController.ts",
          "service": "externalDbConnectionService.ts, dbConnectionManager.ts",
          "features": ["외부 DB 연결", "Connection Pool 관리", "REST API 프록시"]
        },
        "배치": {
          "controller": "batchController.ts, batchManagementController.ts",
          "service": "batchService.ts, batchSchedulerService.ts",
          "features": ["Cron 스케줄러", "외부 DB → 내부 DB 동기화", "컬럼 매핑", "실행 이력"]
        },
        "메일": {
          "controller": "mailSendSimpleController.ts, mailReceiveBasicController.ts",
          "service": "mailSendSimpleService.ts, mailReceiveBasicService.ts",
          "features": ["메일 발송 (nodemailer)", "메일 수신 (IMAP)", "템플릿 관리", "첨부파일"]
        },
        "파일": {
          "controller": "fileController.ts, screenFileController.ts",
          "service": "fileSystemManager.ts",
          "features": ["파일 업로드 (multer)", "파일 다운로드", "화면별 파일 관리"]
        }
      },
      "database_access": {
        "connection_pool": {
          "min": "2~5 (환경별)",
          "max": "10~20 (환경별)",
          "connectionTimeout": "30000ms",
          "idleTimeout": "600000ms",
          "statementTimeout": "60000ms"
        },
        "query_patterns": {
          "multi_row": "query('SELECT ...', [params])",
          "single_row": "queryOne('SELECT ...', [params])",
          "transaction": "transaction(async (client) => { ... })"
        },
        "sql_injection_prevention": "Parameterized Query 사용 (pg 라이브러리)"
      },
      "external_integration": {
        "supported_databases": ["PostgreSQL", "MySQL", "MSSQL", "Oracle"],
        "connector_pattern": "Factory Pattern (DatabaseConnectorFactory)",
        "rest_api": "axios 기반 프록시"
      },
      "batch_scheduler": {
        "library": "node-cron",
        "timezone": "Asia/Seoul",
        "cron_examples": {
          "매일 새벽 2시": "0 2 * * *",
          "5분마다": "*/5 * * * *",
          "평일 오전 8시": "0 8 * * 1-5"
        },
        "execution_flow": [
          "1. 소스 DB에서 데이터 조회",
          "2. 컬럼 매핑 적용",
          "3. 타겟 DB에 INSERT/UPDATE",
          "4. 실행 로그 기록"
        ]
      },
      "file_handling": {
        "upload_path": "uploads/{company_code}/{timestamp}-{uuid}-{filename}",
        "max_file_size": "10MB",
        "allowed_types": ["이미지", "PDF", "Office 문서"],
        "library": "multer"
      },
      "security": {
        "password_encryption": "bcrypt (12 rounds)",
        "sensitive_data_encryption": "AES-256-CBC (외부 DB 비밀번호)",
        "jwt_secret": "환경변수 관리",
        "security_headers": ["Helmet (CSP, X-Frame-Options)", "CORS (credentials: true)", "Rate Limiting (1분 10000회)"],
        "sql_injection_prevention": "Parameterized Query"
      },
      "error_handling": {
        "postgres_error_codes": {
          "23505": "중복된 데이터",
          "23503": "참조 무결성 위반",
          "23502": "필수 입력값 누락"
        },
        "process_level": {
          "unhandledRejection": "로깅 (서버 유지)",
          "uncaughtException": "로깅 (서버 유지, 주의)",
          "SIGTERM/SIGINT": "Graceful Shutdown"
        }
      },
      "logging": {
        "library": "Winston",
        "log_files": {
          "error.log": "에러만 (10MB × 5파일)",
          "combined.log": "전체 로그 (10MB × 10파일)"
        },
        "log_levels": "error (0) → warn (1) → info (2) → debug (5)"
      },
      "performance_optimization": {
        "pool_monitoring": "5분마다 상태 체크, 대기 연결 5개 이상 시 경고",
        "slow_query_detection": "1초 이상 걸린 쿼리 자동 경고",
        "caching": "Redis (메뉴: 10분 TTL, 공통코드: 30분 TTL)",
        "compression": "Gzip (1KB 이상 응답, 레벨 6)"
      }
    },
    "critical_rules": [
      "✅ 모든 쿼리에 company_code 필터 추가",
      "✅ JWT 토큰에서 company_code 추출 (클라이언트 신뢰 금지)",
      "✅ Parameterized Query 사용 (SQL Injection 방지)",
      "✅ 슈퍼관리자 데이터 숨김 (company_code != '*')",
      "✅ 비밀번호는 bcrypt, 민감정보는 AES-256",
      "✅ 에러 핸들링 try/catch 필수",
      "✅ 트랜잭션이 필요한 경우 transaction() 사용",
      "✅ 파일 업로드는 회사별 디렉토리 분리"
    ]
  },
  "needs_from_others": [],
  "questions": []
}
