<!doctype html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/layout :: head('운영 현황')}"></head>
<body>
<nav th:replace="~{fragments/layout :: nav}"></nav>
<main class="container py-4">
  <div class="page-title">
    <h1>운영 현황</h1>
    <details class="explanation-details">
      <summary>도움말</summary>
      <p>보호 객체별 ORDS handler, 행 접근 정책(VPD), 행 접근 rule, 최근 검증 상태를 확인합니다. 이상이 있을 때는 해당 객체의 행 접근 규칙·VPD 정책·ORDS 순서로 점검하세요.</p>
      <p>컬럼 마스킹은 ASO/Data Redaction 정책 상태로 별도 확인합니다. 행 접근 정책이 정상이더라도 ASO 정책이 불일치하면 민감 컬럼이 예상과 다르게 원문 또는 마스킹값으로 반환될 수 있습니다.</p>
    </details>
  </div>

  <section class="content-band">
    <div class="section-heading">
      <div>
        <span class="architecture-kicker">운영 요약</span>
        <h2>지금 먼저 확인할 상태</h2>
        <p class="section-subtitle">아래 요약은 이 화면의 DB 조회 결과에서 계산한 운영자용 triage입니다. 최종 증적은 행별 상세와 접근 검증 결과로 확인합니다.</p>
      </div>
      <span class="badge"
            th:classappend="${' ' + summary.overallBadgeClass()}"
            th:text="${summary.overallLabel()}">정상</span>
    </div>
    <div class="effective-preview">
      <dl>
        <div>
          <dt>전체 판단</dt>
          <dd>
            <strong th:text="${summary.overallLabel()}">정상</strong><br>
            <small th:text="${summary.primaryAction()}">현재 요약 기준으로 즉시 조치할 항목은 없습니다.</small>
          </dd>
        </div>
        <div>
          <dt>행 접근 정책(VPD)</dt>
          <dd th:text="${summary.rowPolicySummary()}">정상 0 · 확인 0 · 오류 0</dd>
        </div>
        <div>
          <dt>컬럼 마스킹 정책(ASO)</dt>
          <dd th:text="${summary.maskingSummary()}">적용 0 · 미적용 정상 0 · 불일치 0</dd>
        </div>
        <div>
          <dt>검증 필요</dt>
          <dd th:text="${summary.unverifiedCount() + '개 보호 객체'}">0개 보호 객체</dd>
        </div>
      </dl>
    </div>
    <div class="result-metrics mt-3">
      <div><span>보호 객체</span><strong th:text="${summary.protectedObjectCount()}">0</strong></div>
      <div><span>ORDS handler 없음</span><strong th:text="${summary.missingHandlerCount()}">0</strong></div>
      <div><span>VPD 정책 없음</span><strong th:text="${summary.missingPolicyCount()}">0</strong></div>
      <div><span>ASO 불일치</span><strong th:text="${summary.maskingMismatchCount()}">0</strong></div>
    </div>
  </section>

  <section class="content-band">
    <div class="section-heading">
      <div>
        <span class="architecture-kicker">운영 판단 기준</span>
        <h2>행 접근 정책(VPD)과 컬럼 마스킹 정책(ASO)을 분리해서 봅니다</h2>
        <p class="section-subtitle">VPD는 행 접근, ASO/Data Redaction은 컬럼 원문/마스킹을 담당합니다. 둘 중 하나만 정상이어도 전체 권한 결과가 정상이라고 판단하면 안 됩니다.</p>
      </div>
    </div>
    <div class="effective-preview">
      <dl>
        <div>
          <dt>행 접근 정책(VPD)</dt>
          <dd>아래 보호 객체 표에서 policy, function, 최근 접근 검증 상태를 확인합니다.</dd>
        </div>
        <div>
          <dt>ASO 컬럼 정책</dt>
          <dd>아래 ASO 표에서 백오피스 활성 컬럼 수와 DB Redaction 컬럼 수가 일치하는지 확인합니다.</dd>
        </div>
        <div>
          <dt>실제 결과 검증</dt>
          <dd>상태가 정상이어도 최종 판단은 <a href="/probe">접근 검증</a>에서 토큰 기준 응답으로 확인합니다.</dd>
        </div>
      </dl>
    </div>
  </section>

  <section class="content-band">
    <h2>행 접근 정책(VPD) · ORDS 검증 상태</h2>
    <div class="table-responsive">
      <table class="table table-sm align-middle operation-status-table">
        <thead>
        <tr>
          <th>Health</th>
          <th>Object</th>
          <th>ORDS</th>
          <th>VPD</th>
          <th>권한</th>
          <th>최근 검증</th>
          <th>조치</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="row : ${rows}">
          <td>
            <span class="badge"
                  th:classappend="${row.healthLevel() == 'OK'} ? ' text-bg-success' : (${row.healthLevel() == 'ERROR'} ? ' text-bg-danger' : ' text-bg-warning')"
                  th:text="${row.healthLevel()}">OK</span>
          </td>
          <td>
            <strong th:text="${row.displayName()}">ADMIN.TABLE</strong>
            <div class="text-muted small" th:text="${row.enabledYn()}">Y</div>
          </td>
          <td>
            <code th:text="${row.ordsPath()}">cb-ords/path</code>
            <div class="small mt-1">
              <span th:if="${row.handlerId() != null}">
                <span class="badge text-bg-secondary" th:text="${row.handlerMethod()}">POST</span>
                <span th:text="${row.handlerSourceType()}">plsql/block</span>
              </span>
              <span th:unless="${row.handlerId() != null}" class="text-danger">handler 없음</span>
            </div>
          </td>
          <td>
            <div><code th:text="${row.policyNames()} ?: '-'">POLICY</code></div>
            <div class="small">
              <span th:text="${row.policyEnabled()} ?: '-'">YES</span>
              <span> / </span>
              <span th:text="${row.functionStatus()} ?: '-'">VALID</span>
            </div>
            <div class="text-muted small" th:text="${row.functionName()} ?: '-'">ADMIN.FILTER</div>
          </td>
          <td th:text="${row.permissionSummary()}">1 permissions / 1 rules</td>
          <td>
            <div th:text="${row.lastProbeStatus()} ?: '검증 이력 없음'">SUCCESS</div>
            <div class="text-muted small">
              <span th:text="${row.lastProbeRowCount()} ?: '-'">0</span>
              <span> rows</span>
              <span th:if="${row.lastProbeAt() != null}" th:text="${' / ' + row.lastProbeAt()}"></span>
            </div>
            <div class="text-danger small" th:if="${row.lastProbeErrorCode() != null}" th:text="${row.lastProbeErrorCode()}"></div>
          </td>
          <td class="small" th:text="${row.actionText()}">조치 없음</td>
        </tr>
        <tr th:if="${#lists.isEmpty(rows)}">
          <td colspan="7" class="text-muted">등록된 활성 보호 객체가 없습니다.</td>
        </tr>
        </tbody>
      </table>
    </div>
  </section>

  <section class="content-band">
    <div class="section-heading">
      <div>
        <h2>ASO 컬럼 마스킹 정책 상태</h2>
        <p class="section-subtitle">컬럼 마스킹 화면의 백오피스 설정과 실제 Oracle Data Redaction 정책을 비교한 결과입니다.</p>
      </div>
      <a class="btn btn-sm rw-btn-secondary" href="/masking-rules">컬럼 마스킹 열기</a>
    </div>
    <div class="table-responsive">
      <table class="table table-sm align-middle">
        <thead><tr><th>보호 객체</th><th>DB 정책</th><th>백오피스 활성 컬럼</th><th>DB Redaction 컬럼</th><th>상태</th><th>확인 결과</th></tr></thead>
        <tbody>
        <tr th:each="status : ${maskingPolicyStatuses}">
          <td><code th:text="${status.targetLabel()}">OWNER.OBJECT_NAME</code></td>
          <td><code th:text="${status.policyName()}">REDACTION_POLICY</code></td>
          <td th:text="${status.configuredColumnCount()}">0</td>
          <td th:text="${status.appliedColumnCount()}">0</td>
          <td><span class="badge" th:classappend="${' ' + status.badgeClass()}" th:text="${status.statusLabel()}">적용됨</span></td>
          <td th:text="${status.detail()}">활성 규칙과 DB 정책 컬럼이 일치합니다.</td>
        </tr>
        <tr th:if="${#lists.isEmpty(maskingPolicyStatuses)}">
          <td colspan="6" class="text-muted">조회할 ASO 정책 상태가 없습니다.</td>
        </tr>
        </tbody>
      </table>
    </div>
  </section>
</main>
</body>
</html>
