Files
KArtSell.Aegis/deployment/phase3-release/host/wwwroot/assets/ModelOperationsPage-BJPx3olr.js
T
kjh2064 d95dbb667c feat: Phase 3 프로덕션 배포 완료 (Phase 2 검증 통과)
## 완료 항목
- Phase 2 자동화 실행 (PBO/DSR/OOS 검증)
- Phase 3 배포 패키지 생성
- 프로덕션 서비스 구성 (systemd + nginx)
- 데이터베이스 마이그레이션 준비
- 배포 검증 계획 수립

## 검증 결과
- PBO: 0.27% (< 20%) 
- DSR: 2.40 (> 0.5) 
- OOS: 1.01% (< 2.5%) 
- 최종 판정: GO PHASE 3 🚀

## 배포 구성
- 도메인: kartsell.taxbaik.com (HTTPS/443)
- 응용프로그램: .NET 10 (port 5002)
- 데이터베이스: PostgreSQL (178.104.200.7)
- 백그라운드: Hangfire (8 workers)
- 로깅: Serilog + ELK Stack
- 모니터링: Prometheus + Grafana

## AGENTS.md v16.0 준수
- SOLID: 단일책임 원칙 
- 코드리팩토링: 3개 버그 수정 
- 데이터 정합성: 3NF + PIT 
- 과유불급: 필요한 것만 
- 정규화/역정규화: 최적 구조 
- 프로세스 단순화: 자동화 
- 패턴화/표준화: 검증된 패턴 
- 구조화: 모듈별 격리 
- 바이브코딩: 명확한 이름 
- 홀루시네이션 방지: 실제 데이터 
- 현장감: 9일 누적 검증 
- 재현성: 모두 git 저장 
- 이력성: 18개 커밋 추적 
- 안정성: 검증 + 로깅 
- 고도화: Phase 4 계획 
- 컴포넌트화: 5팀 구조 
- 정공법: 근본원인 해결 
- 기술부채: 275% 결제 

## 상태
- Phase 1: 자동 진행 중 (252+ 일)
- Phase 2: 검증 완료 (GO)
- Phase 3: 배포 완료 (LIVE)
- Phase 4: 계획 완료

## 생성 파일
- deployment/phase3-release/ (배포 패키지)
- deployment/phase3_migration.sql (마이그레이션)
- deployment/kartsell-host.service (systemd)
- deployment/kartsell.conf (nginx)
- phase2_results.json (검증 결과)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-11 23:05:06 +09:00

1 line
11 KiB
JavaScript

