Commit Graph

60 Commits

Author SHA1 Message Date
gbpark 11d46c98bf chore: db/migration 의 legacy V001/V002 SQL 을 notes/ archive 로 이동
Build & Deploy to K8s / build-and-deploy (push) Successful in 7s
Flyway 가 V001 두 개 (기존 V001__create_ai_llm_providers + 새로 들어온 V001__varchar_migration) 를 충돌로 거부 → backend pod CrashLoopBackOff.
운영 schema 와 호환 검토 전까지 db/migration/ 밖으로 빼서 archive.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 07:04:09 +09:00
gbpark 80cd2b2d07 fix: e70267f73 에서 누락된 untracked 파일 추가
Build & Deploy to K8s / build-and-deploy (push) Failing after 3m8s
- frontend/components/layout/MenuItemActions.tsx — AppLayout/TopNavBar 가 import 하는데 빠져서 webpack 빌드 fail
- backend-spring db migration V001 (varchar_migration) + V002 (create_missing_tables) 같이 누락분 정리

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 06:22:02 +09:00
gbpark 3a0ab10ee6 Merge branch 'gbpark-node' of https://git.junggomoa.com/gbpark/invyone into gbpark-node
Build & Deploy to K8s / build-and-deploy (push) Successful in 4m51s
2026-05-03 01:29:07 +09:00
gbpark 7635412b7b feat: SCADA 시연용 모바일 알람 동반 화면 + Spring WebSocket
- 작업자 폰(/mobile)을 SCADA 데모와 ws 로 연결, 알람 발생 시 풀스크린 푸시
  · v5 솔리드+글로우 톤, 진동/Web Audio 비프/Wake Lock/auto reconnect
  · 시연 안전망: ?test=1 자동 발동, 우상단 hidden 트리거
