Application Logs prod-log-2026092222.txt 27 entries
All ERR WRN INF DBG
Activity 22
2026-09-22 22:25:44.358 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:de0639e34275d5d241683fa4dcfc434c] HTTP GET /swagger responded 301 in 0.0497 ms
2026-09-22 22:25:31.258 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:9c688b82717dc6f927c620c1acb9c367] HTTP GET /UI/business/login responded 200 in 4.0318 ms
2026-09-22 22:25:31.258 +00:00 [INF] [HTTP] [U:-] [E:-] [C:436939841aec] [T:9c688b82717dc6f927c620c1acb9c367] HTTP GET /UI/business/login 200
Req: [no body] Res: <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Sign In - Wealthmax</title> <link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" /> <style> html, body { height: 100%; } body { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; background-color: #f5f7fa; } .login-wrapper { display: flex; flex-direction: column; align-items: center; width: 100%; padding: 1.5rem; } .brand-logo { margin-bottom: 1.75rem; text-align: center; } .brand-logo span { font-size: 1.4rem; font-weight: 700; color: #1a1a2e; letter-spacing: -0.5px; } .brand-logo small { display: block; font-size: 0.7rem; color: #6c757d; font-weight: 500; text-transform: uppercase; letter-spacing: 1px; margin-top: 2px; } </style> </head> <body> <div class="login-wrapper"> <div class="brand-logo"> <span>Wealthmax</span> <small>PM CRM</small> </div> <div class="card shadow-sm" style="width: 100%; max-width: 400px;"> <div class="card-body p-4"> <h4 class="card-title mb-1 fw-semibold">Sign In</h4> <p class="text-muted small mb-4">Enter your credentials to access the portal.</p> <form method="post" novalidate action="/UI/business/login"> <div class="mb-3"> <label class="form-label" for="Email">Email</label> <input class="form-control" placeholder="you@example.com" autofocus type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Email" name="Email" value="" /> <span class="text-danger small field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span> </div> <div class="mb-4"> <label class="form-label" for="Password">Password</label> <input type="password" class="form-control" placeholder="••••••••" data-val="true" data-val-minlength="The field Password must be a string or array type with a minimum length of &#x27;8&#x27;." data-val-minlength-min="8" data-val-required="The Password field is required." id="Password" name="Password" /> <span class="text-danger small field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span> </div> <button type="submit" class="btn btn-primary w-100">Sign In</button> <input name="__RequestVerificationToken" type="hidden" value="CfDJ8BWcGWpu-gtJlFkAHgUMLVSYfVrlsRT7yDUW5jr00oLOr-SGkhau2CndAnoq_qfIsbnw39c88oPqTPKL5PxnQm97CVG_imUqUIwzfnuIW-h4QHYoCozQ4cMHjQaei_YvKEJaBAwyaWg8DTAibuWfQEY" /></form> <div class="mt-3 text-center"> <a href="/UI/business/forgot-password" class="small text-decoration-none">Forgot password?</a> </div> </div> </div> </div> <script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="/lib/jquery/dist/jquery.min.js"></script> <script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script> <script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script> </body> </html>
2026-09-22 22:25:31.157 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:cc6d506ff9131aa5a6678e71f0731cd2] HTTP GET /UI/FactFindGenerate responded 302 in 0.3712 ms
2026-09-22 22:25:31.157 +00:00 [INF] [HTTP] [U:-] [E:-] [C:a15df6a1fa63] [T:cc6d506ff9131aa5a6678e71f0731cd2] HTTP GET /UI/FactFindGenerate 302
Req: [no body] Res: [empty response]
2026-09-22 22:25:31.053 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:d4967a978856c70e54721531fc1ea112] HTTP GET /css/site.css responded 200 in 1.5906 ms
2026-09-22 22:25:31.052 +00:00 [INF] [HTTP] [U:-] [E:-] [C:-] [T:d4967a978856c70e54721531fc1ea112] HTTP GET /css/site.css 200
Req: [no body] Res: html { font-size: 14px; } @media (min-width: 768px) { html { font-size: 16px; } } .btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus { box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb; } html { position: relative; min-height: 100%; } body { margin-bottom: 60px; } .form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder { color: var(--bs-secondary-color); text-align: end; } .form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder { text-align: start; }
2026-09-22 22:25:19.165 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:e8978964844729b44b555aadbd6d9e92] HTTP GET /css/commissions.css responded 200 in 0.7817 ms
2026-09-22 22:25:19.164 +00:00 [INF] [HTTP] [U:-] [E:-] [C:-] [T:e8978964844729b44b555aadbd6d9e92] HTTP GET /css/commissions.css 200
Req: [no body] Res: /* ============================================================ Wealthmax UI — scoped clean-fintech light theme Applies under .commissions-area (Commissions module) and .wm-ui-area (all other modernised UI pages) so that the design tokens and cm-* components are shared across the app without leaking into legacy Bootstrap pages. ============================================================ */ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); /* ── Design tokens ─────────────────────────────────────────── */ .commissions-area, .wm-ui-area { --cm-canvas: #f4f6fb; --cm-surface: #ffffff; --cm-border: #e8ecf4; --cm-border-light: #f0f3f9; --cm-radius: 14px; --cm-radius-sm: 8px; --cm-shadow: 0 1px 3px rgba(30,41,80,.06), 0 4px 16px rgba(30,41,80,.07); --cm-shadow-hover: 0 4px 12px rgba(30,41,80,.10), 0 12px 32px rgba(30,41,80,.10); --cm-font: 'Inter', system-ui, -apple-system, sans-serif; --cm-accent: #4361ee; --cm-accent-muted: #eef1fc; --cm-text: #1a2035; --cm-text-muted: #7b8ab8; --cm-text-light: #a8b4d0; --cm-green: #10b981; --cm-green-muted: #ecfdf5; --cm-amber: #f59e0b; --cm-amber-muted: #fffbeb; --cm-red: #ef4444; --cm-red-muted: #fef2f2; --cm-blue: #3b82f6; --cm-blue-muted: #eff6ff; --cm-violet: #8b5cf6; --cm-violet-muted: #f5f3ff; --cm-slate: #64748b; --cm-slate-muted: #f8fafc; font-family: var(--cm-font); background-color: var(--cm-canvas); color: var(--cm-text); } /* ── Page background (full main viewport) ───────────────────── */ .commissions-area .page-bg-fix { background: var(--cm-canvas); } /* ── Page header ────────────────────────────────────────────── */ .cm-page-head { margin-bottom: 1.75rem; } .cm-page-head h3, .cm-page-head .cm-title { font-size: 1.5rem; font-weight: 700; color: var(--cm-text); letter-spacing: -0.02em; margin: 0; } .cm-page-head .cm-subtitle { font-size: 0.8125rem; color: var(--cm-text-muted); margin-top: 0.2rem; } /* ── Preview badge (replaces the stock warning badge) ───────── */ .cm-preview-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; padding: 2px 8px; border-radius: 20px; background: #fff8e6; color: #b45309; border: 1px solid #fcd34d; vertical-align: middle; } /* ── KPI tiles ───────────────────────────────────────────────── */ .cm-kpi { background: var(--cm-surface); border-radius: var(--cm-radius); box-shadow: var(--cm-shadow); padding: 1.25rem 1.375rem; position: relative; overflow: hidden; transition: box-shadow .18s, transform .18s; border: 1px solid var(--cm-border-light); } .cm-kpi:hover { box-shadow: var(--cm-shadow-hover); transform: translateY(-2px); } .cm-kpi::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; border-radius: var(--cm-radius) var(--cm-radius) 0 0; } .cm-kpi-green::before { background: linear-gradient(90deg, #10b981, #34d399); } .cm-kpi-amber::before { background: linear-gradient(90deg, #f59e0b, #fbbf24); } .cm-kpi-blue::before { background: linear-gradient(90deg, #3b82f6, #60a5fa); } .cm-kpi-red::before { background: linear-gradient(90deg, #ef4444, #f87171); } .cm-kpi-violet::before { background: linear-gradient(90deg, #8b5cf6, #a78bfa); } .cm-kpi-slate::before { background: linear-gradient(90deg, #64748b, #94a3b8); } .cm-kpi-icon { width: 36px; height: 36px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 1rem; margin-bottom: 0.875rem; flex-shrink: 0; } .cm-kpi-green .cm-kpi-icon { background: var(--cm-green-muted); color: var(--cm-green); } .cm-kpi-amber .cm-kpi-icon { background: var(--cm-amber-muted); color: var(--cm-amber); } .cm-kpi-blue .cm-kpi-icon { background: var(--cm-blue-muted); color: var(--cm-blue); } .cm-kpi-red .cm-kpi-icon { background: var(--cm-red-muted); color: var(--cm-red); } .cm-kpi-violet .cm-kpi-icon { background: var(--cm-violet-muted); color: var(--cm-violet); } .cm-kpi-slate .cm-kpi-icon { background: var(--cm-slate-muted); color: var(--cm-slate); } .cm-kpi-label { font-size: 0.7rem; font-weight: 600; letter-spacing: 0.07em; text-transform: uppercase; color: var(--cm-text-muted); margin-bottom: 0.25rem; } .cm-kpi-value { font-size: 1.625rem; font-weight: 700; color: var(--cm-text); letter-spacing: -0.025em; line-height: 1.1; } .cm-kpi-sub { font-size: 0.75rem; color: var(--cm-text-muted); margin-top: 0.3rem; } /* ── Cards ───────────────────────────────────────────────────── */ .cm-card { background: var(--cm-surface); border-radius: var(--cm-radius); box-shadow: var(--cm-shadow); border: 1px solid var(--cm-border-light); overflow: hidden; } .cm-card-header { padding: 1rem 1.375rem; border-bottom: 1px solid var(--cm-border); display: flex; align-items: center; justify-content: space-between; gap: 1rem; background: var(--cm-surface); } .cm-card-header-title { font-size: 0.875rem; font-weight: 600; color: var(--cm-text); display: flex; align-items: center; gap: 0.5rem; } .cm-card-header-title i { color: var(--cm-accent); font-size: 1rem; } .cm-card-header-meta { font-size: 0.75rem; color: var(--cm-text-muted); } .cm-card-body { padding: 1.25rem 1.375rem; } /* Nav cards (dashboard) */ .cm-nav-card { background: var(--cm-surface); border-radius: var(--cm-radius); box-shadow: var(--cm-shadow); border: 1px solid var(--cm-border-light); padding: 1.25rem 1.375rem; display: flex; align-items: flex-start; gap: 1rem; text-decoration: none; transition: box-shadow .18s, transform .18s, border-color .18s; height: 100%; } .cm-nav-card:hover { box-shadow: var(--cm-shadow-hover); transform: translateY(-3px); border-color: var(--cm-accent); text-decoration: none; } .cm-nav-card-icon { width: 44px; height: 44px; border-radius: 12px; background: var(--cm-accent-muted); color: var(--cm-accent); display: flex; align-items: center; justify-content: center; font-size: 1.25rem; flex-shrink: 0; } .cm-nav-card-title { font-size: 0.9rem; font-weight: 600; color: var(--cm-text); margin-bottom: 0.25rem; } .cm-nav-card-desc { font-size: 0.78rem; color: var(--cm-text-muted); line-height: 1.4; margin: 0; } /* ── Tables ──────────────────────────────────────────────────── */ .commissions-area .cm-table, .wm-ui-area .cm-table { margin: 0; font-size: 0.8375rem; color: var(--cm-text); border-collapse: collapse; width: 100%; } .commissions-area .cm-table thead th, .wm-ui-area .cm-table thead th { background: var(--cm-canvas); color: var(--cm-text-muted); font-size: 0.7rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; padding: 0.75rem 1rem; border-bottom: 1px solid var(--cm-border); border-top: none; white-space: nowrap; } .commissions-area .cm-table tbody td, .wm-ui-area .cm-table tbody td { padding: 0.75rem 1rem; border-bottom: 1px solid var(--cm-border-light); vertical-align: middle; } .commissions-area .cm-table tbody tr:last-child td, .wm-ui-area .cm-table tbody tr:last-child td { border-bottom: none; } .commissions-area .cm-table tbody tr:hover td, .wm-ui-area .cm-table tbody tr:hover td { background: var(--cm-canvas); } .commissions-area .cm-table tfoot td, .wm-ui-area .cm-table tfoot td { padding: 0.75rem 1rem; border-top: 2px solid var(--cm-border); background: var(--cm-canvas); font-weight: 600; font-size: 0.8375rem; } /* ── Badges / pills ──────────────────────────────────────────── */ .cm-pill { display: inline-flex; align-items: center; gap: 3px; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.02em; padding: 2px 9px; border-radius: 20px; line-height: 1.6; white-space: nowrap; } .cm-pill-green { background: var(--cm-green-muted); color: #065f46; } .cm-pill-amber { background: var(--cm-amber-muted); color: #92400e; } .cm-pill-blue { background: var(--cm-blue-muted); color: #1e40af; } .cm-pill-red { background: var(--cm-red-muted); color: #991b1b; } .cm-pill-violet { background: var(--cm-violet-muted); color: #5b21b6; } .cm-pill-slate { background: var(--cm-slate-muted); color: #334155; border: 1px solid #e2e8f0; } .cm-pill-info { background: #eff6ff; color: #1e40af; } .cm-pill-warn { background: var(--cm-amber-muted); color: #92400e; } /* ── Buttons ─────────────────────────────────────────────────── */ .commissions-area .cm-btn-back, .wm-ui-area .cm-btn-back { font-size: 0.8125rem; font-weight: 500; padding: 0.375rem 0.875rem; border-radius: var(--cm-radius-sm); border: 1px solid var(--cm-border); background: var(--cm-surface); color: var(--cm-text-muted); text-decoration: none; display: inline-flex; align-items: center; gap: 0.35rem; transition: border-color .14s, color .14s, background .14s; } .commissions-area .cm-btn-back:hover, .wm-ui-area .cm-btn-back:hover { border-color: var(--cm-accent); color: var(--cm-accent); background: var(--cm-accent-muted); text-decoration: none; } .commissions-area .cm-btn-primary, .wm-ui-area .cm-btn-primary { font-size: 0.8125rem; font-weight: 500; padding: 0.375rem 0.875rem; border-radius: var(--cm-radius-sm); border: 1px solid var(--cm-accent); background: var(--cm-accent); color: #fff; text-decoration: none; display: inline-flex; align-items: center; gap: 0.35rem; transition: opacity .14s; } .commissions-area .cm-btn-primary:hover, .wm-ui-area .cm-btn-primary:hover { opacity: 0.88; color: #fff; text-decoration: none; } .commissions-area .cm-btn-action, .wm-ui-area .cm-btn-action { font-size: 0.75rem; font-weight: 500; padding: 0.25rem 0.625rem; border-radius: 6px; border: 1px solid var(--cm-border); background: var(--cm-surface); color: var(--cm-text-muted); text-decoration: none; display: inline-flex; align-items: center; gap: 0.25rem; transition: border-color .14s, color .14s; white-space: nowrap; } .commissions-area .cm-btn-action:hover, .wm-ui-area .cm-btn-action:hover { border-color: var(--cm-accent); color: var(--cm-accent); text-decoration: none; } .commissions-area .cm-btn-action.cm-btn-action-primary, .wm-ui-area .cm-btn-action.cm-btn-action-primary { border-color: var(--cm-accent); color: var(--cm-accent); } .commissions-area .cm-btn-action.cm-btn-action-primary:hover, .wm-ui-area .cm-btn-action.cm-btn-action-primary:hover { background: var(--cm-accent-muted); } /* ── Form controls inside tables ─────────────────────────────── */ .commissions-area .cm-table .form-control, .wm-ui-area .cm-table .form-control { font-size: 0.8125rem; border-radius: 6px; border-color: var(--cm-border); background: var(--cm-canvas); color: var(--cm-text); } .commissions-area .cm-table .input-group-text, .wm-ui-area .cm-table .input-group-text { font-size: 0.8125rem; background: var(--cm-border-light); border-color: var(--cm-border); color: var(--cm-text-muted); } /* ── Info callout ────────────────────────────────────────────── */ .cm-callout { display: flex; align-items: flex-start; gap: 0.6rem; padding: 0.875rem 1rem; border-radius: var(--cm-radius-sm); font-size: 0.8rem; line-height: 1.5; border: 1px solid; } .cm-callout-info { background: var(--cm-blue-muted); border-color: #bfdbfe; color: #1e40af; } .cm-callout-warn { background: var(--cm-amber-muted); border-color: #fde68a; color: #92400e; } .cm-callout-success { background: var(--cm-green-muted); border-color: #a7f3d0; color: #065f46; } .cm-callout-danger { background: var(--cm-red-muted); border-color: #fecaca; color: #991b1b; } .cm-callout i { margin-top: 1px; flex-shrink: 0; font-size: 0.95rem; } /* ── Audit / event stream ────────────────────────────────────── */ .cm-event-list { list-style: none; padding: 0; margin: 0; } .cm-event-item { padding: 0.875rem 0; border-bottom: 1px solid var(--cm-border-light); display: flex; flex-direction: column; gap: 0.25rem; } .cm-event-item:last-child { border-bottom: none; } .cm-event-header { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; } .cm-event-type { font-size: 0.8375rem; font-weight: 600; color: var(--cm-text); display: flex; align-items: center; gap: 0.375rem; } .cm-event-ref { font-size: 0.7rem; font-weight: 500; padding: 1px 7px; border-radius: 4px; background: var(--cm-canvas); border: 1px solid var(--cm-border); color: var(--cm-text-muted); font-family: ui-monospace, 'Cascadia Code', monospace; } .cm-event-meta { font-size: 0.75rem; color: var(--cm-text-light); white-space: nowrap; } .cm-event-detail { font-size: 0.78rem; color: var(--cm-text-muted); } /* ── Metadata row (key/value pairs) ─────────────────────────── */ .cm-meta-row { display: flex; justify-content: space-between; align-items: center; padding: 0.45rem 0; border-bottom: 1px solid var(--cm-border-light); font-size: 0.8125rem; } .cm-meta-row:last-child { border-bottom: none; } .cm-meta-label { color: var(--cm-text-muted); } .cm-meta-value { font-weight: 600; color: var(--cm-text); } /* ── Total banner (Profile page) ────────────────────────────── */ .cm-total-banner { border-radius: var(--cm-radius-sm); padding: 0.75rem 1rem; display: flex; align-items: center; gap: 0.5rem; font-size: 0.8375rem; font-weight: 500; border: 1px solid; margin-top: 1rem; } .cm-total-banner.ok { background: var(--cm-green-muted); border-color: #a7f3d0; color: #065f46; } .cm-total-banner.err { background: var(--cm-red-muted); border-color: #fecaca; color: #991b1b; } /* ── Section divider label ───────────────────────────────────── */ .cm-section-label { font-size: 0.7rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--cm-text-muted); margin-bottom: 0.75rem; padding-bottom: 0.4rem; border-bottom: 1px solid var(--cm-border-light); } /* ── Tabbed output card (shared by AllocationDetail + Lifecycle) ─ */ .commissions-area .sim-tabs-card, .wm-ui-area .sim-tabs-card { overflow: visible; } .commissions-area .sim-tabnav, .wm-ui-area .sim-tabnav { display: flex; gap: 2px; padding: 0 0.5rem; border-bottom: 1px solid var(--cm-border); background: var(--cm-canvas); border-radius: var(--cm-radius) var(--cm-radius) 0 0; flex-wrap: wrap; } .commissions-area .sim-tab, .wm-ui-area .sim-tab { position: relative; border: none; background: transparent; cursor: pointer; font-size: 0.8125rem; font-weight: 600; color: var(--cm-text-muted); padding: 0.75rem 0.95rem; display: inline-flex; align-items: center; gap: 0.4rem; border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color .14s, border-color .14s; } .commissions-area .sim-tab i, .wm-ui-area .sim-tab i { font-size: 0.9rem; } .commissions-area .sim-tab:hover, .wm-ui-area .sim-tab:hover { color: var(--cm-text); } .commissions-area .sim-tab.is-active, .wm-ui-area .sim-tab.is-active { color: var(--cm-accent); border-bottom-color: var(--cm-accent); } .commissions-area .sim-tab-sub, .wm-ui-area .sim-tab-sub { font-weight: 400; color: var(--cm-text-muted); font-size: 0.75rem; } .commissions-area .sim-tab-count, .wm-ui-area .sim-tab-count { font-size: 0.68rem; font-weight: 700; line-height: 1; padding: 2px 6px; border-radius: 20px; background: var(--cm-accent-muted); color: var(--cm-accent); } .commissions-area .sim-tabpanel, .wm-ui-area .sim-tabpanel { display: none; } .commissions-area .sim-tabpanel.is-active, .wm-ui-area .sim-tabpanel.is-active { display: block; } /* Toolbar strip inside a panel (legend / heading row) */ .commissions-area .sim-panel-toolbar, .wm-ui-area .sim-panel-toolbar { padding: 0.75rem 1.375rem; border-bottom: 1px solid var(--cm-border-light); background: var(--cm-surface); } .commissions-area .sim-panel-toolbar-between, .wm-ui-area .sim-panel-toolbar-between { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; } .commissions-area .sim-panel-heading, .wm-ui-area .sim-panel-heading { font-size: 0.8rem; font-weight: 600; color: var(--cm-text); } /* Stronger totals band in a ledger footer */ .commissions-area .cm-table.cm-table-totals tfoot td, .wm-ui-area .cm-table.cm-table-totals tfoot td { border-top: 2px solid var(--cm-accent); background: var(--cm-accent-muted); color: var(--cm-text); } .commissions-area .cm-table.cm-table-totals tfoot td:first-child, .wm-ui-area .cm-table.cm-table-totals tfoot td:first-child { text-transform: uppercase; letter-spacing: 0.05em; font-size: 0.72rem; color: var(--cm-accent); } /* Bounded event-log items so entries don't blend together */ .commissions-area .cm-event-list.cm-event-list-cards .cm-event-item, .wm-ui-area .cm-event-list.cm-event-list-cards .cm-event-item { padding: 0.75rem 0.85rem; margin-bottom: 0.55rem; border: 1px solid var(--cm-border-light); border-left-width: 3px; border-radius: var(--cm-radius-sm); background: var(--cm-surface); } .commissions-area .cm-event-list.cm-event-list-cards .cm-event-item:last-child, .wm-ui-area .cm-event-list.cm-event-list-cards .cm-event-item:last-child { margin-bottom: 0; } /* ── Chart legend ────────────────────────────────────────────── */ .cm-legend { display: flex; gap: 1.25rem; flex-wrap: wrap; font-size: 0.75rem; color: var(--cm-text-muted); align-items: center; } .cm-legend-item { display: flex; align-items: center; gap: 5px; } .cm-legend-dot { width: 10px; height: 10px; border-radius: 3px; display: inline-block; flex-shrink: 0; } .cm-legend-dot-circle { border-radius: 50%; } /* ── Form controls (wm-ui-area pages: Reporting, Templates, etc.) */ .wm-ui-area .form-control, .wm-ui-area .form-select { font-size: 0.8375rem; border-color: var(--cm-border); border-radius: var(--cm-radius-sm); background: var(--cm-surface); color: var(--cm-text); } .wm-ui-area .form-control:focus, .wm-ui-area .form-select:focus { border-color: var(--cm-accent); box-shadow: 0 0 0 3px rgba(67,97,238,.12); } .wm-ui-area .form-label { font-size: 0.8rem; font-weight: 600; color: var(--cm-text-muted); letter-spacing: 0.02em; } .wm-ui-area .form-check-input:checked { background-color: var(--cm-accent); border-color: var(--cm-accent); } /* ── Status badge override (replaces Bootstrap badge) ─────────── */ .wm-ui-area .cm-status-active { background: var(--cm-green-muted); color: #065f46; } .wm-ui-area .cm-status-inactive { background: var(--cm-slate-muted); color: #334155; border: 1px solid #e2e8f0; } .wm-ui-area .cm-status-system { background: var(--cm-blue-muted); color: #1e40af; } /* ── Pagination ─────────────────────────────────────────────── */ .wm-ui-area .pagination .page-link { font-size: 0.8rem; color: var(--cm-text-muted); border-color: var(--cm-border); background: var(--cm-surface); } .wm-ui-area .pagination .page-item.active .page-link { background: var(--cm-accent); border-color: var(--cm-accent); color: #fff; } /* ── Upload Commission Statement modal ─────────────────────────── */ .cm-upload-modal { border-radius: var(--cm-radius); border: 1px solid var(--cm-border); } .cm-upload-icon { width: 44px; height: 44px; flex-shrink: 0; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--cm-accent-muted); color: var(--cm-accent); font-size: 1.1rem; } .cm-upload-template-card { display: flex; align-items: center; gap: 0.75rem; padding: 0.875rem 1rem; margin: 1rem 0; border-radius: var(--cm-radius-sm); background: var(--cm-canvas); border: 1px solid var(--cm-border-light); } .cm-upload-template-icon { width: 34px; height: 34px; flex-shrink: 0; border-radius: var(--cm-radius-sm); display: flex; align-items: center; justify-content: center; background: var(--cm-green-muted); color: var(--cm-green); } .cm-upload-template-text { flex: 1 1 auto; } .cm-upload-template-title { font-size: 0.8375rem; font-weight: 600; color: var(--cm-text); } .cm-upload-template-desc { font-size: 0.75rem; color: var(--cm-text-muted); } .cm-upload-segment { display: flex; gap: 0.5rem; margin-bottom: 1rem; } .cm-upload-segment-btn { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.8125rem; font-weight: 600; padding: 0.4rem 1rem; border-radius: 20px; border: 1px solid var(--cm-border); background: var(--cm-surface); color: var(--cm-text-muted); transition: border-color .14s, color .14s, background .14s; } .cm-upload-segment-btn.is-active { background: var(--cm-accent); border-color: var(--cm-accent); color: #fff; } .cm-upload-segment-btn:disabled { opacity: 0.55; cursor: not-allowed; } .cm-upload-dropzone { border: 2px dashed var(--cm-border); border-radius: var(--cm-radius-sm); background: var(--cm-canvas); padding: 2rem 1rem; text-align: center; cursor: pointer; transition: border-color .14s, background .14s; margin-bottom: 1rem; } .cm-upload-dropzone.is-dragover { border-color: var(--cm-accent); background: var(--cm-accent-muted); } .cm-upload-dropzone-icon { display: inline-flex; width: 44px; height: 44px; align-items: center; justify-content: center; border-radius: 50%; background: var(--cm-accent-muted); color: var(--cm-accent); font-size: 1.25rem; margin-bottom: 0.6rem; } .cm-upload-dropzone-text { font-size: 0.8375rem; color: var(--cm-text); } .cm-upload-link { background: none; border: none; padding: 0; color: var(--cm-accent); font-weight: 600; font-size: 0.8375rem; } .cm-upload-dropzone-hint { font-size: 0.72rem; color: var(--cm-text-light); margin-top: 0.3rem; } .cm-upload-file { display: flex; align-items: flex-start; gap: 0.75rem; padding: 0.875rem 1rem; margin-bottom: 1rem; border-radius: var(--cm-radius-sm); background: var(--cm-surface); border: 1px solid var(--cm-border); } .cm-upload-file-icon { width: 34px; height: 34px; flex-shrink: 0; border-radius: var(--cm-radius-sm); display: flex; align-items: center; justify-content: center; background: var(--cm-green-muted); color: var(--cm-green); } .cm-upload-file-info { flex: 1 1 auto; min-width: 0; } .cm-upload-file-name { font-size: 0.8375rem; font-weight: 600; color: var(--cm-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .cm-upload-file-size { font-size: 0.72rem; color: var(--cm-text-muted); margin-bottom: 0.4rem; } .cm-upload-file-actions { display: flex; gap: 0.5rem; flex-shrink: 0; } .cm-upload-remove-btn:hover { border-color: var(--cm-red) !important; color: var(--cm-red) !important; background: var(--cm-red-muted) !important; } .cm-upload-progress { height: 6px; border-radius: 4px; background: var(--cm-border-light); overflow: hidden; } .cm-upload-progress-bar { height: 100%; width: 0%; background: var(--cm-accent); border-radius: 4px; transition: width .2s ease; } /* ── State panels ────────────────────────────────────────────── */ .cm-upload-alert { border-radius: var(--cm-radius-sm); border: 1px solid; padding: 1rem; margin-bottom: 1rem; } .cm-upload-alert--error { background: var(--cm-red-muted); border-color: #fecaca; } .cm-upload-alert--warning { background: var(--cm-amber-muted); border-color: #fde68a; } .cm-upload-alert--success { background: var(--cm-green-muted); border-color: #a7f3d0; display: flex; align-items: center; gap: 0.6rem; color: #065f46; font-size: 0.8375rem; font-weight: 500; } .cm-upload-alert--success i { font-size: 1.1rem; } .cm-upload-alert-header { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8375rem; font-weight: 600; color: var(--cm-text); margin-bottom: 0.5rem; } .cm-upload-alert--error .cm-upload-alert-header i { color: var(--cm-red); } .cm-upload-alert--warning .cm-upload-alert-header i { color: var(--cm-amber); } .cm-upload-warning-list { margin: 0 0 0.85rem; padding-left: 1.1rem; font-size: 0.8rem; color: #92400e; } .cm-upload-warning-list li { margin-bottom: 0.2rem; } .cm-upload-review-btn { font-size: 0.8125rem; } .cm-upload-stats { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0.6rem; margin-bottom: 0.85rem; } .cm-upload-stat { background: var(--cm-surface); border: 1px solid var(--cm-border-light); border-radius: var(--cm-radius-sm); padding: 0.6rem 0.7rem; text-align: center; } .cm-upload-stat-label { font-size: 0.65rem; color: var(--cm-text-muted); text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: 0.2rem; } .cm-upload-stat-value { font-size: 1.15rem; font-weight: 700; color: var(--cm-text); margin-bottom: 0.3rem; } .cm-upload-section-label { font-size: 0.75rem; font-weight: 600; color: var(--cm-text); margin-bottom: 0.5rem; } /* ── Warning review table ────────────────────────────────────── */ .cm-upload-review { border-radius: var(--cm-radius-sm); border: 1px solid #fde68a; background: var(--cm-amber-muted); padding: 1rem; margin-bottom: 1rem; } .cm-upload-review-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; margin-bottom: 0.75rem; } .cm-upload-review-actions { display: flex; gap: 0.5rem; flex-shrink: 0; } .cm-upload-skipall-btn:hover { border-color: var(--cm-red) !important; color: var(--cm-red) !important; } .cm-upload-review-progress { display: flex; align-items: center; gap: 0.75rem; font-size: 0.75rem; color: #92400e; font-weight: 500; margin-bottom: 0.85rem; } .cm-upload-review-progress .cm-upload-progress { flex: 1 1 auto; background: rgba(255,255,255,.6); } .cm-upload-review .cm-table { background: var(--cm-surface); } .cm-upload-muted { color: var(--cm-text-light); } .cm-upload-subtext { font-size: 0.7rem; color: var(--cm-text-muted); margin-top: 1px; } .cm-upload-kebab-btn { width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border-radius: 6px; border: 1px solid var(--cm-border); background: var(--cm-surface); color: var(--cm-text-muted); } .cm-upload-kebab-btn:hover { border-color: var(--cm-accent); color: var(--cm-accent); } .cm-upload-fix-row input.form-control { font-size: 0.8125rem; } .cm-upload-fix-inputs { display: flex; gap: 0.4rem; } .cm-upload-fix-inputs input.form-control { flex: 1 1 0; min-width: 0; } .cm-upload-fix-error { margin-top: 0.3rem; font-size: 0.75rem; color: var(--cm-red); } .cm-upload-fix-actions { display: flex; gap: 0.35rem; justify-content: flex-end; } .cm-upload-fix-actions button { width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border-radius: 6px; border: 1px solid var(--cm-border); background: var(--cm-surface); color: var(--cm-text-muted); } .cm-upload-fix-confirm:hover { border-color: var(--cm-green); color: var(--cm-green); } .cm-upload-fix-cancel:hover { border-color: var(--cm-red); color: var(--cm-red); } .cm-upload-fix-trigger:hover { border-color: var(--cm-accent); color: var(--cm-accent); } .cm-upload-skip-trigger:hover { border-color: var(--cm-red); color: var(--cm-red); } .cm-upload-tips { margin-top: 0.25rem; } @media (max-width: 640px) { .cm-upload-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } .cm-upload-review-header { flex-direction: column; } } /* ============================================================ Commission Allocation Management page (tabs, bulk-action bar, filters, expandable rows, pagination, Overwrite modal) ============================================================ */ /* ── Segment toggle (Protection / Mortgage) ─────────────────── */ .cm-segment-toggle { display: inline-flex; gap: 0.35rem; background: var(--cm-slate-muted); border: 1px solid var(--cm-border); border-radius: 999px; padding: 3px; } .cm-segment-btn { display: inline-flex; align-items: center; gap: 0.35rem; border: none; background: transparent; color: var(--cm-text-muted); font-size: 0.8125rem; font-weight: 600; padding: 0.4rem 0.9rem; border-radius: 999px; white-space: nowrap; } .cm-segment-btn.is-active { background: var(--cm-surface); color: var(--cm-accent); box-shadow: var(--cm-shadow); } .cm-segment-btn:disabled { opacity: 0.5; cursor: not-allowed; } /* ── Tab strip ───────────────────────────────────────────────── */ .cm-tabstrip { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.75rem; background: var(--cm-surface); border: 1px solid var(--cm-border); border-radius: var(--cm-radius-sm); padding: 0.5rem; margin-bottom: 0.75rem; } .cm-tabstrip-tabs { display: flex; flex-wrap: wrap; gap: 0.3rem; } .cm-tab-btn { display: inline-flex; align-items: center; gap: 0.4rem; border: none; background: transparent; color: var(--cm-text-muted); font-size: 0.8125rem; font-weight: 600; padding: 0.5rem 0.9rem; border-radius: var(--cm-radius-sm); } .cm-tab-btn:hover { background: var(--cm-slate-muted); color: var(--cm-text); } .cm-tab-btn.is-active { background: var(--cm-accent); color: #fff; } .cm-tab-count { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 5px; border-radius: 999px; background: rgba(255,255,255,.25); font-size: 0.7rem; font-weight: 700; } .cm-tab-btn:not(.is-active) .cm-tab-count { background: var(--cm-accent-muted); color: var(--cm-accent); } /* ── Bulk-allocate action bar (Unallocated tab) ─────────────── */ .cm-bulk-bar { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; } .cm-bulk-bar label { font-size: 0.8125rem; font-weight: 600; color: var(--cm-text-muted); white-space: nowrap; } .cm-bulk-bar .form-control, .cm-bulk-bar .form-select { font-size: 0.8125rem; padding: 0.4rem 0.65rem; } /* ── Filter row ──────────────────────────────────────────────── */ .cm-filter-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-bottom: 0.75rem; } .cm-filter-row .form-control, .cm-filter-row .form-select { font-size: 0.8125rem; padding: 0.45rem 0.75rem; border-color: var(--cm-border); } .cm-filter-search { position: relative; flex: 1 1 220px; max-width: 280px; } .cm-filter-search i { position: absolute; left: 0.7rem; top: 50%; transform: translateY(-50%); color: var(--cm-text-light); font-size: 0.8rem; } .cm-filter-search input { padding-left: 2rem; } .cm-reset-link { color: var(--cm-red); font-size: 0.8125rem; font-weight: 600; background: none; border: none; display: inline-flex; align-items: center; gap: 0.3rem; } /* ── Expandable line rows ───────────────────────────────────── */ .cm-expand-toggle { border: none; background: none; color: var(--cm-accent); display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 6px; } .cm-expand-toggle:hover { background: var(--cm-accent-muted); } .cm-expand-toggle i { transition: transform .15s ease; } .cm-expand-toggle.is-open i { transform: rotate(90deg); } .cm-row-subtext { font-size: 0.7rem; color: var(--cm-text-muted); margin-top: 1px; } .cm-row-link { color: var(--cm-accent); font-weight: 600; text-decoration: none; } .cm-breakdown-row td { background: var(--cm-slate-muted); padding: 0 !important; } .cm-breakdown-panel { padding: 0.9rem 1.1rem 1.1rem; } .cm-breakdown-title { font-size: 0.75rem; font-weight: 700; color: var(--cm-text-muted); text-transform: uppercase; letter-spacing: .03em; margin-bottom: 0.5rem; } /* ── Pagination footer ──────────────────────────────────────── */ .cm-pagination-footer { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; padding: 0.85rem 1.1rem; font-size: 0.8125rem; color: var(--cm-text-muted); } .cm-pagination-pages { display: flex; align-items: center; gap: 0.25rem; } .cm-page-btn { min-width: 30px; height: 30px; padding: 0 0.4rem; border-radius: 7px; border: 1px solid var(--cm-border); background: var(--cm-surface); color: var(--cm-text-muted); font-size: 0.8125rem; font-weight: 600; } .cm-page-btn:hover:not(:disabled) { border-color: var(--cm-accent); color: var(--cm-accent); } .cm-page-btn.is-active { background: var(--cm-accent); border-color: var(--cm-accent); color: #fff; } .cm-page-btn:disabled { opacity: 0.4; cursor: not-allowed; } /* ── Overwrite modal ─────────────────────────────────────────── */ .cm-overwrite-list { border: 1px solid var(--cm-blue); border-radius: var(--cm-radius-sm); overflow: hidden; } .cm-overwrite-row { display: grid; grid-template-columns: 1fr 1.4fr 0.9fr; gap: 0.75rem; align-items: center; padding: 0.6rem 0.9rem; border-bottom: 1px dashed var(--cm-border); } .cm-overwrite-row:last-child { border-bottom: none; } .cm-overwrite-row-label { font-size: 0.8125rem; font-weight: 600; color: var(--cm-text); } .cm-overwrite-pct-input { position: relative; } .cm-overwrite-pct-input input { padding-right: 1.75rem; } .cm-overwrite-pct-input i { position: absolute; right: 0.65rem; top: 50%; transform: translateY(-50%); color: var(--cm-text-light); font-size: 0.75rem; } .cm-overwrite-total { font-size: 0.75rem; font-weight: 600; margin-top: 0.5rem; text-align: right; } .cm-overwrite-total.is-invalid { color: var(--cm-red); } .cm-overwrite-total.is-valid { color: var(--cm-green); } .cm-empty-state { text-align: center; padding: 2.5rem 1rem; color: var(--cm-text-muted); font-size: 0.8125rem; } .cm-checkbox { width: 16px; height: 16px; cursor: pointer; } @media (max-width: 992px) { .cm-overwrite-row { grid-template-columns: 1fr; gap: 0.35rem; } } /* ── Responsive tweaks ───────────────────────────────────────── */ @media (max-width: 576px) { .cm-kpi-value { font-size: 1.25rem; } .cm-page-head h3, .cm-page-head .cm-title { font-size: 1.25rem; } }
2026-09-22 22:25:19.074 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:bbe9601adf5d6a3d3f61a151b790adcd] HTTP GET /UI responded 200 in 1.0626 ms
2026-09-22 22:25:19.074 +00:00 [INF] [HTTP] [U:-] [E:-] [C:816d309692b3] [T:bbe9601adf5d6a3d3f61a151b790adcd] HTTP GET /UI 200
Req: [no body] Res: <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Home — WM Policy Documents</title> <link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" /> <link rel="stylesheet" href="/css/commissions.css?v=ZRMXSlMSxdLsHmJCZzq1LopWaopJSbVXKu57gvUJG3w" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" /> <style> /* ---- Hover-expand left sidebar -------------------------------------- */ :root { --sb-collapsed: 64px; --sb-expanded: 240px; } body.has-sidebar { /* Reserve space for the collapsed rail; the expanded panel overlays the content on hover, so the content never shifts. */ padding-left: var(--sb-collapsed); } .app-sidebar { position: fixed; top: 0; left: 0; height: 100vh; width: var(--sb-collapsed); overflow-x: hidden; overflow-y: auto; display: flex; flex-direction: column; z-index: 1045; transition: width 0.2s ease; } .app-sidebar:hover, .app-sidebar:focus-within { width: var(--sb-expanded); box-shadow: 0 0 24px rgba(0,0,0,0.35); } .app-sidebar .sb-label { white-space: nowrap; opacity: 0; transition: opacity 0.15s ease; } .app-sidebar:hover .sb-label, .app-sidebar:focus-within .sb-label { opacity: 1; } .sb-link { display: flex; align-items: center; gap: 0.85rem; padding: 0.65rem 0; color: rgba(255,255,255,0.75); text-decoration: none; border-left: 3px solid transparent; } .sb-link:hover { color: #fff; background: rgba(255,255,255,0.08); } .sb-link.active { color: #fff; background: rgba(255,255,255,0.12); border-left-color: #0d6efd; } .sb-link > i:first-child { min-width: var(--sb-collapsed); text-align: center; font-size: 1.15rem; flex-shrink: 0; } .sb-brand { display: flex; align-items: center; gap: 0.85rem; padding: 0.9rem 0; color: #fff; text-decoration: none; font-weight: 700; } .sb-brand > i:first-child { min-width: var(--sb-collapsed); text-align: center; font-size: 1.3rem; flex-shrink: 0; } /* Sub-menu (Fact-Find) */ .sb-submenu .sb-link { font-size: 0.9rem; padding-left: 0; } .sb-submenu .sb-link > i:first-child { font-size: 1rem; } .sb-caret { margin-left: auto; margin-right: 0.9rem; transition: transform 0.15s ease; } .sb-link[aria-expanded="true"] .sb-caret { transform: rotate(180deg); } </style> </head> <body class="d-flex flex-column min-vh-100 has-sidebar"> <nav b-yjl2sbey1b class="app-sidebar navbar-dark bg-dark shadow-sm"> <a class="sb-brand" href="/UI"> <i b-yjl2sbey1b class="bi bi-file-earmark-text"></i> <span b-yjl2sbey1b class="sb-label">Wealthmax</span> </a> <div b-yjl2sbey1b class="d-flex flex-column flex-grow-1"> <a class="sb-link " href="/UI/Dashboard/Index"> <i b-yjl2sbey1b class="bi bi-speedometer2"></i><span b-yjl2sbey1b class="sb-label">Dashboard</span> </a> <a class="sb-link " href="/UI/Templates/Index"> <i b-yjl2sbey1b class="bi bi-collection"></i><span b-yjl2sbey1b class="sb-label">Templates</span> </a> <a class="sb-link " href="/UI/Tokens/Index"> <i b-yjl2sbey1b class="bi bi-braces"></i><span b-yjl2sbey1b class="sb-label">Token Registry</span> </a> <a class="sb-link " href="/UI/Clients/Index"> <i b-yjl2sbey1b class="bi bi-people"></i><span b-yjl2sbey1b class="sb-label">Clients</span> </a> <a class="sb-link " href="/UI/Cases/Index"> <i b-yjl2sbey1b class="bi bi-briefcase"></i><span b-yjl2sbey1b class="sb-label">Cases</span> </a> <a class="sb-link " href="/UI/Reporting/Index"> <i b-yjl2sbey1b class="bi bi-graph-up"></i><span b-yjl2sbey1b class="sb-label">Reports</span> </a> <a class="sb-link " href="/UI/Commissions/Management"> <i b-yjl2sbey1b class="bi bi-cash-coin"></i><span b-yjl2sbey1b class="sb-label">Commissions</span> </a> <!-- User Management --> <a class="sb-link " href="/UI/Users/Index"> <i b-yjl2sbey1b class="bi bi-person-gear"></i><span b-yjl2sbey1b class="sb-label">User Management</span> </a> <!-- Fact-Find (expandable sub-menu) --> <a b-yjl2sbey1b class="sb-link " href="#ffSubmenu" role="button" data-bs-toggle="collapse" aria-expanded="false"> <i b-yjl2sbey1b class="bi bi-file-earmark-text"></i><span b-yjl2sbey1b class="sb-label">Fact-Find</span> <i b-yjl2sbey1b class="bi bi-chevron-down sb-caret sb-label"></i> </a> <div b-yjl2sbey1b class="collapse sb-submenu " id="ffSubmenu"> <a class="sb-link " href="/UI/FactFindFormatters/Index"> <i b-yjl2sbey1b class="bi bi-grid"></i><span b-yjl2sbey1b class="sb-label">Formatters</span> </a> <a class="sb-link " href="/UI/FactFindTemplates/Index"> <i b-yjl2sbey1b class="bi bi-layers"></i><span b-yjl2sbey1b class="sb-label">Templates</span> </a> <a class="sb-link " href="/UI/FactFindGenerate"> <i b-yjl2sbey1b class="bi bi-lightning-charge"></i><span b-yjl2sbey1b class="sb-label">Generate &amp; Preview</span> </a> </div> </div> <!-- Auth (pinned to bottom) --> <div b-yjl2sbey1b class="mt-auto border-top border-secondary"> <a b-yjl2sbey1b class="sb-link" href="/UI/business/login"> <i b-yjl2sbey1b class="bi bi-box-arrow-in-right"></i><span b-yjl2sbey1b class="sb-label">Business login</span> </a> </div> </nav> <main b-yjl2sbey1b class="flex-grow-1 py-4"> <div b-yjl2sbey1b class="container-fluid px-4"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"> <style> body > nav.navbar { position: sticky; top: 0; z-index: 1030; } .dash-hero { background: linear-gradient(135deg, #212529 0%, #343a40 100%); color: #fff; } .dash-card { border: none; border-radius: 12px; transition: transform 0.15s ease, box-shadow 0.15s ease; } .dash-card:hover { transform: translateY(-3px); box-shadow: 0 8px 24px rgba(0,0,0,0.10) !important; } .dash-icon { width: 48px; height: 48px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 1.4rem; } .dash-stat-value { font-size: 2rem; font-weight: 700; line-height: 1; } .dash-card-title { font-size: 0.95rem; font-weight: 600; } .dash-card-text { font-size: 0.78rem; } /* Discreet business-login link pinned to the bottom-right corner. */ .home-login-link { position: fixed; bottom: 1rem; right: 1.25rem; z-index: 1040; } </style> <!-- Hero --> <div class="dash-hero py-4 mb-4"> <div class="container text-center"> <h1 class="display-6 fw-bold mb-2">Wealthmax PM CRM</h1> <p class="lead text-white-50 mb-0" style="max-width: 640px; margin: 0 auto;"> Testing harness dashboard &mdash; system tools, integrations, and live service health at a glance. </p> </div> </div> <div class="container pb-5"> <!-- Tool / Integration cards --> <div class="row g-3 mb-4"> <!-- Tenants Created --> <div class="col-6 col-md-4 col-lg-3"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="d-flex align-items-start justify-content-between mb-2"> <div class="dash-icon bg-primary bg-opacity-10 text-primary"> <i class="bi bi-building-fill"></i> </div> <span class="badge bg-secondary bg-opacity-10 text-secondary">Sample</span> </div> <div class="dash-stat-value text-dark">12</div> <div class="dash-card-title text-dark mt-1">Tenants Created</div> <p class="dash-card-text text-muted mb-0">Total onboarded tenants in this environment.</p> </div> </div> </div> <!-- Build Logs --> <div class="col-6 col-md-4 col-lg-3"> <a href="/UI/DevLogs" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-dark bg-opacity-10 text-dark mb-2"> <i class="bi bi-terminal-fill"></i> </div> <div class="dash-card-title text-dark">Build &amp; App Logs</div> <p class="dash-card-text text-muted mb-0">Browse structured application logs by date and level.</p> </div> </div> </a> </div> <!-- Swagger --> <div class="col-6 col-md-4 col-lg-3"> <a href="/swagger" target="_blank" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="d-flex align-items-start justify-content-between mb-2"> <div class="dash-icon bg-success bg-opacity-10 text-success"> <i class="bi bi-braces"></i> </div> <i class="bi bi-box-arrow-up-right text-muted small"></i> </div> <div class="dash-card-title text-dark">Swagger / API Docs</div> <p class="dash-card-text text-muted mb-0">Explore and try the REST API via OpenAPI UI.</p> </div> </div> </a> </div> <!-- SignalR --> <div class="col-6 col-md-4 col-lg-3"> <a href="/test-signalr.html" target="_blank" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="d-flex align-items-start justify-content-between mb-2"> <div class="dash-icon bg-info bg-opacity-10 text-info"> <i class="bi bi-broadcast"></i> </div> <i class="bi bi-box-arrow-up-right text-muted small"></i> </div> <div class="dash-card-title text-dark">SignalR Hub</div> <p class="dash-card-text text-muted mb-0">Test real-time notifications over the SignalR hub.</p> </div> </div> </a> </div> <!-- iPipeline --> <div class="col-6 col-md-4 col-lg-3"> <a href="/demo/solution-builder" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-warning bg-opacity-10 text-warning mb-2"> <i class="bi bi-plug-fill"></i> </div> <div class="dash-card-title text-dark">iPipeline</div> <p class="dash-card-text text-muted mb-0">Launch the iPipeline Solution Builder integration.</p> </div> </div> </a> </div> <!-- Fetch Quotes --> <div class="col-6 col-md-4 col-lg-3"> <a href="/demo/solution-builder/events" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-danger bg-opacity-10 text-danger mb-2"> <i class="bi bi-receipt"></i> </div> <div class="dash-card-title text-dark">Fetch Quotes</div> <p class="dash-card-text text-muted mb-0">View quote-notification events returned from the pipeline.</p> </div> </div> </a> </div> <!-- CRM Dashboard --> <div class="col-6 col-md-4 col-lg-3"> <a class="text-decoration-none" href="/UI/Dashboard/Index"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-primary bg-opacity-10 text-primary mb-2"> <i class="bi bi-speedometer2"></i> </div> <div class="dash-card-title text-dark">CRM Dashboard</div> <p class="dash-card-text text-muted mb-0">Cases, clients, and commission overview metrics.</p> </div> </div> </a> </div> <!-- Clients --> <div class="col-6 col-md-4 col-lg-3"> <a class="text-decoration-none" href="/UI/Clients/Index"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-success bg-opacity-10 text-success mb-2"> <i class="bi bi-people-fill"></i> </div> <div class="dash-card-title text-dark">Clients &amp; Cases</div> <p class="dash-card-text text-muted mb-0">Manage client records and advisory cases.</p> </div> </div> </a> </div> </div> <!-- System Health --> <div id="health-card" class="card dash-card shadow-sm mb-4"> <div class="card-body p-3"> <!-- Loading state --> <div id="health-loading" class="text-center py-3"> <div class="spinner-border spinner-border-sm text-primary" role="status"> <span class="visually-hidden">Loading...</span> </div> <span class="ms-2 text-muted">Checking system health...</span> </div> <!-- Error state --> <div id="health-error" class="d-none text-center py-3"> <i class="bi bi-exclamation-triangle fs-4 text-danger d-block mb-2"></i> <p class="text-muted mb-1">Unable to reach the health endpoint.</p> <button class="btn btn-sm btn-outline-secondary" onclick="fetchHealth()"> <i class="bi bi-arrow-clockwise me-1"></i>Retry </button> </div> <!-- Success state --> <div id="health-content" class="d-none"> <div class="d-flex align-items-center mb-3"> <i class="bi bi-heart-pulse fs-4 text-primary me-2"></i> <h5 class="fw-semibold mb-0 me-auto">System Health</h5> <span id="health-status-badge" class="badge"></span> </div> <hr class="my-3"> <div class="row g-2 small"> <div class="col-sm-6"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-clock me-2"></i> <span>Checked: <span id="health-timestamp" class="text-body"></span></span> </div> </div> <div class="col-sm-6"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-speedometer2 me-2"></i> <span>Response: <span id="health-duration" class="text-body"></span></span> </div> </div> <div class="col-sm-6 d-none" id="health-db-row"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-database me-2"></i> <span>Database: <span id="health-database" class="text-body"></span></span> </div> </div> <div class="col-sm-6 d-none" id="health-build-row"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-git me-2"></i> <span>Build: <code id="health-commit"></code> <span id="health-build-date" class="text-muted"></span></span> </div> </div> </div> </div> </div> </div> <!-- Tech Stack --> <div class="text-center"> <div class="d-flex flex-wrap justify-content-center gap-3 text-muted small"> <span><i class="bi bi-gear me-1"></i>.NET 10</span> <span class="text-black-50">|</span> <span><i class="bi bi-database me-1"></i>PostgreSQL</span> <span class="text-black-50">|</span> <span><i class="bi bi-layers me-1"></i>Entity Framework Core</span> <span class="text-black-50">|</span> <span><i class="bi bi-lock me-1"></i>JWT Authentication</span> <span class="text-black-50">|</span> <span><i class="bi bi-book me-1"></i>OpenAPI / Swagger</span> </div> </div> </div> </content> </div> </main> <footer b-yjl2sbey1b class="bg-light border-top py-2 text-center text-muted small"> Wealthmax PM CRM &mdash; Policy Document Testing UI </footer> <script src="/lib/jquery/dist/jquery.min.js"></script> <script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="/js/site.js?v=y_Ngd8W21UpuCUhEqGbUKDEqFnNfTjAfb24GhJJGUyM"></script> <script> function escapeHtml(text) { var div = document.createElement('div'); div.appendChild(document.createTextNode(text)); return div.innerHTML; } function statusBadgeClass(status) { switch ((status || '').toLowerCase()) { case 'healthy': return 'bg-success'; case 'degraded': return 'bg-warning text-dark'; default: return 'bg-danger'; } } function fetchHealth() { document.getElementById('health-loading').classList.remove('d-none'); document.getElementById('health-error').classList.add('d-none'); document.getElementById('health-content').classList.add('d-none'); fetch('/api/health') .then(function (response) { if (response.ok || response.status === 503) { return response.json(); } throw new Error('Unexpected status: ' + response.status); }) .then(function (response) { var health = response.data || response; renderHealth(health); document.getElementById('health-loading').classList.add('d-none'); document.getElementById('health-content').classList.remove('d-none'); }) .catch(function () { document.getElementById('health-loading').classList.add('d-none'); document.getElementById('health-error').classList.remove('d-none'); }); } function renderHealth(data) { var badge = document.getElementById('health-status-badge'); badge.textContent = data.status; badge.className = 'badge ' + statusBadgeClass(data.status); document.getElementById('health-timestamp').textContent = new Date(data.timestamp).toLocaleString(); document.getElementById('health-duration').textContent = data.totalDurationMs + ' ms'; var dbRow = document.getElementById('health-db-row'); if (data.databaseName || data.databaseProvider) { var parts = []; if (data.databaseName) parts.push(data.databaseName); if (data.databaseProvider) parts.push(data.databaseProvider); document.getElementById('health-database').textContent = parts.join(' on '); dbRow.classList.remove('d-none'); } else { dbRow.classList.add('d-none'); } var buildRow = document.getElementById('health-build-row'); if (data.commitHash || data.lastBuildDate) { document.getElementById('health-commit').textContent = data.commitHash || ''; document.getElementById('health-build-date').textContent = data.lastBuildDate ? '(' + new Date(data.lastBuildDate).toLocaleDateString() + ')' : ''; buildRow.classList.remove('d-none'); } else { buildRow.classList.add('d-none'); } } fetchHealth(); </script> </body> </html>
2026-09-22 22:24:46.670 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:a878f81d4fdc34ffcfb83d156e26e727] HTTP GET /.env responded 401 in 0.2912 ms
2026-09-22 22:24:46.622 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:c78ef4fd43ba2e46f806d212fc5c8d0b] HTTP GET /.env responded 401 in 0.4559 ms
2026-09-22 22:20:12.078 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:a0d2af9c40f9b23317b34f9dffccad1a] HTTP GET / responded 200 in 1.1068 ms
2026-09-22 22:20:12.078 +00:00 [INF] [HTTP] [U:-] [E:-] [C:74f727922dd5] [T:a0d2af9c40f9b23317b34f9dffccad1a] HTTP GET / 200
Req: [no body] Res: <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Home — WM Policy Documents</title> <link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" /> <link rel="stylesheet" href="/css/commissions.css?v=ZRMXSlMSxdLsHmJCZzq1LopWaopJSbVXKu57gvUJG3w" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" /> <style> /* ---- Hover-expand left sidebar -------------------------------------- */ :root { --sb-collapsed: 64px; --sb-expanded: 240px; } body.has-sidebar { /* Reserve space for the collapsed rail; the expanded panel overlays the content on hover, so the content never shifts. */ padding-left: var(--sb-collapsed); } .app-sidebar { position: fixed; top: 0; left: 0; height: 100vh; width: var(--sb-collapsed); overflow-x: hidden; overflow-y: auto; display: flex; flex-direction: column; z-index: 1045; transition: width 0.2s ease; } .app-sidebar:hover, .app-sidebar:focus-within { width: var(--sb-expanded); box-shadow: 0 0 24px rgba(0,0,0,0.35); } .app-sidebar .sb-label { white-space: nowrap; opacity: 0; transition: opacity 0.15s ease; } .app-sidebar:hover .sb-label, .app-sidebar:focus-within .sb-label { opacity: 1; } .sb-link { display: flex; align-items: center; gap: 0.85rem; padding: 0.65rem 0; color: rgba(255,255,255,0.75); text-decoration: none; border-left: 3px solid transparent; } .sb-link:hover { color: #fff; background: rgba(255,255,255,0.08); } .sb-link.active { color: #fff; background: rgba(255,255,255,0.12); border-left-color: #0d6efd; } .sb-link > i:first-child { min-width: var(--sb-collapsed); text-align: center; font-size: 1.15rem; flex-shrink: 0; } .sb-brand { display: flex; align-items: center; gap: 0.85rem; padding: 0.9rem 0; color: #fff; text-decoration: none; font-weight: 700; } .sb-brand > i:first-child { min-width: var(--sb-collapsed); text-align: center; font-size: 1.3rem; flex-shrink: 0; } /* Sub-menu (Fact-Find) */ .sb-submenu .sb-link { font-size: 0.9rem; padding-left: 0; } .sb-submenu .sb-link > i:first-child { font-size: 1rem; } .sb-caret { margin-left: auto; margin-right: 0.9rem; transition: transform 0.15s ease; } .sb-link[aria-expanded="true"] .sb-caret { transform: rotate(180deg); } </style> </head> <body class="d-flex flex-column min-vh-100 has-sidebar"> <nav b-yjl2sbey1b class="app-sidebar navbar-dark bg-dark shadow-sm"> <a class="sb-brand" href="/UI"> <i b-yjl2sbey1b class="bi bi-file-earmark-text"></i> <span b-yjl2sbey1b class="sb-label">Wealthmax</span> </a> <div b-yjl2sbey1b class="d-flex flex-column flex-grow-1"> <a class="sb-link " href="/UI/Dashboard/Index"> <i b-yjl2sbey1b class="bi bi-speedometer2"></i><span b-yjl2sbey1b class="sb-label">Dashboard</span> </a> <a class="sb-link " href="/UI/Templates/Index"> <i b-yjl2sbey1b class="bi bi-collection"></i><span b-yjl2sbey1b class="sb-label">Templates</span> </a> <a class="sb-link " href="/UI/Tokens/Index"> <i b-yjl2sbey1b class="bi bi-braces"></i><span b-yjl2sbey1b class="sb-label">Token Registry</span> </a> <a class="sb-link " href="/UI/Clients/Index"> <i b-yjl2sbey1b class="bi bi-people"></i><span b-yjl2sbey1b class="sb-label">Clients</span> </a> <a class="sb-link " href="/UI/Cases/Index"> <i b-yjl2sbey1b class="bi bi-briefcase"></i><span b-yjl2sbey1b class="sb-label">Cases</span> </a> <a class="sb-link " href="/UI/Reporting/Index"> <i b-yjl2sbey1b class="bi bi-graph-up"></i><span b-yjl2sbey1b class="sb-label">Reports</span> </a> <a class="sb-link " href="/UI/Commissions/Management"> <i b-yjl2sbey1b class="bi bi-cash-coin"></i><span b-yjl2sbey1b class="sb-label">Commissions</span> </a> <!-- User Management --> <a class="sb-link " href="/UI/Users/Index"> <i b-yjl2sbey1b class="bi bi-person-gear"></i><span b-yjl2sbey1b class="sb-label">User Management</span> </a> <!-- Fact-Find (expandable sub-menu) --> <a b-yjl2sbey1b class="sb-link " href="#ffSubmenu" role="button" data-bs-toggle="collapse" aria-expanded="false"> <i b-yjl2sbey1b class="bi bi-file-earmark-text"></i><span b-yjl2sbey1b class="sb-label">Fact-Find</span> <i b-yjl2sbey1b class="bi bi-chevron-down sb-caret sb-label"></i> </a> <div b-yjl2sbey1b class="collapse sb-submenu " id="ffSubmenu"> <a class="sb-link " href="/UI/FactFindFormatters/Index"> <i b-yjl2sbey1b class="bi bi-grid"></i><span b-yjl2sbey1b class="sb-label">Formatters</span> </a> <a class="sb-link " href="/UI/FactFindTemplates/Index"> <i b-yjl2sbey1b class="bi bi-layers"></i><span b-yjl2sbey1b class="sb-label">Templates</span> </a> <a class="sb-link " href="/UI/FactFindGenerate"> <i b-yjl2sbey1b class="bi bi-lightning-charge"></i><span b-yjl2sbey1b class="sb-label">Generate &amp; Preview</span> </a> </div> </div> <!-- Auth (pinned to bottom) --> <div b-yjl2sbey1b class="mt-auto border-top border-secondary"> <a b-yjl2sbey1b class="sb-link" href="/UI/business/login"> <i b-yjl2sbey1b class="bi bi-box-arrow-in-right"></i><span b-yjl2sbey1b class="sb-label">Business login</span> </a> </div> </nav> <main b-yjl2sbey1b class="flex-grow-1 py-4"> <div b-yjl2sbey1b class="container-fluid px-4"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"> <style> body > nav.navbar { position: sticky; top: 0; z-index: 1030; } .dash-hero { background: linear-gradient(135deg, #212529 0%, #343a40 100%); color: #fff; } .dash-card { border: none; border-radius: 12px; transition: transform 0.15s ease, box-shadow 0.15s ease; } .dash-card:hover { transform: translateY(-3px); box-shadow: 0 8px 24px rgba(0,0,0,0.10) !important; } .dash-icon { width: 48px; height: 48px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 1.4rem; } .dash-stat-value { font-size: 2rem; font-weight: 700; line-height: 1; } .dash-card-title { font-size: 0.95rem; font-weight: 600; } .dash-card-text { font-size: 0.78rem; } /* Discreet business-login link pinned to the bottom-right corner. */ .home-login-link { position: fixed; bottom: 1rem; right: 1.25rem; z-index: 1040; } </style> <!-- Hero --> <div class="dash-hero py-4 mb-4"> <div class="container text-center"> <h1 class="display-6 fw-bold mb-2">Wealthmax PM CRM</h1> <p class="lead text-white-50 mb-0" style="max-width: 640px; margin: 0 auto;"> Testing harness dashboard &mdash; system tools, integrations, and live service health at a glance. </p> </div> </div> <div class="container pb-5"> <!-- Tool / Integration cards --> <div class="row g-3 mb-4"> <!-- Tenants Created --> <div class="col-6 col-md-4 col-lg-3"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="d-flex align-items-start justify-content-between mb-2"> <div class="dash-icon bg-primary bg-opacity-10 text-primary"> <i class="bi bi-building-fill"></i> </div> <span class="badge bg-secondary bg-opacity-10 text-secondary">Sample</span> </div> <div class="dash-stat-value text-dark">12</div> <div class="dash-card-title text-dark mt-1">Tenants Created</div> <p class="dash-card-text text-muted mb-0">Total onboarded tenants in this environment.</p> </div> </div> </div> <!-- Build Logs --> <div class="col-6 col-md-4 col-lg-3"> <a href="/UI/DevLogs" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-dark bg-opacity-10 text-dark mb-2"> <i class="bi bi-terminal-fill"></i> </div> <div class="dash-card-title text-dark">Build &amp; App Logs</div> <p class="dash-card-text text-muted mb-0">Browse structured application logs by date and level.</p> </div> </div> </a> </div> <!-- Swagger --> <div class="col-6 col-md-4 col-lg-3"> <a href="/swagger" target="_blank" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="d-flex align-items-start justify-content-between mb-2"> <div class="dash-icon bg-success bg-opacity-10 text-success"> <i class="bi bi-braces"></i> </div> <i class="bi bi-box-arrow-up-right text-muted small"></i> </div> <div class="dash-card-title text-dark">Swagger / API Docs</div> <p class="dash-card-text text-muted mb-0">Explore and try the REST API via OpenAPI UI.</p> </div> </div> </a> </div> <!-- SignalR --> <div class="col-6 col-md-4 col-lg-3"> <a href="/test-signalr.html" target="_blank" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="d-flex align-items-start justify-content-between mb-2"> <div class="dash-icon bg-info bg-opacity-10 text-info"> <i class="bi bi-broadcast"></i> </div> <i class="bi bi-box-arrow-up-right text-muted small"></i> </div> <div class="dash-card-title text-dark">SignalR Hub</div> <p class="dash-card-text text-muted mb-0">Test real-time notifications over the SignalR hub.</p> </div> </div> </a> </div> <!-- iPipeline --> <div class="col-6 col-md-4 col-lg-3"> <a href="/demo/solution-builder" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-warning bg-opacity-10 text-warning mb-2"> <i class="bi bi-plug-fill"></i> </div> <div class="dash-card-title text-dark">iPipeline</div> <p class="dash-card-text text-muted mb-0">Launch the iPipeline Solution Builder integration.</p> </div> </div> </a> </div> <!-- Fetch Quotes --> <div class="col-6 col-md-4 col-lg-3"> <a href="/demo/solution-builder/events" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-danger bg-opacity-10 text-danger mb-2"> <i class="bi bi-receipt"></i> </div> <div class="dash-card-title text-dark">Fetch Quotes</div> <p class="dash-card-text text-muted mb-0">View quote-notification events returned from the pipeline.</p> </div> </div> </a> </div> <!-- CRM Dashboard --> <div class="col-6 col-md-4 col-lg-3"> <a class="text-decoration-none" href="/UI/Dashboard/Index"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-primary bg-opacity-10 text-primary mb-2"> <i class="bi bi-speedometer2"></i> </div> <div class="dash-card-title text-dark">CRM Dashboard</div> <p class="dash-card-text text-muted mb-0">Cases, clients, and commission overview metrics.</p> </div> </div> </a> </div> <!-- Clients --> <div class="col-6 col-md-4 col-lg-3"> <a class="text-decoration-none" href="/UI/Clients/Index"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-success bg-opacity-10 text-success mb-2"> <i class="bi bi-people-fill"></i> </div> <div class="dash-card-title text-dark">Clients &amp; Cases</div> <p class="dash-card-text text-muted mb-0">Manage client records and advisory cases.</p> </div> </div> </a> </div> </div> <!-- System Health --> <div id="health-card" class="card dash-card shadow-sm mb-4"> <div class="card-body p-3"> <!-- Loading state --> <div id="health-loading" class="text-center py-3"> <div class="spinner-border spinner-border-sm text-primary" role="status"> <span class="visually-hidden">Loading...</span> </div> <span class="ms-2 text-muted">Checking system health...</span> </div> <!-- Error state --> <div id="health-error" class="d-none text-center py-3"> <i class="bi bi-exclamation-triangle fs-4 text-danger d-block mb-2"></i> <p class="text-muted mb-1">Unable to reach the health endpoint.</p> <button class="btn btn-sm btn-outline-secondary" onclick="fetchHealth()"> <i class="bi bi-arrow-clockwise me-1"></i>Retry </button> </div> <!-- Success state --> <div id="health-content" class="d-none"> <div class="d-flex align-items-center mb-3"> <i class="bi bi-heart-pulse fs-4 text-primary me-2"></i> <h5 class="fw-semibold mb-0 me-auto">System Health</h5> <span id="health-status-badge" class="badge"></span> </div> <hr class="my-3"> <div class="row g-2 small"> <div class="col-sm-6"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-clock me-2"></i> <span>Checked: <span id="health-timestamp" class="text-body"></span></span> </div> </div> <div class="col-sm-6"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-speedometer2 me-2"></i> <span>Response: <span id="health-duration" class="text-body"></span></span> </div> </div> <div class="col-sm-6 d-none" id="health-db-row"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-database me-2"></i> <span>Database: <span id="health-database" class="text-body"></span></span> </div> </div> <div class="col-sm-6 d-none" id="health-build-row"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-git me-2"></i> <span>Build: <code id="health-commit"></code> <span id="health-build-date" class="text-muted"></span></span> </div> </div> </div> </div> </div> </div> <!-- Tech Stack --> <div class="text-center"> <div class="d-flex flex-wrap justify-content-center gap-3 text-muted small"> <span><i class="bi bi-gear me-1"></i>.NET 10</span> <span class="text-black-50">|</span> <span><i class="bi bi-database me-1"></i>PostgreSQL</span> <span class="text-black-50">|</span> <span><i class="bi bi-layers me-1"></i>Entity Framework Core</span> <span class="text-black-50">|</span> <span><i class="bi bi-lock me-1"></i>JWT Authentication</span> <span class="text-black-50">|</span> <span><i class="bi bi-book me-1"></i>OpenAPI / Swagger</span> </div> </div> </div> </content> </div> </main> <footer b-yjl2sbey1b class="bg-light border-top py-2 text-center text-muted small"> Wealthmax PM CRM &mdash; Policy Document Testing UI </footer> <script src="/lib/jquery/dist/jquery.min.js"></script> <script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="/js/site.js?v=y_Ngd8W21UpuCUhEqGbUKDEqFnNfTjAfb24GhJJGUyM"></script> <script> function escapeHtml(text) { var div = document.createElement('div'); div.appendChild(document.createTextNode(text)); return div.innerHTML; } function statusBadgeClass(status) { switch ((status || '').toLowerCase()) { case 'healthy': return 'bg-success'; case 'degraded': return 'bg-warning text-dark'; default: return 'bg-danger'; } } function fetchHealth() { document.getElementById('health-loading').classList.remove('d-none'); document.getElementById('health-error').classList.add('d-none'); document.getElementById('health-content').classList.add('d-none'); fetch('/api/health') .then(function (response) { if (response.ok || response.status === 503) { return response.json(); } throw new Error('Unexpected status: ' + response.status); }) .then(function (response) { var health = response.data || response; renderHealth(health); document.getElementById('health-loading').classList.add('d-none'); document.getElementById('health-content').classList.remove('d-none'); }) .catch(function () { document.getElementById('health-loading').classList.add('d-none'); document.getElementById('health-error').classList.remove('d-none'); }); } function renderHealth(data) { var badge = document.getElementById('health-status-badge'); badge.textContent = data.status; badge.className = 'badge ' + statusBadgeClass(data.status); document.getElementById('health-timestamp').textContent = new Date(data.timestamp).toLocaleString(); document.getElementById('health-duration').textContent = data.totalDurationMs + ' ms'; var dbRow = document.getElementById('health-db-row'); if (data.databaseName || data.databaseProvider) { var parts = []; if (data.databaseName) parts.push(data.databaseName); if (data.databaseProvider) parts.push(data.databaseProvider); document.getElementById('health-database').textContent = parts.join(' on '); dbRow.classList.remove('d-none'); } else { dbRow.classList.add('d-none'); } var buildRow = document.getElementById('health-build-row'); if (data.commitHash || data.lastBuildDate) { document.getElementById('health-commit').textContent = data.commitHash || ''; document.getElementById('health-build-date').textContent = data.lastBuildDate ? '(' + new Date(data.lastBuildDate).toLocaleDateString() + ')' : ''; buildRow.classList.remove('d-none'); } else { buildRow.classList.add('d-none'); } } fetchHealth(); </script> </body> </html>
2026-09-22 22:20:02.523 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:bf7a2949eca4f45c7e92147335fa33d4] HTTP GET /robots.txt responded 401 in 0.4968 ms
2026-09-22 22:09:28.268 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:2b26791f892addb4871122464d613441] HTTP GET /enhancecp responded 401 in 0.2850 ms
2026-09-22 22:09:28.113 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:ce491a4501602d7f8008c75e93bf02c0] HTTP GET /robots.txt responded 401 in 0.4427 ms
2026-09-22 22:09:01.609 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:eed725a360400f9482cb79cf7be34955] HTTP GET / responded 200 in 0.9650 ms
2026-09-22 22:09:01.609 +00:00 [INF] [HTTP] [U:-] [E:-] [C:59ff68791e1a] [T:eed725a360400f9482cb79cf7be34955] HTTP GET / 200
Req: [no body] Res: <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Home — WM Policy Documents</title> <link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" /> <link rel="stylesheet" href="/css/commissions.css?v=ZRMXSlMSxdLsHmJCZzq1LopWaopJSbVXKu57gvUJG3w" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" /> <style> /* ---- Hover-expand left sidebar -------------------------------------- */ :root { --sb-collapsed: 64px; --sb-expanded: 240px; } body.has-sidebar { /* Reserve space for the collapsed rail; the expanded panel overlays the content on hover, so the content never shifts. */ padding-left: var(--sb-collapsed); } .app-sidebar { position: fixed; top: 0; left: 0; height: 100vh; width: var(--sb-collapsed); overflow-x: hidden; overflow-y: auto; display: flex; flex-direction: column; z-index: 1045; transition: width 0.2s ease; } .app-sidebar:hover, .app-sidebar:focus-within { width: var(--sb-expanded); box-shadow: 0 0 24px rgba(0,0,0,0.35); } .app-sidebar .sb-label { white-space: nowrap; opacity: 0; transition: opacity 0.15s ease; } .app-sidebar:hover .sb-label, .app-sidebar:focus-within .sb-label { opacity: 1; } .sb-link { display: flex; align-items: center; gap: 0.85rem; padding: 0.65rem 0; color: rgba(255,255,255,0.75); text-decoration: none; border-left: 3px solid transparent; } .sb-link:hover { color: #fff; background: rgba(255,255,255,0.08); } .sb-link.active { color: #fff; background: rgba(255,255,255,0.12); border-left-color: #0d6efd; } .sb-link > i:first-child { min-width: var(--sb-collapsed); text-align: center; font-size: 1.15rem; flex-shrink: 0; } .sb-brand { display: flex; align-items: center; gap: 0.85rem; padding: 0.9rem 0; color: #fff; text-decoration: none; font-weight: 700; } .sb-brand > i:first-child { min-width: var(--sb-collapsed); text-align: center; font-size: 1.3rem; flex-shrink: 0; } /* Sub-menu (Fact-Find) */ .sb-submenu .sb-link { font-size: 0.9rem; padding-left: 0; } .sb-submenu .sb-link > i:first-child { font-size: 1rem; } .sb-caret { margin-left: auto; margin-right: 0.9rem; transition: transform 0.15s ease; } .sb-link[aria-expanded="true"] .sb-caret { transform: rotate(180deg); } </style> </head> <body class="d-flex flex-column min-vh-100 has-sidebar"> <nav b-yjl2sbey1b class="app-sidebar navbar-dark bg-dark shadow-sm"> <a class="sb-brand" href="/UI"> <i b-yjl2sbey1b class="bi bi-file-earmark-text"></i> <span b-yjl2sbey1b class="sb-label">Wealthmax</span> </a> <div b-yjl2sbey1b class="d-flex flex-column flex-grow-1"> <a class="sb-link " href="/UI/Dashboard/Index"> <i b-yjl2sbey1b class="bi bi-speedometer2"></i><span b-yjl2sbey1b class="sb-label">Dashboard</span> </a> <a class="sb-link " href="/UI/Templates/Index"> <i b-yjl2sbey1b class="bi bi-collection"></i><span b-yjl2sbey1b class="sb-label">Templates</span> </a> <a class="sb-link " href="/UI/Tokens/Index"> <i b-yjl2sbey1b class="bi bi-braces"></i><span b-yjl2sbey1b class="sb-label">Token Registry</span> </a> <a class="sb-link " href="/UI/Clients/Index"> <i b-yjl2sbey1b class="bi bi-people"></i><span b-yjl2sbey1b class="sb-label">Clients</span> </a> <a class="sb-link " href="/UI/Cases/Index"> <i b-yjl2sbey1b class="bi bi-briefcase"></i><span b-yjl2sbey1b class="sb-label">Cases</span> </a> <a class="sb-link " href="/UI/Reporting/Index"> <i b-yjl2sbey1b class="bi bi-graph-up"></i><span b-yjl2sbey1b class="sb-label">Reports</span> </a> <a class="sb-link " href="/UI/Commissions/Management"> <i b-yjl2sbey1b class="bi bi-cash-coin"></i><span b-yjl2sbey1b class="sb-label">Commissions</span> </a> <!-- User Management --> <a class="sb-link " href="/UI/Users/Index"> <i b-yjl2sbey1b class="bi bi-person-gear"></i><span b-yjl2sbey1b class="sb-label">User Management</span> </a> <!-- Fact-Find (expandable sub-menu) --> <a b-yjl2sbey1b class="sb-link " href="#ffSubmenu" role="button" data-bs-toggle="collapse" aria-expanded="false"> <i b-yjl2sbey1b class="bi bi-file-earmark-text"></i><span b-yjl2sbey1b class="sb-label">Fact-Find</span> <i b-yjl2sbey1b class="bi bi-chevron-down sb-caret sb-label"></i> </a> <div b-yjl2sbey1b class="collapse sb-submenu " id="ffSubmenu"> <a class="sb-link " href="/UI/FactFindFormatters/Index"> <i b-yjl2sbey1b class="bi bi-grid"></i><span b-yjl2sbey1b class="sb-label">Formatters</span> </a> <a class="sb-link " href="/UI/FactFindTemplates/Index"> <i b-yjl2sbey1b class="bi bi-layers"></i><span b-yjl2sbey1b class="sb-label">Templates</span> </a> <a class="sb-link " href="/UI/FactFindGenerate"> <i b-yjl2sbey1b class="bi bi-lightning-charge"></i><span b-yjl2sbey1b class="sb-label">Generate &amp; Preview</span> </a> </div> </div> <!-- Auth (pinned to bottom) --> <div b-yjl2sbey1b class="mt-auto border-top border-secondary"> <a b-yjl2sbey1b class="sb-link" href="/UI/business/login"> <i b-yjl2sbey1b class="bi bi-box-arrow-in-right"></i><span b-yjl2sbey1b class="sb-label">Business login</span> </a> </div> </nav> <main b-yjl2sbey1b class="flex-grow-1 py-4"> <div b-yjl2sbey1b class="container-fluid px-4"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"> <style> body > nav.navbar { position: sticky; top: 0; z-index: 1030; } .dash-hero { background: linear-gradient(135deg, #212529 0%, #343a40 100%); color: #fff; } .dash-card { border: none; border-radius: 12px; transition: transform 0.15s ease, box-shadow 0.15s ease; } .dash-card:hover { transform: translateY(-3px); box-shadow: 0 8px 24px rgba(0,0,0,0.10) !important; } .dash-icon { width: 48px; height: 48px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 1.4rem; } .dash-stat-value { font-size: 2rem; font-weight: 700; line-height: 1; } .dash-card-title { font-size: 0.95rem; font-weight: 600; } .dash-card-text { font-size: 0.78rem; } /* Discreet business-login link pinned to the bottom-right corner. */ .home-login-link { position: fixed; bottom: 1rem; right: 1.25rem; z-index: 1040; } </style> <!-- Hero --> <div class="dash-hero py-4 mb-4"> <div class="container text-center"> <h1 class="display-6 fw-bold mb-2">Wealthmax PM CRM</h1> <p class="lead text-white-50 mb-0" style="max-width: 640px; margin: 0 auto;"> Testing harness dashboard &mdash; system tools, integrations, and live service health at a glance. </p> </div> </div> <div class="container pb-5"> <!-- Tool / Integration cards --> <div class="row g-3 mb-4"> <!-- Tenants Created --> <div class="col-6 col-md-4 col-lg-3"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="d-flex align-items-start justify-content-between mb-2"> <div class="dash-icon bg-primary bg-opacity-10 text-primary"> <i class="bi bi-building-fill"></i> </div> <span class="badge bg-secondary bg-opacity-10 text-secondary">Sample</span> </div> <div class="dash-stat-value text-dark">12</div> <div class="dash-card-title text-dark mt-1">Tenants Created</div> <p class="dash-card-text text-muted mb-0">Total onboarded tenants in this environment.</p> </div> </div> </div> <!-- Build Logs --> <div class="col-6 col-md-4 col-lg-3"> <a href="/UI/DevLogs" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-dark bg-opacity-10 text-dark mb-2"> <i class="bi bi-terminal-fill"></i> </div> <div class="dash-card-title text-dark">Build &amp; App Logs</div> <p class="dash-card-text text-muted mb-0">Browse structured application logs by date and level.</p> </div> </div> </a> </div> <!-- Swagger --> <div class="col-6 col-md-4 col-lg-3"> <a href="/swagger" target="_blank" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="d-flex align-items-start justify-content-between mb-2"> <div class="dash-icon bg-success bg-opacity-10 text-success"> <i class="bi bi-braces"></i> </div> <i class="bi bi-box-arrow-up-right text-muted small"></i> </div> <div class="dash-card-title text-dark">Swagger / API Docs</div> <p class="dash-card-text text-muted mb-0">Explore and try the REST API via OpenAPI UI.</p> </div> </div> </a> </div> <!-- SignalR --> <div class="col-6 col-md-4 col-lg-3"> <a href="/test-signalr.html" target="_blank" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="d-flex align-items-start justify-content-between mb-2"> <div class="dash-icon bg-info bg-opacity-10 text-info"> <i class="bi bi-broadcast"></i> </div> <i class="bi bi-box-arrow-up-right text-muted small"></i> </div> <div class="dash-card-title text-dark">SignalR Hub</div> <p class="dash-card-text text-muted mb-0">Test real-time notifications over the SignalR hub.</p> </div> </div> </a> </div> <!-- iPipeline --> <div class="col-6 col-md-4 col-lg-3"> <a href="/demo/solution-builder" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-warning bg-opacity-10 text-warning mb-2"> <i class="bi bi-plug-fill"></i> </div> <div class="dash-card-title text-dark">iPipeline</div> <p class="dash-card-text text-muted mb-0">Launch the iPipeline Solution Builder integration.</p> </div> </div> </a> </div> <!-- Fetch Quotes --> <div class="col-6 col-md-4 col-lg-3"> <a href="/demo/solution-builder/events" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-danger bg-opacity-10 text-danger mb-2"> <i class="bi bi-receipt"></i> </div> <div class="dash-card-title text-dark">Fetch Quotes</div> <p class="dash-card-text text-muted mb-0">View quote-notification events returned from the pipeline.</p> </div> </div> </a> </div> <!-- CRM Dashboard --> <div class="col-6 col-md-4 col-lg-3"> <a class="text-decoration-none" href="/UI/Dashboard/Index"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-primary bg-opacity-10 text-primary mb-2"> <i class="bi bi-speedometer2"></i> </div> <div class="dash-card-title text-dark">CRM Dashboard</div> <p class="dash-card-text text-muted mb-0">Cases, clients, and commission overview metrics.</p> </div> </div> </a> </div> <!-- Clients --> <div class="col-6 col-md-4 col-lg-3"> <a class="text-decoration-none" href="/UI/Clients/Index"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-success bg-opacity-10 text-success mb-2"> <i class="bi bi-people-fill"></i> </div> <div class="dash-card-title text-dark">Clients &amp; Cases</div> <p class="dash-card-text text-muted mb-0">Manage client records and advisory cases.</p> </div> </div> </a> </div> </div> <!-- System Health --> <div id="health-card" class="card dash-card shadow-sm mb-4"> <div class="card-body p-3"> <!-- Loading state --> <div id="health-loading" class="text-center py-3"> <div class="spinner-border spinner-border-sm text-primary" role="status"> <span class="visually-hidden">Loading...</span> </div> <span class="ms-2 text-muted">Checking system health...</span> </div> <!-- Error state --> <div id="health-error" class="d-none text-center py-3"> <i class="bi bi-exclamation-triangle fs-4 text-danger d-block mb-2"></i> <p class="text-muted mb-1">Unable to reach the health endpoint.</p> <button class="btn btn-sm btn-outline-secondary" onclick="fetchHealth()"> <i class="bi bi-arrow-clockwise me-1"></i>Retry </button> </div> <!-- Success state --> <div id="health-content" class="d-none"> <div class="d-flex align-items-center mb-3"> <i class="bi bi-heart-pulse fs-4 text-primary me-2"></i> <h5 class="fw-semibold mb-0 me-auto">System Health</h5> <span id="health-status-badge" class="badge"></span> </div> <hr class="my-3"> <div class="row g-2 small"> <div class="col-sm-6"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-clock me-2"></i> <span>Checked: <span id="health-timestamp" class="text-body"></span></span> </div> </div> <div class="col-sm-6"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-speedometer2 me-2"></i> <span>Response: <span id="health-duration" class="text-body"></span></span> </div> </div> <div class="col-sm-6 d-none" id="health-db-row"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-database me-2"></i> <span>Database: <span id="health-database" class="text-body"></span></span> </div> </div> <div class="col-sm-6 d-none" id="health-build-row"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-git me-2"></i> <span>Build: <code id="health-commit"></code> <span id="health-build-date" class="text-muted"></span></span> </div> </div> </div> </div> </div> </div> <!-- Tech Stack --> <div class="text-center"> <div class="d-flex flex-wrap justify-content-center gap-3 text-muted small"> <span><i class="bi bi-gear me-1"></i>.NET 10</span> <span class="text-black-50">|</span> <span><i class="bi bi-database me-1"></i>PostgreSQL</span> <span class="text-black-50">|</span> <span><i class="bi bi-layers me-1"></i>Entity Framework Core</span> <span class="text-black-50">|</span> <span><i class="bi bi-lock me-1"></i>JWT Authentication</span> <span class="text-black-50">|</span> <span><i class="bi bi-book me-1"></i>OpenAPI / Swagger</span> </div> </div> </div> </content> </div> </main> <footer b-yjl2sbey1b class="bg-light border-top py-2 text-center text-muted small"> Wealthmax PM CRM &mdash; Policy Document Testing UI </footer> <script src="/lib/jquery/dist/jquery.min.js"></script> <script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="/js/site.js?v=y_Ngd8W21UpuCUhEqGbUKDEqFnNfTjAfb24GhJJGUyM"></script> <script> function escapeHtml(text) { var div = document.createElement('div'); div.appendChild(document.createTextNode(text)); return div.innerHTML; } function statusBadgeClass(status) { switch ((status || '').toLowerCase()) { case 'healthy': return 'bg-success'; case 'degraded': return 'bg-warning text-dark'; default: return 'bg-danger'; } } function fetchHealth() { document.getElementById('health-loading').classList.remove('d-none'); document.getElementById('health-error').classList.add('d-none'); document.getElementById('health-content').classList.add('d-none'); fetch('/api/health') .then(function (response) { if (response.ok || response.status === 503) { return response.json(); } throw new Error('Unexpected status: ' + response.status); }) .then(function (response) { var health = response.data || response; renderHealth(health); document.getElementById('health-loading').classList.add('d-none'); document.getElementById('health-content').classList.remove('d-none'); }) .catch(function () { document.getElementById('health-loading').classList.add('d-none'); document.getElementById('health-error').classList.remove('d-none'); }); } function renderHealth(data) { var badge = document.getElementById('health-status-badge'); badge.textContent = data.status; badge.className = 'badge ' + statusBadgeClass(data.status); document.getElementById('health-timestamp').textContent = new Date(data.timestamp).toLocaleString(); document.getElementById('health-duration').textContent = data.totalDurationMs + ' ms'; var dbRow = document.getElementById('health-db-row'); if (data.databaseName || data.databaseProvider) { var parts = []; if (data.databaseName) parts.push(data.databaseName); if (data.databaseProvider) parts.push(data.databaseProvider); document.getElementById('health-database').textContent = parts.join(' on '); dbRow.classList.remove('d-none'); } else { dbRow.classList.add('d-none'); } var buildRow = document.getElementById('health-build-row'); if (data.commitHash || data.lastBuildDate) { document.getElementById('health-commit').textContent = data.commitHash || ''; document.getElementById('health-build-date').textContent = data.lastBuildDate ? '(' + new Date(data.lastBuildDate).toLocaleDateString() + ')' : ''; buildRow.classList.remove('d-none'); } else { buildRow.classList.add('d-none'); } } fetchHealth(); </script> </body> </html>
2026-09-22 22:09:01.087 +00:00 [INF] [GEN] [U:-] [E:-] [C:-] [T:7eca2c185f36e1945db485e2f7ddad5e] HTTP HEAD / responded 200 in 3.0796 ms
2026-09-22 22:09:01.084 +00:00 [INF] [HTTP] [U:-] [E:-] [C:bd4fe4da0102] [T:7eca2c185f36e1945db485e2f7ddad5e] HTTP HEAD / 200
Req: [non-JSON body] Res: <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Home — WM Policy Documents</title> <link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="/css/site.css?v=xQHUTQJdpYJFKIjDlFCI1X8KDqtO5qaSSeJFSoCP3pA" /> <link rel="stylesheet" href="/css/commissions.css?v=ZRMXSlMSxdLsHmJCZzq1LopWaopJSbVXKu57gvUJG3w" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" /> <style> /* ---- Hover-expand left sidebar -------------------------------------- */ :root { --sb-collapsed: 64px; --sb-expanded: 240px; } body.has-sidebar { /* Reserve space for the collapsed rail; the expanded panel overlays the content on hover, so the content never shifts. */ padding-left: var(--sb-collapsed); } .app-sidebar { position: fixed; top: 0; left: 0; height: 100vh; width: var(--sb-collapsed); overflow-x: hidden; overflow-y: auto; display: flex; flex-direction: column; z-index: 1045; transition: width 0.2s ease; } .app-sidebar:hover, .app-sidebar:focus-within { width: var(--sb-expanded); box-shadow: 0 0 24px rgba(0,0,0,0.35); } .app-sidebar .sb-label { white-space: nowrap; opacity: 0; transition: opacity 0.15s ease; } .app-sidebar:hover .sb-label, .app-sidebar:focus-within .sb-label { opacity: 1; } .sb-link { display: flex; align-items: center; gap: 0.85rem; padding: 0.65rem 0; color: rgba(255,255,255,0.75); text-decoration: none; border-left: 3px solid transparent; } .sb-link:hover { color: #fff; background: rgba(255,255,255,0.08); } .sb-link.active { color: #fff; background: rgba(255,255,255,0.12); border-left-color: #0d6efd; } .sb-link > i:first-child { min-width: var(--sb-collapsed); text-align: center; font-size: 1.15rem; flex-shrink: 0; } .sb-brand { display: flex; align-items: center; gap: 0.85rem; padding: 0.9rem 0; color: #fff; text-decoration: none; font-weight: 700; } .sb-brand > i:first-child { min-width: var(--sb-collapsed); text-align: center; font-size: 1.3rem; flex-shrink: 0; } /* Sub-menu (Fact-Find) */ .sb-submenu .sb-link { font-size: 0.9rem; padding-left: 0; } .sb-submenu .sb-link > i:first-child { font-size: 1rem; } .sb-caret { margin-left: auto; margin-right: 0.9rem; transition: transform 0.15s ease; } .sb-link[aria-expanded="true"] .sb-caret { transform: rotate(180deg); } </style> </head> <body class="d-flex flex-column min-vh-100 has-sidebar"> <nav b-yjl2sbey1b class="app-sidebar navbar-dark bg-dark shadow-sm"> <a class="sb-brand" href="/UI"> <i b-yjl2sbey1b class="bi bi-file-earmark-text"></i> <span b-yjl2sbey1b class="sb-label">Wealthmax</span> </a> <div b-yjl2sbey1b class="d-flex flex-column flex-grow-1"> <a class="sb-link " href="/UI/Dashboard/Index"> <i b-yjl2sbey1b class="bi bi-speedometer2"></i><span b-yjl2sbey1b class="sb-label">Dashboard</span> </a> <a class="sb-link " href="/UI/Templates/Index"> <i b-yjl2sbey1b class="bi bi-collection"></i><span b-yjl2sbey1b class="sb-label">Templates</span> </a> <a class="sb-link " href="/UI/Tokens/Index"> <i b-yjl2sbey1b class="bi bi-braces"></i><span b-yjl2sbey1b class="sb-label">Token Registry</span> </a> <a class="sb-link " href="/UI/Clients/Index"> <i b-yjl2sbey1b class="bi bi-people"></i><span b-yjl2sbey1b class="sb-label">Clients</span> </a> <a class="sb-link " href="/UI/Cases/Index"> <i b-yjl2sbey1b class="bi bi-briefcase"></i><span b-yjl2sbey1b class="sb-label">Cases</span> </a> <a class="sb-link " href="/UI/Reporting/Index"> <i b-yjl2sbey1b class="bi bi-graph-up"></i><span b-yjl2sbey1b class="sb-label">Reports</span> </a> <a class="sb-link " href="/UI/Commissions/Management"> <i b-yjl2sbey1b class="bi bi-cash-coin"></i><span b-yjl2sbey1b class="sb-label">Commissions</span> </a> <!-- User Management --> <a class="sb-link " href="/UI/Users/Index"> <i b-yjl2sbey1b class="bi bi-person-gear"></i><span b-yjl2sbey1b class="sb-label">User Management</span> </a> <!-- Fact-Find (expandable sub-menu) --> <a b-yjl2sbey1b class="sb-link " href="#ffSubmenu" role="button" data-bs-toggle="collapse" aria-expanded="false"> <i b-yjl2sbey1b class="bi bi-file-earmark-text"></i><span b-yjl2sbey1b class="sb-label">Fact-Find</span> <i b-yjl2sbey1b class="bi bi-chevron-down sb-caret sb-label"></i> </a> <div b-yjl2sbey1b class="collapse sb-submenu " id="ffSubmenu"> <a class="sb-link " href="/UI/FactFindFormatters/Index"> <i b-yjl2sbey1b class="bi bi-grid"></i><span b-yjl2sbey1b class="sb-label">Formatters</span> </a> <a class="sb-link " href="/UI/FactFindTemplates/Index"> <i b-yjl2sbey1b class="bi bi-layers"></i><span b-yjl2sbey1b class="sb-label">Templates</span> </a> <a class="sb-link " href="/UI/FactFindGenerate"> <i b-yjl2sbey1b class="bi bi-lightning-charge"></i><span b-yjl2sbey1b class="sb-label">Generate &amp; Preview</span> </a> </div> </div> <!-- Auth (pinned to bottom) --> <div b-yjl2sbey1b class="mt-auto border-top border-secondary"> <a b-yjl2sbey1b class="sb-link" href="/UI/business/login"> <i b-yjl2sbey1b class="bi bi-box-arrow-in-right"></i><span b-yjl2sbey1b class="sb-label">Business login</span> </a> </div> </nav> <main b-yjl2sbey1b class="flex-grow-1 py-4"> <div b-yjl2sbey1b class="container-fluid px-4"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"> <style> body > nav.navbar { position: sticky; top: 0; z-index: 1030; } .dash-hero { background: linear-gradient(135deg, #212529 0%, #343a40 100%); color: #fff; } .dash-card { border: none; border-radius: 12px; transition: transform 0.15s ease, box-shadow 0.15s ease; } .dash-card:hover { transform: translateY(-3px); box-shadow: 0 8px 24px rgba(0,0,0,0.10) !important; } .dash-icon { width: 48px; height: 48px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 1.4rem; } .dash-stat-value { font-size: 2rem; font-weight: 700; line-height: 1; } .dash-card-title { font-size: 0.95rem; font-weight: 600; } .dash-card-text { font-size: 0.78rem; } /* Discreet business-login link pinned to the bottom-right corner. */ .home-login-link { position: fixed; bottom: 1rem; right: 1.25rem; z-index: 1040; } </style> <!-- Hero --> <div class="dash-hero py-4 mb-4"> <div class="container text-center"> <h1 class="display-6 fw-bold mb-2">Wealthmax PM CRM</h1> <p class="lead text-white-50 mb-0" style="max-width: 640px; margin: 0 auto;"> Testing harness dashboard &mdash; system tools, integrations, and live service health at a glance. </p> </div> </div> <div class="container pb-5"> <!-- Tool / Integration cards --> <div class="row g-3 mb-4"> <!-- Tenants Created --> <div class="col-6 col-md-4 col-lg-3"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="d-flex align-items-start justify-content-between mb-2"> <div class="dash-icon bg-primary bg-opacity-10 text-primary"> <i class="bi bi-building-fill"></i> </div> <span class="badge bg-secondary bg-opacity-10 text-secondary">Sample</span> </div> <div class="dash-stat-value text-dark">12</div> <div class="dash-card-title text-dark mt-1">Tenants Created</div> <p class="dash-card-text text-muted mb-0">Total onboarded tenants in this environment.</p> </div> </div> </div> <!-- Build Logs --> <div class="col-6 col-md-4 col-lg-3"> <a href="/UI/DevLogs" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-dark bg-opacity-10 text-dark mb-2"> <i class="bi bi-terminal-fill"></i> </div> <div class="dash-card-title text-dark">Build &amp; App Logs</div> <p class="dash-card-text text-muted mb-0">Browse structured application logs by date and level.</p> </div> </div> </a> </div> <!-- Swagger --> <div class="col-6 col-md-4 col-lg-3"> <a href="/swagger" target="_blank" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="d-flex align-items-start justify-content-between mb-2"> <div class="dash-icon bg-success bg-opacity-10 text-success"> <i class="bi bi-braces"></i> </div> <i class="bi bi-box-arrow-up-right text-muted small"></i> </div> <div class="dash-card-title text-dark">Swagger / API Docs</div> <p class="dash-card-text text-muted mb-0">Explore and try the REST API via OpenAPI UI.</p> </div> </div> </a> </div> <!-- SignalR --> <div class="col-6 col-md-4 col-lg-3"> <a href="/test-signalr.html" target="_blank" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="d-flex align-items-start justify-content-between mb-2"> <div class="dash-icon bg-info bg-opacity-10 text-info"> <i class="bi bi-broadcast"></i> </div> <i class="bi bi-box-arrow-up-right text-muted small"></i> </div> <div class="dash-card-title text-dark">SignalR Hub</div> <p class="dash-card-text text-muted mb-0">Test real-time notifications over the SignalR hub.</p> </div> </div> </a> </div> <!-- iPipeline --> <div class="col-6 col-md-4 col-lg-3"> <a href="/demo/solution-builder" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-warning bg-opacity-10 text-warning mb-2"> <i class="bi bi-plug-fill"></i> </div> <div class="dash-card-title text-dark">iPipeline</div> <p class="dash-card-text text-muted mb-0">Launch the iPipeline Solution Builder integration.</p> </div> </div> </a> </div> <!-- Fetch Quotes --> <div class="col-6 col-md-4 col-lg-3"> <a href="/demo/solution-builder/events" class="text-decoration-none"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-danger bg-opacity-10 text-danger mb-2"> <i class="bi bi-receipt"></i> </div> <div class="dash-card-title text-dark">Fetch Quotes</div> <p class="dash-card-text text-muted mb-0">View quote-notification events returned from the pipeline.</p> </div> </div> </a> </div> <!-- CRM Dashboard --> <div class="col-6 col-md-4 col-lg-3"> <a class="text-decoration-none" href="/UI/Dashboard/Index"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-primary bg-opacity-10 text-primary mb-2"> <i class="bi bi-speedometer2"></i> </div> <div class="dash-card-title text-dark">CRM Dashboard</div> <p class="dash-card-text text-muted mb-0">Cases, clients, and commission overview metrics.</p> </div> </div> </a> </div> <!-- Clients --> <div class="col-6 col-md-4 col-lg-3"> <a class="text-decoration-none" href="/UI/Clients/Index"> <div class="card dash-card shadow-sm h-100"> <div class="card-body p-3"> <div class="dash-icon bg-success bg-opacity-10 text-success mb-2"> <i class="bi bi-people-fill"></i> </div> <div class="dash-card-title text-dark">Clients &amp; Cases</div> <p class="dash-card-text text-muted mb-0">Manage client records and advisory cases.</p> </div> </div> </a> </div> </div> <!-- System Health --> <div id="health-card" class="card dash-card shadow-sm mb-4"> <div class="card-body p-3"> <!-- Loading state --> <div id="health-loading" class="text-center py-3"> <div class="spinner-border spinner-border-sm text-primary" role="status"> <span class="visually-hidden">Loading...</span> </div> <span class="ms-2 text-muted">Checking system health...</span> </div> <!-- Error state --> <div id="health-error" class="d-none text-center py-3"> <i class="bi bi-exclamation-triangle fs-4 text-danger d-block mb-2"></i> <p class="text-muted mb-1">Unable to reach the health endpoint.</p> <button class="btn btn-sm btn-outline-secondary" onclick="fetchHealth()"> <i class="bi bi-arrow-clockwise me-1"></i>Retry </button> </div> <!-- Success state --> <div id="health-content" class="d-none"> <div class="d-flex align-items-center mb-3"> <i class="bi bi-heart-pulse fs-4 text-primary me-2"></i> <h5 class="fw-semibold mb-0 me-auto">System Health</h5> <span id="health-status-badge" class="badge"></span> </div> <hr class="my-3"> <div class="row g-2 small"> <div class="col-sm-6"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-clock me-2"></i> <span>Checked: <span id="health-timestamp" class="text-body"></span></span> </div> </div> <div class="col-sm-6"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-speedometer2 me-2"></i> <span>Response: <span id="health-duration" class="text-body"></span></span> </div> </div> <div class="col-sm-6 d-none" id="health-db-row"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-database me-2"></i> <span>Database: <span id="health-database" class="text-body"></span></span> </div> </div> <div class="col-sm-6 d-none" id="health-build-row"> <div class="d-flex align-items-center text-muted mb-2"> <i class="bi bi-git me-2"></i> <span>Build: <code id="health-commit"></code> <span id="health-build-date" class="text-muted"></span></span> </div> </div> </div> </div> </div> </div> <!-- Tech Stack --> <div class="text-center"> <div class="d-flex flex-wrap justify-content-center gap-3 text-muted small"> <span><i class="bi bi-gear me-1"></i>.NET 10</span> <span class="text-black-50">|</span> <span><i class="bi bi-database me-1"></i>PostgreSQL</span> <span class="text-black-50">|</span> <span><i class="bi bi-layers me-1"></i>Entity Framework Core</span> <span class="text-black-50">|</span> <span><i class="bi bi-lock me-1"></i>JWT Authentication</span> <span class="text-black-50">|</span> <span><i class="bi bi-book me-1"></i>OpenAPI / Swagger</span> </div> </div> </div> </content> </div> </main> <footer b-yjl2sbey1b class="bg-light border-top py-2 text-center text-muted small"> Wealthmax PM CRM &mdash; Policy Document Testing UI </footer> <script src="/lib/jquery/dist/jquery.min.js"></script> <script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="/js/site.js?v=y_Ngd8W21UpuCUhEqGbUKDEqFnNfTjAfb24GhJJGUyM"></script> <script> function escapeHtml(text) { var div = document.createElement('div'); div.appendChild(document.createTextNode(text)); return div.innerHTML; } function statusBadgeClass(status) { switch ((status || '').toLowerCase()) { case 'healthy': return 'bg-success'; case 'degraded': return 'bg-warning text-dark'; default: return 'bg-danger'; } } function fetchHealth() { document.getElementById('health-loading').classList.remove('d-none'); document.getElementById('health-error').classList.add('d-none'); document.getElementById('health-content').classList.add('d-none'); fetch('/api/health') .then(function (response) { if (response.ok || response.status === 503) { return response.json(); } throw new Error('Unexpected status: ' + response.status); }) .then(function (response) { var health = response.data || response; renderHealth(health); document.getElementById('health-loading').classList.add('d-none'); document.getElementById('health-content').classList.remove('d-none'); }) .catch(function () { document.getElementById('health-loading').classList.add('d-none'); document.getElementById('health-error').classList.remove('d-none'); }); } function renderHealth(data) { var badge = document.getElementById('health-status-badge'); badge.textContent = data.status; badge.className = 'badge ' + statusBadgeClass(data.status); document.getElementById('health-timestamp').textContent = new Date(data.timestamp).toLocaleString(); document.getElementById('health-duration').textContent = data.totalDurationMs + ' ms'; var dbRow = document.getElementById('health-db-row'); if (data.databaseName || data.databaseProvider) { var parts = []; if (data.databaseName) parts.push(data.databaseName); if (data.databaseProvider) parts.push(data.databaseProvider); document.getElementById('health-database').textContent = parts.join(' on '); dbRow.classList.remove('d-none'); } else { dbRow.classList.add('d-none'); } var buildRow = document.getElementById('health-build-row'); if (data.commitHash || data.lastBuildDate) { document.getElementById('health-commit').textContent = data.commitHash || ''; document.getElementById('health-build-date').textContent = data.lastBuildDate ? '(' + new Date(data.lastBuildDate).toLocaleDateString() + ')' : ''; buildRow.classList.remove('d-none'); } else { buildRow.classList.add('d-none'); } } fetchHealth(); </script> </body> </html>
Errors & Warnings 5
2026-09-22 22:24:46.670 +00:00 [WRN] [HTTP] [U:-] [E:-] [C:1cc68be70167] [T:a878f81d4fdc34ffcfb83d156e26e727] HTTP GET /.env 401
Req: [no body] Res: {"success":false,"error":{"code":"UNAUTHORIZED","message":"Authentication is required to access this resource."},"timestamp":"2026-09-22T22:24:46.6701895Z"}
2026-09-22 22:24:46.622 +00:00 [WRN] [HTTP] [U:-] [E:-] [C:fc1a6ed655d8] [T:c78ef4fd43ba2e46f806d212fc5c8d0b] HTTP GET /.env 401
Req: [no body] Res: {"success":false,"error":{"code":"UNAUTHORIZED","message":"Authentication is required to access this resource."},"timestamp":"2026-09-22T22:24:46.6222865Z"}
2026-09-22 22:20:02.523 +00:00 [WRN] [HTTP] [U:-] [E:-] [C:34e2afb0ab5c] [T:bf7a2949eca4f45c7e92147335fa33d4] HTTP GET /robots.txt 401
Req: [no body] Res: {"success":false,"error":{"code":"UNAUTHORIZED","message":"Authentication is required to access this resource."},"timestamp":"2026-09-22T22:20:02.5230627Z"}
2026-09-22 22:09:28.268 +00:00 [WRN] [HTTP] [U:-] [E:-] [C:48ca9c8a1e91] [T:2b26791f892addb4871122464d613441] HTTP GET /enhancecp 401
Req: [no body] Res: {"success":false,"error":{"code":"UNAUTHORIZED","message":"Authentication is required to access this resource."},"timestamp":"2026-09-22T22:09:28.2682327Z"}
2026-09-22 22:09:28.112 +00:00 [WRN] [HTTP] [U:-] [E:-] [C:19c01e71a6d6] [T:ce491a4501602d7f8008c75e93bf02c0] HTTP GET /robots.txt 401
Req: [no body] Res: {"success":false,"error":{"code":"UNAUTHORIZED","message":"Authentication is required to access this resource."},"timestamp":"2026-09-22T22:09:28.1128177Z"}