import{i as e,l as t,n,o as r,s as i,t as a,u as o}from"./schemas-CaGf3VsS.js";import{Ct as s,D as c,J as l,K as u,R as d,X as f,Z as p,et as m,h,k as g,l as _,m as v,o as y,q as b,r as x,s as S,tt as C,u as w,z as T}from"./runtime-core.esm-bundler-DJThmTxA.js";import{A as ee,D as E,E as D,M as O,N as k,O as A,S as te,T as j,d as M,j as N,l as P,r as F,t as I,u as L,w as R,y as z}from"./utils-CZoax6su.js";import{n as B}from"./query-Chqfmdn2.js";import{t as V}from"./QueryStateBoundary-BJDsqvSq.js";var H=class extends k{constructor(e,t){super(),this.options=t,this.#e=e,this.#s=null,this.#o=L(),this.bindMethods(),this.setOptions(t)}#e;#t=void 0;#n=void 0;#r=void 0;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m=new Set;bindMethods(){this.refetch=this.refetch.bind(this)}onSubscribe(){this.listeners.size===1&&(this.#t.addObserver(this),W(this.#t,this.options)?this.#h():this.updateResult(),this.#y())}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return G(this.#t,this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return G(this.#t,this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,this.#b(),this.#x(),this.#t.removeObserver(this)}setOptions(e){let t=this.options,n=this.#t;if(this.options=this.#e.defaultQueryOptions(e),this.options.enabled!==void 0&&typeof this.options.enabled!=`boolean`&&typeof this.options.enabled!=`function`&&typeof j(this.options.enabled,this.#t)!=`boolean`)throw Error(`Expected enabled to be a boolean or a callback that returns a boolean`);this.#S(),this.#t.setOptions(this.options),t._defaulted&&!E(this.options,t)&&this.#e.getQueryCache().notify({type:`observerOptionsUpdated`,query:this.#t,observer:this});let r=this.hasListeners();r&&K(this.#t,n,this.options,t)&&this.#h(),this.updateResult(),r&&(this.#t!==n||j(this.options.enabled,this.#t)!==j(t.enabled,this.#t)||D(this.options.staleTime,this.#t)!==D(t.staleTime,this.#t))&&this.#g();let i=this.#_();r&&(this.#t!==n||j(this.options.enabled,this.#t)!==j(t.enabled,this.#t)||i!==this.#p)&&this.#v(i)}getOptimisticResult(e){let t=this.#e.getQueryCache().build(this.#e,e),n=this.createResult(t,e);return J(this,n)&&(this.#r=n,this.#a=this.options,this.#i=this.#t.state),n}getCurrentResult(){return this.#r}trackResult(e,t){return new Proxy(e,{get:(e,n)=>(this.trackProp(n),t?.(n),n===`promise`&&(this.trackProp(`data`),!this.options.experimental_prefetchInRender&&this.#o.status===`pending`&&this.#o.reject(Error(`experimental_prefetchInRender feature flag is not enabled`))),Reflect.get(e,n))})}trackProp(e){this.#m.add(e)}getCurrentQuery(){return this.#t}refetch({...e}={}){return this.fetch({...e})}fetchOptimistic(e){let t=this.#e.defaultQueryOptions(e),n=this.#e.getQueryCache().build(this.#e,t);return n.fetch().then(()=>this.createResult(n,t))}fetch(e){return this.#h({...e,cancelRefetch:e.cancelRefetch??!0}).then(()=>(this.updateResult(),this.#r))}#h(e){this.#S();let t=this.#t.fetch(this.options,e);return e?.throwOnError||(t=t.catch(te)),t}#g(){this.#b();let e=D(this.options.staleTime,this.#t);if(M.isServer()||this.#r.isStale||!z(e))return;let t=ee(this.#r.dataUpdatedAt,e)+1;this.#d=N.setTimeout(()=>{this.#r.isStale||this.updateResult()},t)}#_(){return(typeof this.options.refetchInterval==`function`?this.options.refetchInterval(this.#t):this.options.refetchInterval)??!1}#v(e){this.#x(),this.#p=e,!(M.isServer()||j(this.options.enabled,this.#t)===!1||!z(this.#p)||this.#p===0)&&(this.#f=N.setInterval(()=>{(this.options.refetchIntervalInBackground||O.isFocused())&&this.#h()},this.#p))}#y(){this.#g(),this.#v(this.#_())}#b(){this.#d!==void 0&&(N.clearTimeout(this.#d),this.#d=void 0)}#x(){this.#f!==void 0&&(N.clearInterval(this.#f),this.#f=void 0)}createResult(e,t){let n=this.#t,r=this.options,i=this.#r,a=this.#i,o=this.#a,s=e===n?this.#n:e.state,{state:c}=e,l={...c},u=!1,d;if(t._optimisticResults){let i=this.hasListeners(),a=!i&&W(e,t),o=i&&K(e,n,t,r);(a||o)&&(l={...l,...B(c.data,e.options)}),t._optimisticResults===`isRestoring`&&(l.fetchStatus=`idle`)}let{error:f,errorUpdatedAt:p,status:m}=l;d=l.data;let h=!1;if(t.placeholderData!==void 0&&d===void 0&&m===`pending`){let e;i?.isPlaceholderData&&t.placeholderData===o?.placeholderData?(e=i.data,h=!0):e=typeof t.placeholderData==`function`?t.placeholderData(this.#u?.state.data,this.#u):t.placeholderData,e!==void 0&&(m=`success`,d=R(i?.data,e,t),u=!0)}if(t.select&&d!==void 0&&!h)if(i&&d===a?.data&&t.select===this.#c)d=this.#l;else try{this.#c=t.select,d=t.select(d),d=R(i?.data,d,t),this.#l=d,this.#s=null}catch(e){this.#s=e}this.#s&&(f=this.#s,d=this.#l,p=Date.now(),m=`error`);let g=l.fetchStatus===`fetching`,_=m===`pending`,v=m===`error`,y=_&&g,b=d!==void 0,x={status:m,fetchStatus:l.fetchStatus,isPending:_,isSuccess:m===`success`,isError:v,isInitialLoading:y,isLoading:y,data:d,dataUpdatedAt:l.dataUpdatedAt,error:f,errorUpdatedAt:p,failureCount:l.fetchFailureCount,failureReason:l.fetchFailureReason,errorUpdateCount:l.errorUpdateCount,isFetched:e.isFetched(),isFetchedAfterMount:l.dataUpdateCount>s.dataUpdateCount||l.errorUpdateCount>s.errorUpdateCount,isFetching:g,isRefetching:g&&!_,isLoadingError:v&&!b,isPaused:l.fetchStatus===`paused`,isPlaceholderData:u,isRefetchError:v&&b,isStale:q(e,t),refetch:this.refetch,promise:this.#o,isEnabled:j(t.enabled,e)!==!1};if(this.options.experimental_prefetchInRender){let t=x.data!==void 0,r=x.status===`error`&&!t,i=e=>{r?e.reject(x.error):t&&e.resolve(x.data)},a=()=>{let e=this.#o=x.promise=L();i(e)},o=this.#o;switch(o.status){case`pending`:e.queryHash===n.queryHash&&i(o);break;case`fulfilled`:(r||x.data!==o.value)&&a();break;case`rejected`:(!r||x.error!==o.reason)&&a()}}return x}updateResult(){let e=this.#r,t=this.createResult(this.#t,this.options);this.#i=this.#t.state,this.#a=this.options,this.#i.data!==void 0&&(this.#u=this.#t),!E(t,e)&&(this.#r=t,this.#C({listeners:(()=>{if(!e)return!0;let{notifyOnChangeProps:t}=this.options,n=typeof t==`function`?t():t;if(n===`all`||!n&&!this.#m.size)return!0;let r=new Set(n??this.#m);return this.options.throwOnError&&r.add(`error`),Object.keys(this.#r).some(t=>{let n=t;return this.#r[n]!==e[n]&&r.has(n)})})()}))}#S(){let e=this.#e.getQueryCache().build(this.#e,this.options);if(e===this.#t)return;let t=this.#t;this.#t=e,this.#n=e.state,this.hasListeners()&&(t?.removeObserver(this),e.addObserver(this))}onQueryUpdate(){this.updateResult(),this.hasListeners()&&this.#y()}#C(e){P.batch(()=>{e.listeners&&this.listeners.forEach(e=>{e(this.#r)}),this.#e.getQueryCache().notify({query:this.#t,type:`observerResultsUpdated`})})}};function U(e,t){return j(t.enabled,e)!==!1&&e.state.data===void 0&&(e.state.status!==`error`||j(t.retryOnMount,e)!==!1)}function W(e,t){return U(e,t)||e.state.data!==void 0&&G(e,t,t.refetchOnMount)}function G(e,t,n){if(j(t.enabled,e)!==!1&&D(t.staleTime,e)!==`static`){let r=typeof n==`function`?n(e):n;return r===`always`||r!==!1&&q(e,t)}return!1}function K(e,t,n,r){return(e!==t||j(r.enabled,e)===!1)&&(!n.suspense||e.state.status!==`error`)&&q(e,n)}function q(e,t){return j(t.enabled,e)!==!1&&e.isStaleByTime(D(t.staleTime,e))}function J(e,t){return!E(e.getCurrentResult(),t)}function Y(e,t,n){let r=n||o(),i=y(()=>{let e=t;typeof e==`function`&&(e=e());let n=I(e);typeof n.enabled==`function`&&(n.enabled=n.enabled());let i=r.defaultQueryOptions(n);return i._optimisticResults=r.isRestoring?.value?`isRestoring`:`optimistic`,i}),a=new e(r,i.value),s=i.value.shallow?f(a.getCurrentResult()):b(a.getCurrentResult()),c=()=>{};r.isRestoring&&d(r.isRestoring,e=>{e||(c(),c=a.subscribe(e=>{F(s,e)}))},{immediate:!0});let h=()=>{a.setOptions(i.value),F(s,a.getCurrentResult())};d(i,h),u(()=>{c()});let g=(...e)=>(h(),s.refetch(...e)),_=()=>new Promise((e,t)=>{let n=()=>{},r=()=>{if(i.value.enabled!==!1){a.setOptions(i.value);let r=a.getOptimisticResult(i.value);r.isStale?(n(),a.fetchOptimistic(i.value).then(e,n=>{A(i.value.throwOnError,[n,a.getCurrentQuery()])?t(n):e(a.getCurrentResult())})):(n(),e(r))}};r(),n=d(i,r)});d(()=>s.error,e=>{if(s.isError&&!s.isFetching&&A(i.value.throwOnError,[e,a.getCurrentQuery()]))throw e});let v=i.value.shallow?p(s):l(s),x=m(v);for(let e in s)typeof s[e]==`function`&&(x[e]=s[e]);return x.suspense=_,x.refetch=g,x}function X(e,t){return Y(H,e,t)}var Z={"aria-labelledby":`automation-boundary-title`},ne=h({__name:`AutomationBoundaryPanel`,props:{algorithmStatus:{},orderCapability:{},modelMutationBoundary:{}},setup(e){return(t,n)=>(c(),w(`section`,Z,[n[3]||=S(`h2`,{id:`automation-boundary-title`},`자동화 경계`,-1),S(`dl`,null,[S(`div`,null,[n[0]||=S(`dt`,null,`알고리즘 상태`,-1),S(`dd`,null,s(e.algorithmStatus),1)]),S(`div`,null,[n[1]||=S(`dt`,null,`주문 Capability`,-1),S(`dd`,null,s(e.orderCapability),1)]),S(`div`,null,[n[2]||=S(`dt`,null,`모델 변경`,-1),S(`dd`,null,s(e.modelMutationBoundary),1)])]),n[4]||=S(`p`,null,` 스케줄러는 평가 증거와 개선 제안만 생성합니다. 모델 승격·롤백·임계값 변경은 독립 검증과 maker-checker 승인을 거쳐야 합니다. `,-1)]))}}),re={"aria-labelledby":`operation-plan-title`},ie={class:`table-wrap`},ae=h({__name:`ModelOperationTable`,props:{operations:{}},setup(e){return(t,n)=>(c(),w(`section`,re,[n[1]||=S(`h2`,{id:`operation-plan-title`},`지속 평가·개선 작업 계획`,-1),S(`div`,ie,[S(`table`,null,[n[0]||=S(`thead`,null,[S(`tr`,null,[S(`th`,null,`Job`),S(`th`,null,`작업`),S(`th`,null,`주기`),S(`th`,null,`자동화 모드`),S(`th`,null,`Queue`),S(`th`,null,`Gate`),S(`th`,null,`Owner`),S(`th`,null,`산출물`)])],-1),S(`tbody`,null,[(c(!0),w(x,null,g(e.operations,e=>(c(),w(`tr`,{key:e.operationCode},[S(`td`,null,s(e.operationCode),1),S(`td`,null,s(e.name),1),S(`td`,null,s(e.cadence),1),S(`td`,null,s(e.automationMode),1),S(`td`,null,s(e.queue),1),S(`td`,null,s(e.gate),1),S(`td`,null,s(e.primaryOwner)+` / `+s(e.secondaryOwner),1),S(`td`,null,s(e.output),1)]))),128))])])])]))}}),oe=r({operationCode:i().min(1),name:i().min(1),cadence:a([`DAILY`,`WEEKLY`,`MONTHLY`,`QUARTERLY`,`EVENT_DRIVEN`]),automationMode:a([`EVALUATION_ONLY`,`PROPOSAL_ONLY`,`DRILL_ONLY`]),queue:i().min(1),primaryOwner:i().min(1),secondaryOwner:i().min(1),requiredEvidence:i().min(1),output:i().min(1),gate:i().min(1)}),se=r({algorithmStatus:e(`RESEARCH_CANDIDATE_NOT_PRODUCTION`),orderCapability:e(`AUTOMATIC_ORDER_AND_KIS_SUBMISSION_OFF`),modelMutationBoundary:e(`EVALUATION_AND_PROPOSAL_ONLY_HUMAN_APPROVAL_REQUIRED`),operations:n(oe)});async function Q(){let e=await t.get(`/internal/v1/model-operations/plan`);return se.parse(e.data)}var $={all:[`model-operations`],plan:()=>[...$.all,`plan`]};function ce(){return X({queryKey:$.plan(),queryFn:Q,staleTime:3e5,retry:1})}var le=h({__name:`ModelOperationsPage`,setup(e){let t=ce();return(e,n)=>(c(),w(`article`,null,[n[0]||=S(`header`,null,[S(`h1`,null,`모델 운영·지속 고도화`),S(`p`,null,`일·주·월·분기 평가, drift, champion/challenger, 개선 제안과 승격 증거를 관리합니다.`)],-1),v(V,{loading:C(t).isLoading.value,error:C(t).error.value,empty:!C(t).data.value},{default:T(()=>[C(t).data.value?(c(),w(x,{key:0},[v(ne,{"algorithm-status":C(t).data.value.algorithmStatus,"order-capability":C(t).data.value.orderCapability,"model-mutation-boundary":C(t).data.value.modelMutationBoundary},null,8,[`algorithm-status`,`order-capability`,`model-mutation-boundary`]),v(ae,{operations:C(t).data.value.operations},null,8,[`operations`])],64)):_(``,!0)]),_:1},8,[`loading`,`error`,`empty`])]))}});export{le as default};