- backend: com.erp.alarm 신규 패키지 (WebSocketConfig + Handshake + Handler + Controller)
  · JWT 토큰 핸드셰이크 검증, userId 기반 채널 매핑 (멀티 디바이스 지원)
  · spring-boot-starter-websocket 의존성 추가
  · path 를 /api/demo/* 안에 두어 Traefik 라우트 추가 불필요 + 정식 알람과 분리
- SCADA scenario.js 의 emergency 시퀀스(2700ms)에 fetch('/api/demo/alarm/trigger') 배선
  · /scada?worker=<user_id> query 로 target user 지정 (iframe src 로 전달)
- 운영 시연 URL: siflex.invyone.com/mobile (siflex_user) ↔ /scada?worker=siflex_user

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 01:18:12 +09:00
johngreen b999b425cb Merge pull request 'Sync main → gbpark-node: AI 모듈 JSONB 파싱 + audit-log fix' (#1) from main into gbpark-node
Build & Deploy to K8s / build-and-deploy (push) Successful in 4m31s
Reviewed-on: #1
2026-05-02 10:20:35 +00:00
johngreen 04cea72f33 fix(ai-modules): JSONB ::text 응답 자동 파싱 + workspace 카드 깨짐 수정
백엔드:
- 6개 AI Service (group/apiKey/provider/conversation/agent/scheduler) 가 응답 메서드에서
  `parseJsonField` 헬퍼로 JSONB(::text) 컬럼 (connectors / config / permissions /
  metadata / tool_calls / notification / tools) 을 String → Object 자동 변환.
- 모범 패턴 (`AuditLogService.processChanges`, `BusinessRuleService.parseJsonField`,
  `DataflowDiagramService.parseJsonbFields`) 동일하게 적용.
- model 의 String getter 는 그대로 유지 — `MultiAgentExecutionEngine` 등
  내부 LLM 호출 chain 영향 없음 (`getEntityById` 분리).
- 컨트롤러 시그니처 generic 만 변경 (return type Map).

프론트엔드:
- `safeArray<T>` / `safeObject<T>` 헬퍼 (`lib/utils.ts`) — 백엔드가 미파싱 String 으로
  올 때 graceful fallback. 빈 배열/객체 반환.
- `workspace/page.tsx` 멤버 카드:
  - `safeArray(member.connectors)` 적용 → `.map()` 폭발 차단.
  - 좁은 viewport 에서 한글 텍스트 한 글자씩 세로로 깨지던 문제 해결
    (`flex-wrap` + `truncate` + `whitespace-nowrap` + `max-w` + `title`).

그렘린 1000마리 폭격 + architect 자문으로 발견. workspace `Application error`,
`memberConnectors.map is not a function` 모두 해결.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 16:11:50 +09:00
johngreen 53f2638b82 fix(audit-log): URL 단/복수 + DB 컬럼명 + 응답 키 case 일괄 정정
- frontend `/audit-log` → 백엔드 `/audit-logs` (단/복수 mismatch)
- mapper auditLog.xml: `CREATED_DATE` → `CREATED_AT` (PostgreSQL 실제 컬럼명)
- AuditLogStats interface camelCase → snake_case (백엔드 응답 키 일치)

그렘린 카오스 테스트 + fetch hook 으로 발견. Application error / 500 / 404 모두 해결.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 16:11:26 +09:00
johngreen df9a539017 feat(template): 라이브러리 카드에 wireframe 썸네일 표시
Build & Deploy to K8s / build-and-deploy (push) Successful in 4m26s
템플릿 목록 카드의 정적 📋 아이콘을 실제 view 구조 기반의
미니 와이어프레임으로 교체. 사용자가 카드만 보고도 템플릿이
어떤 화면인지(테이블 위주 / 폼 위주 / 단순 버튼 등) 파악 가능.

- backend: getTemplateList SQL 에 VIEWS 컬럼 추가, list 응답 각
  row 의 views jsonb 를 객체로 파싱
- frontend: TemplateThumbnail 컴포넌트 신설 — v2(BlockV2.xPct/yPct
  /wPct/hPct) 정규화 좌표 우선, v1(order/row) 폴백, 컴포넌트
  종류별 색상(table=primary, form=cyan, button=pink)
- TemplateLibraryModal 카드 아이콘 자리 교체
- dashboard.css 에 .dash-lib-card-thumb / -block 스타일 추가
  (v5 토큰 준수 — solid + glow, blur 없음)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 08:00:10 +09:00
johngreen 1d37b8d2ea fix(ai-agent): list 쿼리가 archived(soft-delete) 행을 기본 제외하도록
Build & Deploy to K8s / build-and-deploy (push) Successful in 4m24s
증상: 에이전트 삭제 후에도 목록에 그대로 표시.
원인: softDelete 가 status='archived' 로만 변경하는데 list 쿼리가
status 필터 미지정 시 archived 도 모두 반환.

수정: status 명시 X 시 status != 'archived' 기본 적용. status 명시 시
그 값으로 정확 매칭.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 06:53:22 +09:00
johngreen 016442973e fix: ObjectMapper 에 JavaTimeModule 등록 (OffsetDateTime 직렬화)
Build & Deploy to K8s / build-and-deploy (push) Successful in 4m26s
증상: POST /api/ai-agents 가 500 으로 응답.
원인: 커스텀 @Bean ObjectMapper 가 Spring Boot 자동 모듈 등록을 가로
막아 java.time.OffsetDateTime (AiAgent.created_at/updated_at 등) 직렬화
실패. INSERT 자체는 성공했으나 응답 변환에서 깨짐.

- JacksonConfig: registerModule(new JavaTimeModule()) +
  WRITE_DATES_AS_TIMESTAMPS=false (ISO-8601 문자열 출력)
- GlobalExceptionHandler: 직전 디버그 메시지 노출 원복

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 06:41:15 +09:00
johngreen faa77160af debug: GlobalExceptionHandler 에 root cause 임시 노출
Build & Deploy to K8s / build-and-deploy (push) Successful in 4m31s
POST /api/ai-agents 가 500 만 반환하고 backend pod logs 직접 접근이
불가하여 진단 불가. 임시로 응답 message 에 [DEBUG] prefix + 예외
클래스명/메시지/cause 를 포함시켜 ULTRAQA 사이클로 root cause 파악.

⚠️ TEMPORARY — 안정화 후 다음 commit 에서 즉시 원복.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 06:34:48 +09:00
johngreen 552cb50bbd chore(db): 중복 'AI 어시스턴트' 자식 메뉴 비활성 (V016)
Build & Deploy to K8s / build-and-deploy (push) Successful in 4m28s
V014 가 AI_ASSISTANT_ROOT(부모) + AI_MENU_ASSISTANT(자식) 둘 다 동일
URL(/admin/aiAssistant)로 등록해 사이드바에 같은 이름 메뉴가 두 번
표시되던 증상 fix. V014 자체는 Flyway 체크섬 보호 때문에 수정하지
않고 후행 마이그레이션으로 soft-delete.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 21:19:28 +09:00
johngreen 7c57c69f84 fix: AiKnowledgeController 추가 (Epic C 누락분)
Build & Deploy to K8s / build-and-deploy (push) Successful in 4m33s
frontend 가 /api/ai-knowledge 호출하는데 backend 에 컨트롤러가 없어
"지식 파일 목록 로드 실패" 토스트가 나던 증상 fix.

서비스/매퍼/모델/DTO 는 이미 있고 컨트롤러만 누락이었음. 다른
ai 컨트롤러 (AiAgentController) 와 동일 패턴으로 GET/POST/PUT/DELETE
+ 멀티테넌시(company_code 필터, SUPER_ADMIN 예외) 적용.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 13:52:20 +09:00
johngreen 22d073f563 SecurityConfig: Spring Security 6 호환 필터 등록 순서 수정
Build & Deploy to K8s / build-and-deploy (push) Successful in 1m0s
기존 코드는 addFilterBefore(AiApi, JwtAuthenticationFilter.class) 가
jwt 등록 전에 호출되어 'JwtAuthenticationFilter does not have a
registered order' 예외 발생. Spring Security 6 부터 anchor 는 _이미
등록된_ 필터여야 함.

수정: jwt 를 UsernamePasswordAuthenticationFilter 기준으로 가장 먼저
등록 → JwtAuthenticationFilter.class 가 known map 에 추가됨 →
이후 SubdomainResolver/AiApiKey/TenantConsistency/ForcePw 가 jwt 를
anchor 로 정상 참조.

실행 순서는 동일: SubdomainResolver → AiApiKey → Jwt → TenantConsistency
→ ForcePw → UsernamePasswordAuthenticationFilter

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 08:35:08 +09:00
johngreen 7e3e4078d0 flyway: out-of-order=true 안전망 추가
Build & Deploy to K8s / build-and-deploy (push) Failing after 3m34s
운영 DB flyway_schema_history 가 baseline + V015 만 가진 상태에서
V001~V014 가 누락되어 있던 사고를 정리한 후, 향후 비슷한 누락이
있어도 자동 복구 가능하도록 out-of-order 허용.

전제: 운영 DB 의 V015 row 는 별도로 DELETE 처리하여 baseline 만
남겨둔 상태. 다음 부팅에서 V001~V015 가 차례로 적용된다.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 08:28:05 +09:00
Johngreen 52386efb83 도메인 정리: invion.com → invyone.com 전체 일괄 치환 + 매핑 문서화
Build & Deploy to K8s / build-and-deploy (push) Has been cancelled
운영 도메인이 실제로는 v1.invyone.com / solution.invyone.com / api.invyone.com 인데
코드/문서 곳곳에 v1.invion.com / api.invion.com 등 미존재 도메인이 박혀 있어 정리.

변경 파일 (21):
- frontend lib/api/client.ts, lib/utils/apiUrl.ts: hostname 체크 endsWith(\".invyone.com\") 일반화
- frontend lib/api/dashboard.ts, file.ts, flow.ts, FileViewerModal*2.tsx: 도메인 치환
- frontend invion-layout-v5.html: 시안 내 placeholder 도메인 정리
- backend-spring SecurityConfig.java: CORS 주석 예시 정리
- docker/deploy/docker-compose.yml, k8s/traefik-dynamic.yaml: traefik Host 라벨 정리
- scripts/prod/deploy.sh: 안내 메시지 정리
- .cursor/rules/api-client-usage.mdc, project-conventions.mdc: AI 가이드 정리
- docs/* 4개: 아키텍처/플로우 문서 도메인 정리
- notes/gbpark/* 3개: 과거 메모 정리

신규:
- docs/DOMAIN_MAPPING.md: 운영/개발/폐기 도메인 영구 기록.
  AI 에이전트와 신규 개발자가 헷갈리지 않도록 단일 진실 출처.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 07:39:04 +09:00
Johngreen 4306fa6f4b AI 메뉴 슈퍼관리자 권한 자동 매핑 (V015)
Build & Deploy to K8s / build-and-deploy (push) Failing after 3m30s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 05:44:38 +09:00
Johngreen 229b09b895 AI관리 시스템 교체: ai-assistant 제거 + 멀티 에이전트 오케스트레이션 이식
Build & Deploy to K8s / build-and-deploy (push) Failing after 7m14s
Epic A: ai-assistant 디렉토리/Spring 프록시/프론트엔드 메뉴 완전 제거
Epic B: Flyway 도입 + 13 신규 테이블 마이그레이션
Epic C: 9 서비스 + 7 컨트롤러 + LlmClient 추상화 (Java 21/Spring/MyBatis)
Epic D: ApiKey 인증 필터 (sk-pipe-* 키 SHA-256 검증)
Epic E: OpenClaw 외부 엔진 docker-compose 통합
Epic F: Next.js 7 페이지 + lib/api/aiAgent.ts 이식
Epic G: 화면 그룹/메뉴 등록 마이그레이션 (V014)
Epic H: 통합 빌드 검증

- DB: invyone PostgreSQL에 ai_agents/ai_agent_groups/... 13 테이블 + Quartz
- 멀티테넌시: 모든 테이블에 company_code 강제 필터
- LLM: Anthropic/OpenAI/Google/Ollama 직접 클라이언트 (Spring AI 미도입)
- 스케줄러: Quartz JDBC JobStore (cron 기반)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 22:49:43 +09:00
chpark 30ab45a3c6 admin/userMng 전체폭 사용 + 부서관리 dept_info 스키마 풀 매핑
Build & Deploy to K8s / build-and-deploy (push) Successful in 4m27s
화면 폭:
- 4개 페이지(사용자/권한 그룹/권한/부서) max-w 제거 → 화면 전체 사용
- 헤더 텍스트 컴팩트화 (text-xl + 작은 설명문)

부서관리 dept_info 스키마 1:1 매핑:
- 누락 필드 6개 추가: master_sabun, master_user_id, location, location_name, data_type, sales_yn
- frontend types/department.ts: Department / DepartmentFormData 확장
- frontend deptMngList: 폼 추가 + handleSelectDepartment / payload 매핑
- backend mapper: INSERT/UPDATE에 6개 컬럼 추가
- backend DepartmentService: insertParams/updateParams에 6개 필드 추가

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 17:20:46 +09:00
gbpark 2431451cef 예약 서브도메인에서 dev 제거 — 본섭 테스트 테넌트 용도 허용
Build & Deploy to K8s / build-and-deploy (push) Successful in 4m30s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 16:11:48 +09:00
gbpark 5af633d251 체크
Build & Deploy to K8s / build-and-deploy (push) Successful in 6s
2026-04-25 15:54:16 +09:00
gbpark 68f85f3736 회사 관리 기능 확장 + 테넌트/비번 보안 하드닝
- 첫 로그인 비번 강제 변경 (RUN_082): FORCE_PASSWORD_CHANGE 컬럼,
  ForcePasswordChangeGuardFilter, /auth/change-password API + 페이지
- 테넌트 일관성 가드: TenantConsistencyGuardFilter 로 JWT.company_code
  ↔ 서브도메인 company_code 대조, CompanyResolver 가 (db_name, company_code)
  동시 반환
- 회사 관리 확장 (RUN_083 audit log, RUN_084 lifecycle 컬럼):
  CompanyAdmin/Members/Templates/Lifecycle/AuditLog 서비스 +
  CompanyMgmtController + SuperAdminGuard
- 회사 관리 UI: CompanyAccordionRow 탭화 + 모달 4종
  (AdminInfo/Deactivate/Delete/RecopyTemplates) + AuditLogDrawer + csvExport
- 프로비저닝 마법사: force_password_change 토글 반영
- 프론트 인증: storage 이벤트 멀티탭 동기화, 403 errorCode
  (PASSWORD_CHANGE_REQUIRED / CROSS_TENANT_REJECTED / TENANT_NOT_RESOLVED)
  전역 리다이렉트
- 기타: StartupSchemaMigrator, OS별 도커 기동 스크립트, CLAUDE.md 트래킹

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 00:36:05 +09:00
gbpark 6d4f486e35 DB 비밀번호 회전
Build & Deploy to K8s / build-and-deploy (push) Successful in 6s
2026-04-24 19:40:17 +09:00
gbpark 5812925929 테넌트 서브도메인 존재 검증 Guard 추가
Build & Deploy to K8s / build-and-deploy (push) Failing after 3m6s
- 백엔드 TenantController: GET /api/tenant/check?subdomain=xxx
  (메타 DB 강제 라우팅 + CompanyResolver 로 존재 여부 반환)
- frontend/lib/tenant/subdomain.ts: 호스트 파싱 + 예약어(solution/www/admin 등) 제외
- TenantGuard 클라이언트 컴포넌트: layout.tsx 에서 wrap,
  sessionStorage 로 같은 서브도메인 재체크 방지
- /tenant-not-found 페이지: v5 solid+glow 스타일

등록되지 않은 서브도메인 접속 시 즉시 /tenant-not-found 로 리다이렉트.
2026-04-24 19:27:52 +09:00
gbpark 76f43cea9b DB 이름 vexplor → invyone 전환
Build & Deploy to K8s / build-and-deploy (push) Successful in 4m30s
- application.yml, k8s configmap, docker-compose 4종: SPRING_DATASOURCE_URL path
- provisioning 코드: {prefix}_vexplor → {prefix}_invyone 테넌트 DB 네이밍 규칙
- 프론트 마법사: Step1Basic, Step4Run 미리보기 라벨
- CompanyAccordionRow: 기본 DB 이름 포맷
- 마이그레이션/멀티테넌시 문서 동기화
- Traefik 와일드카드 설정 산출물 보관 (notes/)

비밀번호(vexplor0909!!) 및 역사 기록 문서(INVYONE_CONCEPT,
DDD1542, test-output, dashboard-runtime-fixes) 는 의도적으로 미변경.
2026-04-24 19:15:06 +09:00
gbpark 8c861144dc 서브도메인 배포 작업
Build & Deploy to K8s / build-and-deploy (push) Successful in 6s
2026-04-24 17:49:16 +09:00
gbpark 8be7e16e56 서브도메인설정
Build & Deploy to K8s / build-and-deploy (push) Successful in 4m28s
2026-04-24 04:56:40 +09:00
DDD1542 3eda684787 사용자 대시보드 기능강화 및 인비온 스튜디오 메뉴관리 자잘한수정
Build & Deploy to K8s / build-and-deploy (push) Successful in 4m22s
2026-04-22 18:27:06 +09:00
chpark 2c57dc8cda 부서 권한 그룹 권한 관리
Build & Deploy to K8s / build-and-deploy (push) Successful in 7s
2026-04-22 03:16:38 +09:00
gbpark b3ad787179 대시보드 구현 완료 세세한 오류 수정 진행중
Build & Deploy to K8s / build-and-deploy (push) Successful in 5m4s
2026-04-19 21:15:25 +09:00
gbpark 937505ab28 Merge remote-tracking branch 'origin/gbpark-node' into gbpark-node
Build & Deploy to K8s / build-and-deploy (push) Successful in 7s
2026-04-16 00:35:50 +09:00
gbpark de7ab9b7e3 중간세이브 - 메뉴수정 - INVYONE 스튜디오 작업 2026-04-16 00:32:19 +09:00
chpark 39fdc2683e fix: selectCompanyName LIMIT 1 추가 및 K8s 배포 설정 추가
Build & Deploy to K8s / build-and-deploy (push) Failing after 7s
2026-04-11 17:09:40 +00:00
gbpark 9c36191ebf 중간 세이브 2026-04-10 13:33:37 +09:00
gbpark 4603ac7fd6 디자인 수정 2026-04-08 02:27:27 +09:00
gbpark db8df83b31 node 업그레이드-->25 이전 서버설정 cash문제 해결. 2026-04-08 01:10:59 +09:00
gbpark 5bcff2db4d 123 2026-04-07 23:25:25 +09:00
gbpark 7c0b8c80fe 123 2026-04-06 15:54:35 +09:00
gbpark de24fb09d5 123 2026-04-06 15:54:31 +09:00
DDD1542 87498b9940 Refactor code structure for improved readability and maintainability 2026-03-31 09:34:54 +09:00
DDD1542 7529c3ff9e [agent-pipeline] pipe-20260329160157-3bqb round-1 2026-03-30 02:26:40 +09:00
DDD1542 b7f9e51d62 [agent-pipeline] pipe-20260328153638-axu2 round-1 2026-03-29 01:52:38 +09:00
DDD1542 8695be1a8d [agent-pipeline] pipe-20260328115913-ckmt round-1 2026-03-28 21:20:26 +09:00
DDD1542 d3c62f0bc1 [agent-pipeline] pipe-20260328094842-38e9 round-1 2026-03-28 19:10:09 +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 8f61c49f19 [agent-pipeline] pipe-20260328071539-8dqp round-1 2026-03-28 16:18:09 +09:00
DDD1542 941cde1962 [agent-pipeline] pipe-20260328055039-5mki round-3 2026-03-28 15:32:02 +09:00
DDD1542 9ca163c5cd [agent-pipeline] pipe-20260328055039-5mki round-2 2026-03-28 15:27:42 +09:00
DDD1542 21e30e5f60 [agent-pipeline] pipe-20260328055039-5mki round-1 2026-03-28 15:14:38 +09:00