Commit Graph

12 Commits

Author SHA1 Message Date
johngreen 1e1b3e103c fix(테이블타입): constraints SQL ARRAY_AGG → text 캐스트로 일원화
이전 PR (#15) 의 Java parseColumnArray 분기 추가가 실제 운영 환경에서
빈 배열을 그대로 반환 — MyBatis ↔ PostgreSQL JDBC 의 array 타입 변환이
java.sql.Array 가 아닌 다른 경로로 도착하는 듯.

방식 변경: SQL 단에서 ARRAY_AGG(...)::text 캐스트 → PostgreSQL 가
"{email,phone}" String 으로 반환. parseColumnArray 의 기존 String 분기
(중괄호 제거 + 쉼표 split) 가 자연스럽게 처리.

장점:
- JDBC 드라이버 / MyBatis 변환 동작에 의존하지 않음
- parseColumnArray 코드 단순 복원 (List/String 2분기)
- 한 줄 SQL 변경으로 PK/IDX 두 쿼리 모두 해결

검증:
- gradle compileJava BUILD SUCCESSFUL
- solution.invyone.com 에서 customer_mng PK columns / email IDX columns
  비어있지 않음 확인 예정

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 09:18:26 +09:00
johngreen 0365b743f5 fix(테이블타입): constraints API PgArray 디코딩 + primary_key key 매칭
테이블 타입 관리 페이지에서 PK/IDX 토글 후 UI 상태가 갱신되지 않던 버그.

1. Backend: TableManagementService.parseColumnArray
   - PostgreSQL ARRAY_AGG 가 java.sql.Array (PgArray) 로 오는데
     List/String 만 처리해서 항상 List.of() 반환 → columns 빈 배열
   - 조치: java.sql.Array 분기 추가, arr.getArray() → Object[] → List<String>

2. Frontend: loadConstraints
   - 백엔드는 result.put("primary_key", ...) 로 snake_case 반환
   - 프론트가 data.primaryKey 로 camelCase 로 읽어 undefined → 항상 빈 PK
   - 조치: data.primary_key 로 통일

이전 PR (#14) 의 IDX payload 수정과 합쳐, PK/IDX 토글이 API 호출/DB 적용/
UI 반영까지 한 사이클로 동작.

검증:
- gradle compileJava BUILD SUCCESSFUL
- solution.invyone.com 에서 IDX 토글 양방향 확인 예정

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 08:32:48 +09:00
johngreen efea906ead security(테이블타입): TableManagementController 인가 + createLogTable SQL injection 강화
bug hunt security-reviewer 발견 2건 보안 fix:

1. TableManagementController 인가 누락 (OWASP A01 Broken Access Control)
   - 15개 write/DDL endpoint 가 admin role 검증 없이 JWT 만 있으면 호출 가능
   - 일반 사용자가 PK 재설정/index 변경/컬럼 수정 가능했음
   - 조치:
     - DepartmentController 의 isAdmin/isSuperAdmin helper 패턴 복사
     - SUPER_ADMIN 전용 (DDL 5건): primary-key, indexes, nullable, unique, log
     - admin (COMPANY_ADMIN+) (10건): updateColumnSettings, addTableData, editTableData, deleteTableData, multi-save 등
     - read 19건은 그대로 (일반 사용자 접근 유지, company_code 격리만)

2. createLogTable SQL injection (OWASP A03 Injection)
   - information_schema.data_type 을 raw concat 으로 DDL 생성
   - 조치:
     - ALLOWED_LOG_COLUMN_TYPES Set 으로 화이트리스트 (varchar/text/integer/numeric/boolean/date/timestamp/jsonb 등 21개)
     - sanitize 빈 식별자 차단 + 원본 테이블에 없는 컬럼 skip
     - colDefs empty 시 IllegalArgumentException
     - 알 수 없는 type 은 text 로 안전 대체

검증:
- gradle compileJava BUILD SUCCESSFUL
- mapper XML 0건 변경 (READ 경로 보호)
- 별도 미해결 보안 이슈 (k8s secrets git 노출, CORS 와일드카드 등) 는 본 PR scope 외

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 18:07:40 +09:00
johngreen 574319811c refactor(테이블타입): backend INSERT/UPDATE 8개 validate 백스톱
- TableManagementService.normalizeInputType(value, context) 오버로드 — user-insert/user-update-type 만 8개 검증, user-update-other/system-normalize 는 skip
- TableManagementService.updateColumnSettings: payload 의 input_type 키 존재 여부로 context 분기 (input_type 자체 변경 vs 다른 속성 변경)
- DdlService.addColumn / saveColumnMetadata: convertToInputType 결과를 USER_SELECTABLE_INPUT_TYPES (8개) 와 대조, 외이면 IllegalArgumentException

mapper XML 5곳 (categoryTree / entityJoin / tableCategoryValue / screenManagement / tableManagement / entityReference) 무변경 — READ 경로 12개 그대로.

spec: .omc/specs/deep-dive-table-type-storage-ui-separation.md (v3.2 §6.3)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:43:41 +09:00
DDD1542 87498b9940 Refactor code structure for improved readability and maintainability 2026-03-31 09:34:54 +09:00
DDD1542 b7f9e51d62 [agent-pipeline] pipe-20260328153638-axu2 round-1 2026-03-29 01:52:38 +09:00
DDD1542 dc035667e8 [agent-pipeline] pipe-20260328092322-vevu round-1 2026-03-28 18:38:49 +09:00
DDD1542 a7c9ba2982 [agent-pipeline] pipe-20260328071539-8dqp round-2 2026-03-28 16:24:36 +09:00
DDD1542 21e30e5f60 [agent-pipeline] pipe-20260328055039-5mki round-1 2026-03-28 15:14:38 +09:00
DDD1542 1c324e4487 [agent-pipeline] pipe-20260327131904-jedw round-5 2026-03-28 00:01:33 +09:00
DDD1542 c73628e57a [agent-pipeline] pipe-20260327131904-jedw round-2 2026-03-27 23:23:52 +09:00
DDD1542 3923dbefa0 [agent-pipeline] pipe-20260327053504-cc40 round-2 2026-03-27 18:11:56 +09:00