AxDbTool 프로젝트의 주요 변경 이력 및 개선 사항이 기록된 문서입니다.
Services/AuthService.cs, Models/User.cs):AuthService.DeleteUser(userId, adminId): 단일 사용자 및 해당 사용자의 모든 활성 세션(Sessions) 트랜잭션 기반 원자적 영구 삭제AuthService.DeleteUsers(userIds, adminId): 다중 사용자 일괄 삭제 및 BatchDeleteUsersRequest DTO 지원admin) 및 현재 로그인된 관리자 본인 계정은 삭제 대상에서 원천 차단(삭제 방어 검증)Controllers/AuthController.cs):DELETE /api/auth/users/{userId}: 관리자 권한 단일 사용자 영구 삭제POST /api/auth/users/batch-delete: 관리자 권한 다중 선택 사용자 일괄 삭제FileLoggingService) 기록wwwroot/index.html, wwwroot/js/auth.js):선택 삭제 (N) 버튼 추가체크박스 및 [삭제] 버튼 배치 (기본 관리자 및 본인 행은 체크박스 비활성화 및 삭제 버튼 미표시)showConfirm 확인 대화상자를 통한 오삭제 방지auth.js에 Auth.deleteUser, Auth.deleteUsers API 연동 및 삭제 완료 후 사용자 목록 자동 갱신sw.js):auth.js?v=1.12.12 갱신 및 CACHE_NAME을 axdbtool-sw-v1.12.12로 상향wwwroot/js/core/tab-manager.js):openTab, activateTab, closeTab, closeOtherTabs, closeTabsToLeft, closeTabsToRight, closeAllTabs) 캡슐화renderTabBar) 로직 캡슐화renderEmptyTabPlaceholder) 제어TableViewComponent, ScriptViewComponent, TableViewDiffComponent, ScriptViewDiffComponent) 동적 인스턴스화window.TabManager, window.openNewTab, window.activateTab, window.closeTab 전역 호환 바인딩 제공wwwroot/js/app.js):index.html, sw.js):index.html의 스크립트 태그 순서를 core/ -> modals/ -> views/ -> auth.js -> app.js로 최종 확정core/tab-manager.js 등록 및 CACHE_NAME을 axdbtool-sw-v1.12.11로 업데이트wwwroot/js/views/table-view.js):TableViewComponent 분리GridCellSelector 분리window.TableViewComponent, window.GridCellSelector 전역 노출로 탭 매니저와의 완벽한 연동 보장wwwroot/js/views/script-view.js):ScriptViewComponent 분리window.ScriptViewComponent 전역 노출wwwroot/js/views/diff-view.js):TableViewDiffComponent 분리ScriptViewDiffComponent 분리window.TableViewDiffComponent, window.ScriptViewDiffComponent 전역 노출wwwroot/js/app.js):app.js의 역할을 MDI 탭 라이프사이클 관리, 사이드바 내비게이션 바인딩, 초기화(initApp) 전용 오케스트레이터로 정제index.html, sw.js):index.html에 분리된 3개 뷰 모듈 스크립트 태그 등록CACHE_NAME을 axdbtool-sw-v1.12.10으로 업데이트wwwroot/js/core/state.js):app.js)에서 전역 상수(APP_CONFIG) 및 상태 관리 객체(AppState)를 독립 파일로 분리window.APP_CONFIG, window.AppState 네임스페이스 바인딩을 통한 하위 호환성 및 모듈 간 상태 공유 보장wwwroot/js/core/dom.js):app.js 내 정적 캐시되던 DOM 객체를 Getter 기반 동적 바인딩 구조로 개선하여 독립 파일로 분리wwwroot/js/core/utils.js):formatDataType, escapeHtml), 테마 관리(applyTheme, toggleTheme), 대화상자(showAlert, showConfirm) 분리downloadFileBlob, openFileInOs), 클립보드 복사(writeTextToClipboard, copyToClipboard) 분리showPrintPreview, savePrintPreviewToPdf), Monaco Editor 인라인 초기화(initMonaco) 분리auth.js에서 호출하던 escapeHtml, showAlert, showConfirm의 스크립트 선행 로드 보장wwwroot/js/modals/config-modal.js):ConfigModal 객체 캡슐화 및 window.* 하위 호환 헬퍼 함수 제공wwwroot/js/modals/table-data-modal.js):TableDataManager 객체 캡슐화 및 window.TableDataManager 전역 노출wwwroot/js/modals/print-modal.js):PrintModal 객체 캡슐화 및 window.PrintModal 전역 노출index.html, sw.js, app.js):index.html 및 sw.js 프리캐시 목록에 신규 3개 모달 모듈 등록 및 캐시 버스팅 파라미터(v=1.12.9) 동기화app.js에서 모달 로직 1,570여 라인을 안전하게 제거하여 파일 크기를 추가 경량화 (6,809줄 -> 5,946줄 -> 4,375줄, 누적 2,434줄 분리 달성)rawToken, 64자리)과 DB 저장용 SHA-256 해시(TokenHash), 관리용 세션 식별자(SessionId, UUID) 분리GET /api/auth/sessions) 시 쿠키 원본 토큰을 노출하지 않고 안전한 관리용 SessionId만 반환하도록 개선DELETE /api/auth/sessions/{id}) 시 관리용 SessionId를 기반으로 안전하게 파기 처리ConnectionController.TestConnection 호출 시 로컬 루프백(127.0.0.1, localhost, ::1), 와일드카드(0.0.0.0), 클라우드 메타데이터 및 링크-로컬 대역(169.254.0.0/16) 연결 즉시 차단Dns.GetHostAddressesAsync)을 수행하여 실제 IP 수준에서 루프백 및 메타데이터 주소 검증 강화429 Too Many Requests) 적용wwwroot/lib/ 디렉토리로 정적 번들링index.html 및 app.js(require.config)의 호출 경로를 로컬 상대 경로(/lib/...)로 전면 전환editor.main.css) 정적 헤더 연결 및 Diff Editor 변경점(추가/삭제) 시각적 색상 하이라이트 스타일(app.css) 보강dispose), 개행 정규화(\r\n -> \n) 및 테마 동기화 적용으로 차이점 색상 표시 정상화MonacoEnvironment 전역 설정(getWorkerUrl)을 CSP(worker-src 'self' blob:) 표준에 부합하는 Blob URL 방식으로 전환하고 Worker 스레드용 NLS 모듈(platform.nls.js, simpleWorker.nls.js, languages.nls.js) 정적 리소스를 구축하여, data: URI 보안 정책 위반 및 workerMain.js 언어 자원 로딩 404 오류(Failed trying to load default language strings) 원천 차단SystemController의 설정(settings) 및 로그(logs) 조회 시 웹 환경에서는 서버 물리 드라이브 경로(D:\...) 대신 가상 상대 경로(logs/)로 마스킹Content-Security-Policy (CSP): 로컬 번들링 완료에 따라 script-src 및 connect-src의 https: 와일드카드 출처 제거 및 'self' 기반 제한 강화X-XSS-Protection: 0: 최신 브라우저 보안 표준에 맞춰 Deprecated 헤더 비활성화 (CSP 대체)CORS: 개발(Development) 환경에서만 디버깅용 AllowAll을 허용하고 운영(Production) 환경에서는 비인가 Cross-Origin 요청 차단UseStaticFiles): .db, .json, .config, .log, .bat, .ps1, .sh, .md 및 숨김 파일(.*) 직접 다운로드 원천 차단 (404 반환)SystemController의 open-file, open-folder, save-file에 대해 AppEnvironment.IsStandalone 사전 검증 추가 (서버 환경 프로세스 실행 원천 차단)fe80::) 및 사이트-로컬 대역 SSRF 방어 강화[ ] 이름 불일치만):IsNameMismatch)를 추출하는 DbObjectNameExtractor 엔진 추가\p{L}) 및 유니코드 식별자, 공백/특수문자가 포함된 대괄호([...]), 쌍따옴표("..."), 백틱(` ... `) 식별자를 완벽하게 파싱할 수 있도록 정규표현식 및 객체명 분리 파서 전면 보강[ ] 이름 불일치만 체크박스를 추가하여 불일치 항목만 즉시 필터링 지원정의: [실제정의명])를 표시하여 원인 파악 용이nameMismatchOnly) 지원clearDetail)되도록 개선하고, 필터 결과 변경 시 첫 번째 항목 자동 선택 동기화 연동특정문구 입력란(TextBox)과 특정문구를 제외 체크박스(CheckBox) 신설textPattern, excludePattern) 및 SQL ESCAPE 안전 처리 적용app.js)에서 [특정문구를 제외] 체크박스 토글 및 특정문구 입력 시 실시간 클라이언트 필터링(renderScriptList) 및 자동 재조회 이벤트 연동loading-overlay) 추가collapsed)로 표시하도록 개선Table/View Diff 상단 유형(전체, 테이블, 뷰) 선택 시 좌측 목록 및 통계 카운트에 실시간 필터가 즉시 적용되도록 수정Script Diff 상단 객체 구분(Procedure, Function, Trigger, View, Package) 옵션 값 표준화 및 목록 렌더링 시 대소문자 무시 동의어 수용 필터링 연동build-packages.ps1 패키징 빌드 시 chgLog/CHANGELOG.md의 최신 버전 번호를 파싱하여 src/AxDbTool.Electron/package.json의 "version" 항목을 자동으로 동기화하도록 스크립트 기능 추가AppEnvironment.IsStandalone 및 --standalone 플래그 / 환경변수 연동ConnectionController 및 MetadataController에서 비-Standalone 환경의 SQLite 연결 테스트, 프로필 저장, 메타데이터 조회를 400 Bad Request로 안전하게 차단app.js)에서 Standalone 여부에 따라 DB 설정 폼 및 필터의 SQLite 옵션 비활성화(disabled), 시각적 뱃지 안내, 변경 시 경고 및 자동 롤백 처리AuthService.cs, CryptoService.cs):SystemController.cs):GET/POST /api/system/settings) 및 서버 로그 조회/초기화(GET/DELETE /api/system/logs) 엔드포인트에 관리자(Admin) 권한 검증 강제 적용 (비인가 사용자 403 차단)save-file), 탐색기 열기(open-folder), OS 파일 열기(open-file)에 대해 로컬 루프백(127.0.0.1, localhost) 요청만 허용하도록 격리하고 원격 웹 접속 환경에서는 403 Forbidden 차단 (Electron 로컬 데스크톱 전용 기능 제한).xlsx, .zip, .sql, .pdf, .json, .txt, .csv) 검증을 적용하여 실행 파일(.exe, .bat, .ps1 등) 저장 및 실행 절대 금지MetadataController.cs):MetadataController에 세션 사용자 컨텍스트(CurrentUser)를 주입하여 타 사용자의 비공개 DB 프로필에 대한 무단 메타데이터, DDL 및 데이터 조회 요청 원천 차단ConnectionController.cs, ProfileService.cs):GET /api/connection) 및 단일 프로필 상세 조회 시 클라이언트로 DB 접속 비밀번호를 평문 전송하지 않고 마스킹(••••••••)하여 전송save-all) 시 마스킹 상태이거나 빈 값인 경우 SQLite DB의 기존 암호를 안전하게 보존하고, 새 비밀번호를 입력한 경우에만 암호화하여 갱신test-connection) 시 비밀번호가 마스킹된 상태여도 서버 DB의 복호화된 기존 암호를 자동으로 조회하여 테스트함으로써 기존 화면의 모든 프로필 수정/테스트/저장 기능이 100% 정상 작동하도록 보장Program.cs, AuthController.cs):X-Forwarded-Proto: https) 환경에서 HSTS (Strict-Transport-Security: max-age=31536000; includeSubDomains) 헤더 자동 적용X-Content-Type-Options: nosniff (MIME 타입 스니핑 방지), X-Frame-Options: SAMEORIGIN (Clickjacking 방지), X-XSS-Protection: 1; mode=block, Referrer-Policy: strict-origin-when-cross-origin 전역 미들웨어 적용Secure 플래그 강제 적용MetadataController.cs, *Adapter.cs)**:table-data)의 WHERE 및 ORDER BY 절에 세미콜론(;)이 포함된 경우 400 Bad Request로 즉시 차단]), PostgreSQL("), MySQL(`` ``), Oracle("`) 식별자 이스케이프 정규화 강화nav-item-tableview-diff)ALTER TABLE ADD/MODIFY COLUMN, CREATE TABLE DDL 자동 생성 및 원클릭 클립보드 복사POST /api/export/table-diff-excel)nav-item-script-diff)POST /api/export/script-diff-excel)FormatDataType is not defined 예외 해결):formatDataType vs FormatDataType)를 해결하기 위해 FormatDataType 별칭을 전역 등록하고, precision/scale 정밀도 파라미터까지 유연하게 처리할 수 있도록 기능 보강DIFF)'으로 설정하던 로직을 제거하고, [비교 실행] 즉시 백그라운드 병렬 배치(Concurrency: 6)를 가동하여 모든 객체의 컬럼/인덱스 및 스크립트 소스를 자동 대조하도록 개선MATCH)' 상태로 분류되어 좌측 목록 및 통계 카운트가 실시간 동기화되며, 사전 캐시를 통해 테이블 클릭 시 0ms로 즉각 렌더링되도록 최적화 (Script Diff 동일 적용)z-[9999]) 최우선 노출 보장index.html 기본 마크업 및 renderEmptyTabPlaceholder 헬퍼 함수 적용)v1.9.8):app.js의 APP_CONFIG.VERSION을 v1.9.8로 갱신하여 헤더 버전 뱃지 및 변경 이력 모달에 최신 버전 자동 반영config/axdb.db):Users 및 Sessions 테이블 자동 생성 및 CryptoService(AES-256-CBC) 암호화 연동admin / admin1234) 자동 생성 및 초기 비밀번호 변경 강제 플래그(MustChangePassword) 적용axdb_session) 기반의 안전한 세션 토큰 체계 구축 (XSS 방어 및 브라우저/Electron 호환)AuthMiddleware를 통한 API 엔드포인트 보호 및 유효성 실시간 검증IsShared):config/connections.json 프로필 데이터를 SQLite Connections 테이블로 무손실 자동 마이그레이션 (connections.json.bak 백업 보관)Admin)는 전체 프로필에 대한 조회 및 일괄 관리 권한 보유modal-admin-panel):SystemSettings): 관리자 패널에서 세션 만료 시간(1시간~30일)을 실시간으로 선택 및 변경 적용할 수 있도록 설정 기능 추가 (GET/POST /api/auth/session-timeout)auth.js, app.js):z-[9999])으로 즉시 전환navigator.clipboard 미지원 및 비보안 컨텍스트 대응 (writeTextToClipboard):navigator.clipboard API는 보안 컨텍스트(HTTPS, localhost)에서만 활성화되므로 사내망 IP 접속이나 특정 브라우저/Electron 환경에서 undefined로 인식되어 발생하던 Cannot read properties of undefined (reading 'writeText') 오류 수정document.execCommand('copy') 기반의 투명 textarea 임시 생성 폴백(Fallback) 메커니즘을 내장한 안전한 writeTextToClipboard 비동기 헬퍼 함수 구현v1.9.6):app.js 상단에 APP_CONFIG.VERSION (v1.9.6) 단일 진실 공급원(Single Source of Truth)을 정의하고 화면 초기화(initApp) 시 헤더의 버전 뱃지(#app-version-badge)에 텍스트가 자동으로 주입/표출되도록 개선package.json), 통합 패키징 스크립트(build-packages.ps1, AxDbTool-Server-Setup.iss) 메타데이터 버전을 1.9.6으로 일괄 동기화MySqlAdapter에서 컬럼 메타데이터 조회 시 COLUMN_TYPE 전체 문자열(예: varchar(32))이 Length 필드로 매핑되어 화면 표시 시 varchar(varchar(32)) 형태로 중첩 표시되던 버그 수정COLUMN_TYPE에서 괄호 안의 순수 길이/정밀도 값만 추출하도록 어댑터 로직 개선app.js) 및 엑셀 내보내기(ExportService.cs)의 FormatDataType 함수에 중첩 괄호 및 중복 타입명 방어 정규화 로직 적용 (인쇄/미리보기 및 레이아웃 엑셀 저장 포함 전 영역 완벽 동기화)CHANGELOG.md를 스타일드 단독 문서(wwwroot/changelog.html)로 자동 변환하여 정적 리소스에 포함 (Convert-Changelog.ps1 연동)modal-changelog)으로 변경 이력 및 실시간 검색/필터링 기능 지원Enter(다음 일치 항목) 및 Shift + Enter(이전 일치 항목) 키 또는 상/하 탐색 버튼(▲, ▼)을 통한 순환 스크롤 및 현재 일치 순번/개수 뱃지 표출 지원showSaveDialog) 연동 및 백엔드(/api/system/save-file) 디스크 파일 쓰기/File.Exists 실제 존재 검증 후 열기 확인창 표출showSaveFilePicker 저장 후 getFile()을 통한 파일 인스턴스 및 크기 검증 후 열기 확인창 표출<a>) 환경: 웹 JS가 로컬 파일 실제 존재를 알 수 없는 상태에서 임의의 모달 확인창을 띄우지 않도록 억제하고 브라우저 다운로드 관리자로 일원화perMachine: true 및 productName: "AxDbTools" 설정을 적용하여 기본 설치 디렉터리를 C:\Program Files\AxDbTools로 지정allowToChangeInstallationDirectory: true 유지createDesktopShortcut: "always", createStartMenuShortcut: true, shortcutName: "AxDbTool" 적용으로 설치 완료 시 바탕화면 및 시작메뉴에 AxDbTool 바로가기 자동 생성<PublishReadyToRun>true</PublishReadyToRun>):SPLASH_HTML)을 표출하여 더블클릭 시 100ms 이내 즉각 반응500\text{ms}에서 100\text{ms} 초고속 폴링으로 단축하여 백엔드 준비 완료 즉시 화면 전환AxDbTool Setup 1.9.2.exe)과 무설치 Unzip 압축 해제형(AxDbTool-1.9.2-win.zip) 2종으로 패키지 구성 최적화 완료releases/standalone/):AxDbTool Setup 1.9.2.exe (NSIS 기반 설치 마법사, 시작메뉴/바탕화면 바로가기 지원)AxDbTool 1.9.2.exe (포터블 단일 실행 파일), AxDbTool-1.9.2-win.zip (압축 해제 후 즉시 실행)releases/server/):releases/server/windows/):AxDbTool-Server-Setup.iss (Inno Setup 스크립트), Install-Service.bat (Windows Service 자동 등록 및 방화벽 TCP 5000 허용), Uninstall-Service.bat (서비스 및 방화벽 제거)AxDbTool-Server-win-x64-1.9.2.zip (Self-Contained 바이너리, start-server.bat, appsettings.json 일체 포함)releases/server/linux/):install-service.sh (Systemd 자동 등록, UFW/Firewalld 포트 자동 개방), uninstall-service.shAxDbTool-Server-linux-x64-1.9.2.tar.gz, AxDbTool-Server-linux-x64-1.9.2.zip (start-server.sh, axdbtool.service 유닛 포함)build-packages.ps1, build-packages.bat):releases/ 디렉터리에 자동 출력src/AxDbTool.Electron 데스크톱 클라이언트)package.json, main.js, preload.js, README.md, .gitignore 생성spawn), 앱 종료 시 백엔드 자식 프로세스 자동 완전 종료(taskkill / SIGTERM)electron-builder 기반 Windows 설치형/포터블 빌드 스크립트 제공PK(기본키 시에만 표시), Null(NOT NULL 시에만 N 표시), 기본값(있을 때만 표시), 설명(있을 때만 표시)의 - 문자를 제거하고 빈 셀 처리Unique(UNIQUE), PK(PK)에 대해 미해당 항목은 공백 처리생성일시 미존재 시 공백 처리- 대체문자를 제거하고 값이 존재하는 셀만 표시하도록 통일PK, 기본값 열 정돈:PK 컬럼은 실제 기본키인 경우에만 PK를 표시하고, 기본키가 아닌 경우 빈 셀(- 제거)로 처리기본값 (DefaultValue) 열도 실제 정의된 기본값이 있는 경우에만 해당 값을 표시하고, 없는 경우 빈 셀(- 제거)로 처리PK, 기본값, 설명 열의 - 대체문자를 제거하고 값이 있을 때만 셀 값을 기록하도록 일치화Nullable 열 간소화:!isNullable)인 경우에만 강조된 N을 표시하고, NULL 허용 컬럼은 빈 셀로 정돈하여 직관적인 필수 입력 컬럼 식별 지원Null 열에 N인 항목만 볼드 표기하고 Y는 공백 처리bg-white dark:bg-slate-800, text-slate-700 dark:text-slate-200, border-slate-300) 및 Cyan 포인트 아이콘으로 개선하여 가독성과 심미성 향상ScriptViewComponent의 마크업 클래스인 .sv-script-tbody와 GridCellSelector 바인딩 시 탐색 클래스(.sv-grid-tbody)의 불일치로 인해 셀렉터 인스턴스가 생성되지 않던 문제를 해결하여 마우스 드래그 셀/블록 선택 및 Ctrl + C 클립보드 복사가 정상 동작하도록 수정Microsoft.Data.Sqlite 드라이버 및 SqliteAdapter 구현:.db, .sqlite, .sqlite3, :memory:)에 대한 접속 테스트, 테이블/뷰 목록, 컬럼/인덱스/트리거 메타데이터, 원본 DDL 스크립트 추출 및 데이터 그리드 조회/필터링 완벽 지원SQLite (.db, .sqlite) 항목 추가table-list-excel, script-list-excel) 추가:ExportController의 POST 엔드포인트 URL 불일치로 인해 발생하던 404 Not Found 및 엑셀 생성 실패 오류 수정ExportMultiTableLayoutToExcelAsync에서 [데이터타입]과 [길이/정밀도] 컬럼을 7개 표준 컬럼 명세서로 통합FormatDataType) 적용:int(10, 0) \rightarrow int, bigint(19, 0) \rightarrow bigint, datetime(23, 3) \rightarrow datetime, date(10) \rightarrow date, bit(1) \rightarrow bit 등 고정 크기 데이터타입의 불필요한 괄호/정밀도 생략 처리varchar(50), numeric(18, 2) 등 유효한 가변 길이/정밀도 지정은 그대로 유지데이터타입과 길이/정밀도 컬럼을 데이터타입(길이) 형태의 단일 컬럼(예: VARCHAR(50), NUMERIC(18,2))으로 통합하여 화면 공간 활용성 및 직관성 향상Ctrl + C 복사 연동:Ctrl + C (TSV 클립보드 복사), ESC 선택 취소 지원Ctrl + C 복사 연동:Ctrl + C 복사 지원ExportService의 테이블 목록 및 스크립트 목록 엑셀 생성기에 자동 열너비 클램핑 및 테마 스타일 헤더 적용 완료12\text{ch}, 최대 45\text{ch} 범위로 열 너비를 제한하여 엑셀 시트의 가독성 극대화calcCharWidth) 적용:\times 2.0)를 적용하여 텍스트 잘림 현상 방지wch, wpx, width) 동시 지원:wch)와 픽셀 단위(wpx), width를 모두 명시하여 자동 열너비가 100% 정상 반영되도록 개선Description), 2행에 영문 물리 컬럼명(ColumnName), 3행부터 실제 데이터 레코드가 저장되도록 분리ESC 키 2단계 동작 지원:ESC를 누르면 선택 영역만 우선 취소ESC를 누르면 모달 팝업 닫기Ctrl + C (Cmd + C) 클립보드 TSV 복사 지원:[X] 닫기 버튼 추가:[x] 버튼으로 자유롭게 닫을 수 있으며, 마지막 탭 닫기 시 모달 자동 종료 지원Description), 2줄: 컬럼명(ColumnName) 형식으로 구성하여 각 컬럼의 의미를 즉각 식별 가능Description, IsPrimaryKey) 실시간 매핑:GetTableDataAsync에서 카탈로그의 컬럼 코멘트를 조회하여 TableColumnMetadata에 자동 매핑 지원1240px \times 800px, 최대 화면 96vw \times 92vh):WHERE, ORDER BY 절 중복 키워드 및 식별자(대괄호, 백틱, 쌍따옴표) 이중 감싸기 방지ROWNUM <= N 쿼리 구문 정규화GetColumnSchemaAsync() 대신 reader.FieldCount, reader.GetName(), reader.GetDataTypeName() 표준 방식으로 전환하여 100% 안정성 확보escapeHtml 헬퍼 함수 추가:TableDataManager에서 HTML 특수문자 이스케이프 처리 시 발생하던 ReferenceError: escapeHtml is not defined 오류 수정#modal-table-data) 구현:[자료보기] 버튼 클릭 시 실행테이블/뷰명 [설명] (설명이 없는 경우 테이블/뷰명)▲/▼ 인디케이터 표시)NULL 값 연회색 [NULL] 배지 표시 및 PK/데이터타입 헤더 메타정보 표시[Excel 저장] 클릭 시 파일 저장 다이얼로그 오픈{탭제목}_{yyyyMMdd}.xlsx 자동 지정[복사] 버튼 클릭 시 TSV 포맷으로 클립보드 복사 지원GetTableDataAsync 및 GET /api/metadata/table-data API 추가h-12 (48\text{px})로 통일:h-6 \rightarrow h-8):24\text{px}에서 32\text{px}로 확장하고 텍스트 크기를 text-[11px]에서 text-xs로 개선하여 긴 메시지 및 작업 결과 상태 확인 시 시인성 대폭 향상[SQL 저장 ▾] 드롭다운 메뉴 적용:단일 SQL (.sql) 및 개별 SQL (.zip)을 동일한 드롭다운 메뉴 형식으로 통합 구성sv-filter-input) 추가:[SQL 저장 ▾] 버튼 클릭 시 나타나는 드롭다운 메뉴 내부에 불필요한 라벨 없이 오직 실행 대상인 단일 SQL (.sql)과 개별 SQL (.zip) 2개 항목만 깔끔하게 노출되도록 개선SQL 저장 ▾ 콤보박스 드롭다운(단일 SQL (.sql), 개별 SQL (.zip))으로 통합하여 툴바를 더욱 간결하고 직관적으로 개편searchKeyword)가 테이블/뷰 이름뿐만 아니라 코멘트/설명 컬럼에도 적용되도록 확장tv-filter-input) 기능 추가:cfg-test-status)를 배치하고, [접속 테스트 (Ping)] 버튼을 우측 끝으로 이동하여 일반적인 폼 액션 배치 표준 준수w-64)의 검색어 입력란 + DBMS 필터 + 상태 필터 배치[정렬] 드롭다운 & [그룹 뷰] 토글 버튼 + 우측 [가져오기], [내보내기], [프로필 저장] 버튼을 동일한 수평 라인에 나란히 배치h-7, inline-flex):h-7) 및 items-center로 통일하여 완벽한 수평 줄 맞춤 적용w-36 \rightarrow w-52):프로필명, 호스트, DB 검색...)w-[980px]로 여유 있게 확보하여 상단 툴바의 모든 필터 및 액션 버튼이 한 줄로 최적 배치되도록 개선flex-1, 최소 높이 min-h-[140px], resize-y 지원connections.json)에 영구 삭제 저장 및 UI 동기화space-y-2.5, gap-2.5, 비고 높이 h-16) 및 모달 크기(w-[940px] h-[680px]) 최적화로 불필요한 상하 스크롤바 제거confirm() 제거 및 전용 Confirm 모달 일원화:deleteCurrentConfigProfile) 및 오늘의 로그 비우기(clearTodayServerLogs) 시 브라우저 기본 팝업 대신 다크/라이트 테마가 적용된 일관된 커스텀 모달(showConfirm)로 확인 메시지를 표시하도록 개선grip-vertical)을 통해 마우스 드래그로 원하는 위치로 자유롭게 순서 변경 가능[프로필 저장] 시 connections.json에 그대로 반영되어 다음 실행 시에도 유지사용자 지정 순서 (Drag/Drop), 이름순 (A-Z / Z-A), DBMS 타입순, 사용 상태 우선#btn-cfg-import) 버튼 배치showOpenFilePicker) 및 파일 인풋 폴백을 통해 사용자가 JSON 파일을 선택하여 프로필 목록을 한 번에 불러와 그리드 및 편집 폼에 자동 반영app.js 내 DOM.mdiTabBar (#mdi-tab-bar) 및 DOM.mdiContentArea (#mdi-content-area) 참조 키를 정확한 ID로 수정하여 초기 탭 로드(openNewTab, renderTabBar) 시 발생하던 TypeError 해결showSaveFilePicker)를 통해 사용자가 원하는 경로와 파일명을 지정하는 '다른 이름으로 저장' 다이얼로그 호출 및 프로필 목록 JSON 파일 저장 지원<a> 태그 Blob 다운로드) 안전 폴백 처리config/ 디렉터리 분리 보관:.axdb_key (마스터 암호화 키), server_settings.json (시스템 설정), connections.json (DB 접속 프로필) 파일의 저장 위치를 프로그램 실행 디렉터리 하위의 config/ 폴더(AppDomain.CurrentDomain.BaseDirectory/config/)로 일원화%APPDATA%/AxDbTool 또는 실행 루트)에 저장되어 있던 설정 및 키 파일을 신규 config/ 디렉터리로 자동 마이그레이션(복사)하여 데이터 연속성 보장logs/ 디렉터리 보관 로직 보강:logs/ 디렉터리 자동 생성 및 일자별 로그 파일(axdb_yyyyMMdd.log) 저장 구조 확립Table/View Content, SP/FN Content, 인쇄 미리보기 PDF 저장 등 모든 파일 내보내기 작업 완료 시 화면 하단 상태바에 저장된 파일명을 칩 형태로 노출SystemController에서 Shell.Application Windows 셸 COM 인터페이스(Open(), ShellExecute())를 호출하여 저장된 폴더 및 실행 파일 창이 백그라운드가 아닌 사용자 화면 최상단(Foreground)으로 즉시 활성화되도록 개선Column, Index, Trigger 그리드의 <thead> 및 <tbody> 순번 컬럼 너비를 모두 50px 중앙 정렬로 완벽하게 일치시킴SystemController 내 Process.Start 호출 방식을 PowerShell Start-Process 기반으로 전면 교체하여 Windows 10/11 환경에서 파일 실행 및 탐색기 폴더 열기가 사용자 화면에 즉각 팝업되도록 개선SystemController 내 Process.Start 실패 시 cmd.exe /c start를 통한 다중 실행 폴백 적용exportTableList, exportSingleDdlSql, exportZipDdlSql)의 await 처리 보강으로 파일 저장 완료 후 후속 동작이 누락 없이 실행되도록 보장SystemController에 /api/system/open-file API 추가Process.Start(UseShellExecute = true)를 통해 사용자 PC의 OS 기본 연결 프로그램(Excel, PDF 뷰어, SQL/텍스트 에디터)으로 직접 실행개별 SQL): 저장 완료 시 Windows 탐색기를 통해 해당 저장 폴더를 즉시 열기"파일이 저장되었습니다. 파일을 여시겠습니까?" 확인 창 표시 후, [확인] 클릭 시 브라우저 새 탭/뷰어를 통해 파일 즉시 실행(열기)modal-alert 및 modal-confirm의 z-index를 z-[100]으로 지정하여 인쇄/미리보기 창(z-50) 및 설정 창(z-40) 위에서 항상 최상단에 메시지 창이 표시되도록 개선app.js의 DOM 캐시 객체에 modalConfirm 관련 요소 바인딩 추가showConfirm 함수 내 document.getElementById 및 브라우저 기본 다이얼로그 2중 안전 폴백 적용Merge)되어 긴 설명도 잘림 없이 온전히 표시SqlServerAdapter, PostgreSqlAdapter, OracleAdapter, MySqlAdapter의 GetTableDetailAsync에서 TableInfo의 메타데이터(Description, CreateDate, ModifyDate)를 누락 없이 채우도록 쿼리 보강 및 프론트엔드 폴백 병합 처리#F1F5F9 / #F8FAFC, 항목명 Bold, 중앙/좌측 정렬, 상태별 컬러링) 적용showSaveFilePicker) 지원html2canvas가 화면 밖 음수 좌표(left: -99999px)의 DOM 요소를 캡처할 때 캔버스가 빈 화면으로 렌더링되던 문제 해결DOM.printDocArea에 실시간 캡처용 pdf-render-mode 클래스를 순간 토글하여, 이미 렌더링된 본문 내용을 100% 온전히 유지하면서도 회색 배경/그림자 없이 순백색 A4 문서로 깨끗하게 캡처하도록 개선p-6 bg-slate-100, 스크롤바, 카드 그림자, 둥근 모서리)가 PDF 캡처 영역에 포함되던 현상 수정.print-paper) 요소만 추출하여 A4 규격 순백색(#ffffff) 전용 임시 캔버스에서 렌더링하도록 개선하여, 깔끔한 정통 A4 문서 본문만 100% 저장되도록 처리loader.min.js) 충돌 해결:define.amd 전역 함수로 인해 html2pdf가 전역 window 객체 대신 모듈 레지스트리에 가로채지던 현상 해결html2pdf.bundle.min.js를 Monaco 로더 이전(<head>)으로 이동시켜 전역 등록을 보장하고, ensureHtml2PdfLoaded에 Monaco require(['html2pdf']) 및 window.define 격리 로직을 완벽 적용ensureHtml2PdfLoaded) 적용:?v=...) 적용PDF 변환 라이브러리를 로드하지 못했습니다 오류 원천 차단favicon.ico 404 방지를 위한 인라인 SVG 파비콘 적용html2pdf.bundle.min.js 온전한 정품 바이너리 파일 교체 (905KB):Uncaught SyntaxError: Invalid or unexpected token 오류 완전 해결html2pdf.bundle.min.js 구문 오류 수정:Uncaught SyntaxError: Unexpected identifier 'Content' 및 PDF 변환 라이브러리를 로드하지 못했습니다 오류 완전 해결/js/html2pdf.bundle.min.js):cdnjs) 의존성을 제거하고 프로젝트 로컬 정적 자산 디렉터리로 완전히 내장PDF 변환 라이브러리를 로드하지 못했습니다 오류 없이 100% 안정적으로 PDF 파일 생성 및 저장 지원.xlsx).xlsx).sql).zip).pdf)Table/View, Script 인쇄 미리보기 팝업 헤더의 [인쇄 실행] 버튼 좌측에 초록색 [PDF 저장] 버튼 추가window.showSaveFilePicker) 연동으로 사용자가 원하는 폴더 및 파일명을 직접 선택하여 저장 가능 (미지원 브라우저는 자동 다운로드 폴백 지원)html2pdf.js 기반 고화질 A4 규격 렌더링, 페이지 나눔 및 SQL 구문 강조/테이블 서식 100% 보존textarea 높이를 h-32 (rows="6")로 확장하여 폼 내부의 여백을 균형 있게 활용하고 긴 메모도 쾌적하게 작성 가능하도록 개선{작업명} 중 오류가 발생했습니다. (예: 접속 테스트 중 오류가 발생했습니다., 프로필 저장 중 오류가 발생했습니다.)로 통일{작업명} 작업 중 오류가 발생했습니다. 형태로 간결하게 표시[추가], [삭제] 버튼 바와 동일한 높이와 스타일의 바텀 바(bg-slate-100 p-2)로 분리하여 완벽한 수평 일직선상으로 재배치ConnectionController: 접속 테스트(Ping) 실패/예외, 프로필 일괄 저장 성공/실패 로깅MetadataController: Table/View 목록 조회, Table/View 상세(컬럼/인덱스/트리거/DDL) 조회, Script 목록 및 소스 본문 조회 시 발생하는 모든 예외 파일 로깅ExportController: 단일/다중 Sheet Excel 생성, Script 목록 Excel, ZIP 압축 파일 생성 중 발생하는 모든 I/O 및 데이터 변환 예외 파일 로깅logs/axdb_yyyyMMdd.log에 자동 기록됨ConnectionController.cs에 FileLoggingService를 주입하여, 접속 테스트 실패 시 오류 사유(호스트, 포트, DB명, 에러 메시지)가 logs/axdb_yyyyMMdd.log 파일에 즉시 기록되도록 보완MetadataController.cs에도 로거를 추가하여 메타데이터 조회 예외 시 파일 로그 자동 기록<form> 제거 및 CSS Text-Security 마스킹 적용):<form> 태그를 제거하여 브라우저의 폼 제출 및 로그인 양식 감지 메커니즘을 무력화<input type="password"> 대신 type="text" + CSS -webkit-text-security: disc; 마스킹 기법을 적용하여 브라우저가 일반 텍스트 필드로 인식하도록 처리 (사용자 화면에는 ●●●● 마스킹 완벽 유지 및 눈 모양 아이콘 토글 정상 지원)User ID 및 Password 입력 폼에 autocomplete="new-password", autocomplete="off", data-lpignore="true", onsubmit="return false;" 및 휴리스틱 분산 속성을 적용하여, 브라우저가 웹사이트 로그인 양식으로 오인하여 비밀번호 저장 안내창을 띄우는 현상 완전 차단server_settings.json)에 영구 저장하여 다중 사용자 공유 환경에서도 전사 공통 적용logs/axdb_yyyyMMdd.log)GlobalExceptionMiddleware) 등록으로 서버 내 모든 예외 및 스택 트레이스 자동 수집192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12)만 웹 서비스 접근을 허용하는 보안 강화 규칙 수록 (Windows Defender, Ubuntu UFW, RHEL firewalld, Cloud Security Group)UFW 포트 허용 및 특정 서브넷 제한 명령어 수록firewalld 서비스/포트 및 Rich Rule 영구 허용 명령어 수록.pfx) 및 Kestrel 자체 SSL 엔드포인트 설정.crt/.key) 및 Let's Encrypt Certbot 자동 발급/갱신flex-1 min-h-0):downloadTextFile is not defined 참조 오류를 수정하여 단일 SQL 파일 다운로드가 정상 작동하도록 복구d.tableInfo 객체 속성 참조 시 발생하던 Cannot read properties of undefined 버그 해결 (대소문자 방어 로직 전면 적용).sql 단일 파일: 1개 선택/체크 시 {스키마}_{객체이름}.sql, 여러 개 시 {연결db명}_{구분}_{yyyyMMddHHmmss}.sql.zip 압축 파일: {연결db명}_{구분}_{yyyyMMddHHmmss}.zip (ZIP 내부 파일명: {스키마}_{객체이름}.sql)@media print 인쇄 시 상단부(제목, 요약정보)가 잘리던 CSS 마진/패딩 문제 해결isActive == true)인 프로필만 드롭다운에 표시되도록 필터링 적용Table/View 리스트: [체크], 구분, 스키마, 테이블/뷰 이름, 설명, 생성일시, 수정일시Script 리스트: [체크], 구분, 스키마, 객체 이름, 생성일시, 수정일시Table / View -> Table/ViewScript (SP/Fn/Trg) -> Script순번, 컬럼명, 설명, 데이터타입, 길이/정밀도, PK, Nullable, 기본값으로 재배치대상 컬럼을 마지막 컬럼으로 이동하고, PK 우선 및 인덱스명 오름차순으로 정렬단일 통합 SQL -> 단일 SQL로 명칭 통일Table / View (N))으로 계속 추가 생성되도록 개선DB 설정으로 통합getMonacoTheme 전역 스코프 정리 및 Monaco Editor 레이아웃 크기(layout()) 강제 재계산 로직을 통해 뷰어 초기화 오류 해결localStorage 테마 설정 저장 및 복원src/AxDbTool/).axdb_key) 자동 관리 모듈 (CryptoService.cs)connections.json 기반 데이터베이스 접속 프로필 CRUD 및 필터링 서비스 (ProfileService.cs)IDatabaseAdapter 공통 인터페이스 및 어댑터 팩토리 (DatabaseAdapterFactory.cs)SqlServerAdapter.cs - Microsoft.Data.SqlClient)PostgreSqlAdapter.cs - Npgsql)MySqlAdapter.cs - MySqlConnector)OracleAdapter.cs - Oracle.ManagedDataAccess.Core).xlsx) 생성 (ExportService.cs)tests/AxDbTool.Tests/CoreServicesTests.cs - 13개 전 항목 통과)