Commit Graph

83 Commits

Author SHA1 Message Date
kjh2064 cb1982c39e feat: Frontend JWT token management and login page
deploy / deploy (push) Successful in 1m57s
deploy / notify (push) Successful in 1s
- Created useAuthApi composable for JWT token lifecycle management
- Implemented setupAuthInterceptor for automatic Authorization header injection
- Added LoginPage.vue with username/password form
- Configured router to redirect to /login for unauthenticated access
- Token stored in localStorage with expiration tracking
- Automatic token validation and cleanup on expiration
- All fetch requests automatically include Bearer token
- Unit tests for login, logout, token validation flows

This enables frontend to authenticate via JWT tokens in production mode.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-18 00:11:47 +09:00
kjh2064 5f35135300 feat(01-06): AEG-VS-01-06 Vue Feature Development - Identity Management Page
cross-version-matrix / .NET 8 + PostgreSQL 14 (push) Has been cancelled
cross-version-matrix / .NET 8 + PostgreSQL 15 (push) Has been cancelled
cross-version-matrix / .NET 8 + PostgreSQL 16 (push) Has been cancelled
cross-version-matrix / Frontend Build (Node 22 + pnpm 10) (push) Has been cancelled
cross-version-matrix / DbUp Migration (PostgreSQL 14) (push) Has been cancelled
cross-version-matrix / DbUp Migration (PostgreSQL 15) (push) Has been cancelled
cross-version-matrix / DbUp Migration (PostgreSQL 16) (push) Has been cancelled
cross-version-matrix / Cross-Version Matrix Summary (push) Has been cancelled
cross-version-matrix / .NET 10 + PostgreSQL 14 (push) Has been cancelled
cross-version-matrix / .NET 10 + PostgreSQL 15 (push) Has been cancelled
cross-version-matrix / .NET 10 + PostgreSQL 16 (push) Has been cancelled
deploy / deploy (push) Failing after 52s
deploy / notify (push) Successful in 1s
Implements Vue 3 Identity Management page with:
- Identity registration form with Zod validation
- Email (required, valid format, lowercase), displayName (required, max 255, trimmed)
- List view with search/filter (by state and MFA requirement)
- Simple create modal + delete functionality with confirmation
- useIdentityApi composable integrating with RegisterIdentity endpoint
- Full TypeScript validation (15 tests pass: identitySchema + useIdentityApi)
- Responsive table display with status badges

Technical approach:
- Simplified component using minimal KsTextField/KsSelect/KsButton
- Avoided complex component wrapper conflicts (prior session issue)
- Mock data for demo, real API calls ready
- Router integration: /system/identities (SCR-SYS-002)
- CSS scoped styling for modal, form, table, badges
- Error/success message handling per state

AGENTS.md v16.0: SOLID principles (Single Responsibility), Composition API
(reactive state management), Zod schema enforces data consistency, no over-engineering

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-17 21:04:12 +09:00
kjh2064 728393226f refactor(fe): P3 pages standardize to screen-type v2 templates
Refactored 4 feature pages to use standard screen-type v2 layouts:

1. HomePage → ScorecardDashboardPage
   - Exception-driven work queue metrics + dashboard layout
   - KPI cards, filters, operational guides
   - Viewport-fit ready, no page-level scrolling

2. ModelsList → MasterDetailCrudPage
   - Master list + detail panel layout
   - Model grid with phase/performance metrics
   - Search, filter, pagination

3. ModelDetail → DetailReadPage
   - Read-only model detail view
   - State management (LOADING/ERROR/READY)
   - Metric display (PBO, DSR, Return)

4. ShadowRunDetail → DetailReadPage
   - Shadow run detail view
   - State management (LOADING/ERROR/READY)
   - Performance metrics (PBO, DSR, OOS)

Pattern Applied:
- Remove PageLayout, use screen-type component
- Add StandardScreenProps (state, evidence)
- State computed from query status
- Slot structure maintained or aligned
- No functional changes, pure standardization

Benefits:
- Consistent layout across pages
- Standardized state management
- Improved viewport-fit compliance
- Better component reusability

Next: Viewport-fit final validation + viewport-fit edge cases

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-17 17:14:30 +09:00
kjh2064 f3ddd4d84b fix(fe): KsDataGrid + CommonCodeManagementPage - grid edit issues
deploy / deploy (push) Failing after 48s
deploy / notify (push) Successful in 1s
Fixed 3 critical bugs in grid editing:

1. onCellValueChanged redrawRows() removal
   - Removed event.api.redrawRows() that was resetting cell input
   - Issue: redrawRows() triggered computed property re-evaluation
   - Result: Array reference changed, grid lost input value

2. ScrollApiModule registration
   - Added ScrollApiModule to ModuleRegistry
   - Issue: focusRow() called ensureIndexVisible without module
   - Result: AG Grid #200 error, page hung

3. onCellEditingStopped removal
   - Removed auto-restart of edit mode on cell exit
   - Issue: Prevented navigateToNextCell from working on Enter key
   - Result: Enter key now properly moves focus to next cell

4. CommonCodeManagementPage focusRow safety
   - Wrapped focusRow() in try-catch
   - Issue: focusRow may not be available, causing errors
   - Result: Grid continues even if focusRow unavailable

Affects: /system/common-codes grid editing and all pages using KsDataGrid

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-16 20:42:18 +09:00
kjh2064 bd971cacdd fix(fe): CommonCodeManagementPage - input reset bug on new row edit
deploy / deploy (push) Failing after 47s
deploy / notify (push) Successful in 0s
Problem: Adding a group row then typing in cells caused continuous reset
Root Cause: Vue reactivity lost when assigning new array to reactive object
Solution: Use Object.assign() to maintain reactivity tracking

- Changed: mockChildCodesMap[key] = list
- To: Object.assign(mockChildCodesMap, { [key]: list })
- Result: Cell input now persists without reset

Affects: /system/common-codes grid editing

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-16 20:29:36 +09:00
kjh2064 1be7029f8f refactor(fe): viewport-fit zero-scroll layout for 11 pages (Part 2)
deploy / deploy (push) Failing after 51s
deploy / notify (push) Successful in 1s
## Summary
- BatchOperationsPageV2: add overflow-y: auto (ShadowRunQueue, DataQualityPage)
- ModelsList: add flex:1 + min-height:0 + overflow-y:auto
- ShadowRunList: change height to 100% (from calc(100vh - 210px))
- ModelOperationsPage: add overflow-y: auto
- WbsWorkspacePage: add flex:1 + min-height:0 + overflow-y:auto
- IngestionStatus, CommonCodeManagementPage: already fitted (via component inheritance)
- MarketDataIngestion: already fitted (EditFormPage)
- HomePage, RebalanceForm, UiStandardPage: already fitted (earlier session)

Total: 11 pages viewport-fit, 7 pages already compliant

Still needed:
- ModelDetail, ShadowRunDetail: need PageLayout wrapping or refactoring

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-16 15:00:03 +09:00
kjh2064 266db96576 refactor(fe): SellDecisionPage - EditFormPage pattern
- Migrate from PageLayout to EditFormPage (standard form pattern)
- Add state management (PROCESSING/ERROR/READY)
- Separate form input and result preview sections
- Use #preview slot for policy evaluation results
- Add evidence tracking (asOf, version)
- Add dirty state (form has potential changes)
- Improve result display: semantic HTML (dl/dt/dd)
- Add CSS styles for result presentation

Result: Consistent form pattern across all research tools

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-16 01:25:32 +09:00
kjh2064 71f76787b1 fix(fe): RiskDashboard - add empty state handling and data validation
- Add EMPTY state to StandardScreenState when portfolio has no positions
- Condition all template slots on dashboard data presence
- Validate dashboard.healthScore, riskMetrics, portfolio, stressResults
- Update empty message: '보유 종목이 없습니다' → '포트폴리오 보유 종목이 없습니다'
- Display 'EMPTY' state instead of blank screen when no data
- Improve state computation: LOADING → ERROR/WARN → EMPTY → READY

Result: Better UX for empty/error states, clearer data validation

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-16 01:22:52 +09:00
kjh2064 8ae6bf6429 refactor(fe): ApprovalQueue - EditFormPage pattern
- Restructure detail panel as approval form (EditFormPage pattern)
- Separate concerns: Header (read-only) + Content (form) + Footer (actions)
- Use form/fieldset semantics for read-only vs editable sections
- Request Details and Metrics as disabled fieldsets (read-only)
- Review Comment as textarea form input
- Footer buttons (Approve/Reject) with validation
- CSS refactor: approval-form, form-header/content/footer structure
- Improved accessibility and semantic HTML

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-16 01:21:39 +09:00
kjh2064 4d1bdb467e refactor(fe): ApprovalQueue - compact layout to eliminate scroll
- Reduce .request-detail gap: var(--spacing-4) → var(--spacing-2)
- Reduce .request-detail padding: var(--spacing-4) → var(--spacing-3)
- Reduce textarea height: 80-120px → 60-80px
- Reduce .detail-header padding and gap for compact header
- Reduce h3 font-size and margin for section headers
- Reduce .detail-item gap for tight item spacing

Result: All content (Request Details, Validation Metrics, Review Comment) fits in viewport without internal scroll

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-16 01:15:12 +09:00
kjh2064 53e91acc52 refactor(fe): ApprovalQueue - MasterDetailCrudPage + UX improvements
- Migrate from ApprovalWorkbenchPage to MasterDetailCrudPage (more appropriate structure)
- Move Approve/Reject buttons to detail header (always visible)
- Compact Validation Metrics (reduced padding and font size)
- Optimize Review Comment textarea (80-120px height)
- Improve layout flow: fixed header + scrollable content in detail panel
- Title: Approval Queue (Maker-Checker Governance)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-16 01:06:49 +09:00
kjh2064 a5a952fd43 refactor(fe): simplify ApprovalQueue summary structure - remove unnecessary wrapper
Removed unnecessary <div class="stats" role="toolbar"> wrapper.
Stats are now direct children of ks-page__summary (which has CSS Grid layout).

Benefits:
- Simpler DOM structure (fewer nesting levels)
- Role="toolbar" was misleading (this is a stats summary, not a toolbar)
- PageLayout.summary already handles grid layout
- Follows AGENTS.md Necessity-driven & Simplicity principles

Before: 1 wrapper + 3 stats = 4 divs
After: 3 stats = 3 divs (25% reduction)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-16 00:57:59 +09:00
kjh2064 dbbfaca4d8 fix(fe): fix ModelList (models-master) scroll on first load - apply height propagation standard
Problem: .master-list had hardcoded height: calc(100vh - 210px), causing scroll on first load

Changes:
  • .master-list: calc(100vh - 210px) → flex: 1; min-height: 0;
  • .items: Added missing min-height: 0; (required for flex children)

Result: Single-screen principle restored (no page-level scroll, height fills viewport)

This aligns with AGENTS.md Height Propagation Chain standard.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-16 00:30:00 +09:00
kjh2064 4ff5aaf97f fix(fe): add flex height constraint to .request-detail - prevent overflow 2026-08-16 00:01:04 +09:00
kjh2064 05e279174f refactor(fe): migrate ApprovalQueue to KsSplitter - standardize master-detail layout
- Replace custom grid layout with KsSplitter component
- Add storageKey to prevent ratio conflicts with other pages
- Remove dead .content CSS class
- Update .request-list height constraint (flex: 1 → height: 100%)
- Maintain overflow-y: auto for scrollable panes
- Simplifies code by ~50 lines, adds drag-to-resize functionality
2026-08-15 23:59:26 +09:00
kjh2064 b299939cb8 fix(fe): remove max-height constraint on approval request list - single screen fit 2026-08-15 23:50:53 +09:00
kjh2064 c1c55e2dce fix(fe): enforce grid height to fill available viewport space
ISSUE: Grid height was constrained to min-height: 220px, leaving large
unused space on page (3 rows visible, lots of empty area below).

PRINCIPLE: Grid must expand to fill available vertical space in viewport.

CHANGES:
ModelOperationTable.vue (.grid-wrapper)
- Removed: min-height: 220px (artificial constraint)
- Added: height: 100%
- Added: min-height: 0 (critical for flex overflow behavior)

RESULT: Grid now spans full available height in flex container,
utilizing screen space efficiently.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 23:41:27 +09:00
kjh2064 8ea0bf4d99 fix(fe): enforce single-screen viewport principle for ApprovalQueue
PRINCIPLE: First load must fit within single viewport (no scroll required,
excluding dashboard summary section).

CHANGES:
1. ReviewWorkbenchLayout.vue
   - Changed: height: calc(100vh - 220px) → height: 100%
   - Reason: calc() was hardcoded to fixed pixels, not respecting parent flex layout
   - Added: min-height: 0 (critical for flex overflow behavior)

2. ApprovalQueue.vue (.content)
   - Added: height: 100% + min-height: 0

3. ApprovalQueue.vue (.detail-panel)
   - Removed: max-height: 700px (was hard limit, causing overflow)
   - Added: height: 100% + min-height: 0

RESULT: Page now fits single viewport without scroll.
Individual panels (list, detail) maintain internal scroll as needed.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 23:32:03 +09:00
kjh2064 a6659bc840 fix(fe): add width 100% to .filters - ensure filters span full container width
CRITICAL FIX: Filters container must explicitly set width: 100% to span
the full parent width and prevent content-based shrink-to-fit.

Without width: 100%, .filters collapses to content width, causing
filter inputs to wrap to multiple lines when parent container width
changes.

Added 'width: 100%;' to .filters in:
- ModelsList.vue
- ShadowRunQueue.vue
- ApprovalQueue.vue
- DataQualityPage.vue

Result: Filters now correctly span full width and display on single line.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 23:28:30 +09:00
kjh2064 fada81f216 style(fe): fix filter layout - add display flex to .filters
CRITICAL FIX: Restored .filters { display: flex } to all pages.

Previous commit removed this necessary style, causing filters to
wrap to 2 lines instead of staying inline.

All filter sections now display in a single line with:
- display: flex
- align-items: center
- gap: var(--ks-space-3)

This ensures:
- Input fields stay inline (1 line)
- 52px filter height maintained
- 34px input height maintained
- Standard layout across all pages

Affected pages:
- ModelsList.vue
- ShadowRunQueue.vue
- ApprovalQueue.vue
- DataQualityPage.vue (already had this)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 23:18:59 +09:00
kjh2064 33df3abbf4 style(fe): remove redundant input styles - use PageLayout defaults
Removed duplicate input field styling from individual pages:
- ModelsList.vue: removed .input height/padding/border styles
- ShadowRunQueue.vue: removed .input height/padding/border styles
- ApprovalQueue.vue: removed .filters and .input styles

PageLayout now provides the authoritative source for input styling:
- All inputs in .ks-page__filters use consistent 34px height
- Padding: 0 0.75rem
- Border-radius: 4px
- Box-sizing: border-box

Individual pages now only define width constraints (max-width: 350px for search).

This applies the DRY principle - single source of truth for filter input
styling across all pages. Reduces code duplication and improves
maintainability.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 23:16:39 +09:00
kjh2064 1e48b4987d style(fe): centralize filter input standardization in PageLayout
PageLayout now provides default styles for all filter inputs:
- Height: 34px
- Padding: 0 0.75rem
- Line-height: 34px
- Border-radius: 4px
- Box-sizing: border-box

This eliminates the need for each page to redefine input styles.
Individual pages now only override width constraints (search-input max-width).

Aligns with DRY principle - single source of truth for input styling.

DataQualityPage:
- Added scoped styles for search-input max-width (350px)

Future: Consider extracting filter inputs into dedicated components
(<KsFilterInput>, <KsFilterSelect>) for even better reusability.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 23:15:51 +09:00
kjh2064 4ec9af9b7c style(fe): standardize filter inputs in ApprovalQueue page
- Input height: 34px (standard KBX compact)
- Padding: 0 0.75rem
- Line-height: 34px for vertical centering
- Box-sizing: border-box for consistent sizing
- Change filters from grid to flex layout
- Remove margin-bottom (handled by PageLayout)
- Filter gap: var(--ks-space-3) (matches other pages)

Aligns with PageLayout + ModelsList + ShadowRunQueue standardization.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 23:14:41 +09:00
kjh2064 00a4840eb3 style(fe): standardize filter inputs in ShadowRunQueue page
- Input height: 34px (standard KBX compact)
- Search input: max-width 350px (matches ModelsList)
- Padding: 0 0.75rem
- Line-height: 34px for vertical centering
- Box-sizing: border-box for consistent sizing
- Status select: min-width 150px

Aligns with PageLayout + ModelsList standardization.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 23:13:25 +09:00
kjh2064 60722576a6 style(fe): standardize filter section height across all pages
PageLayout:
- Filter section: min-height 52px (standard height)
- Display: flex with center alignment
- Consistent gap between elements

ModelsList:
- Filter container: align-items center
- Remove bottom margin (handled by PageLayout)

Ensures all pages have consistent filter bar heights
and alignment without per-page CSS adjustments.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 23:04:59 +09:00
kjh2064 9223f5d288 style(fe): set max-width for search input field
- Search input: max-width 350px (standard size)
- Prevents oversized input fields across different screen sizes
- Maintains responsive min-width 200px

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 23:04:03 +09:00
kjh2064 8f52521a79 refactor(fe): implement responsive flex-based layout for ModelsList
- Grid height: height: 100% (leverages PageLayout flex)
- Filter inputs: Standard 34px height (KBX compact)
- Removes hardcoded calc() and max/min constraints
- Automatically adjusts to viewport/container changes
- No manual adjustments needed per screen size

This allows the component to scale responsively within
the PageLayout flex container without additional CSS.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 23:00:55 +09:00
kjh2064 7d835372fb style(fe): apply KBX design token standardization to ModelsList
- Filter inputs: Use KBX tokens for height, padding, font-size, border-radius
- Grid container: Dynamic height (calc 100vh-400px) with min/max constraints
- Consistent spacing with KBX spacing tokens
- Box-sizing: border-box for consistent sizing
- Prevents grid overflow beyond viewport

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 22:59:02 +09:00
kjh2064 8a3ee0a1d7 feat(fe): implement working ModelsList grid with mock data
- Simplified data fetching (removed TanStack Query for now)
- Added direct mock API client in component
- Fixed state management (isLoading, isError, modelsData)
- Grid now renders with 3 sample model records
- Updated v-if conditions for loading/error/empty states
- Added grid container height and filter styling

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 22:56:04 +09:00
kjh2064 48a3da30d0 fix(fe): remove duplicate script setup block in ModelsList.vue
Removed the incomplete first <script setup> block that was causing
Vite plugin errors. The complete implementation in the second block
already contains all necessary logic.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 22:48:18 +09:00
kjh2064 48cd7d82ee style(fe): enforce 100% viewport-fit zero-scroll dynamic height calculation for ModelOperationTable AG Grid 2026-08-15 22:37:49 +09:00
kjh2064 f73c1e3453 fix(fe): set explicit container height for KsDataGrid wrapper in ModelOperationTable 2026-08-15 22:36:48 +09:00
kjh2064 43e3f88368 feat(fe): replace custom HTML table with standard KsDataGrid in ModelOperationTable for 100% AG Grid & constitution compliance 2026-08-15 22:35:56 +09:00
kjh2064 2b1dc13852 style(fe): standardize Model Operations & Versioning page UI components and layout 2026-08-15 22:28:51 +09:00
kjh2064 ecc5c641dc style(fe): move F3 search button to Page Action Toolbar (#actions) in ModelList page for 100% KBX Command Bar standard compliance 2026-08-15 22:27:04 +09:00
kjh2064 135d0fdded feat(fe): add F3 search button and keyboard shortcut to ModelList page filter bar 2026-08-15 22:25:12 +09:00
kjh2064 5dbf0077e4 style(fe): standardize ModelList master-detail page with central width tokens, selection highlight, and viewport-fit bounds 2026-08-15 22:12:16 +09:00
kjh2064 b3d29dd5b6 refactor(fe): standardize DataQualityPage with BatchOperationsPageV2 layout and AG Grid shell 2026-08-15 22:00:31 +09:00
kjh2064 798dcbc2fc refactor(fe): standardize ShadowRunList page with BatchOperationsPageV2 and DataGridShell 2026-08-15 21:59:35 +09:00
kjh2064 a239e6ab64 feat(fe): support explicit relative flex ratios per grid column 2026-08-15 21:30:13 +09:00
kjh2064 e8b4d561c1 style(fe): standardize page header action toolbar layout and button naming 2026-08-15 21:26:08 +09:00
kjh2064 6483757ba0 fix(fe): structural flex layout fix for 100% viewport height zero-scroll fit 2026-08-15 21:24:28 +09:00
kjh2064 57a2f2adac fix(fe): standardize search input width and grid column sizing in ShadowRunQueue 2026-08-15 21:22:02 +09:00
kjh2064 4780093f11 fix(fe): eliminate duplicate wrappers and enforce exact viewport-fit grid height in ShadowRunQueue 2026-08-15 21:20:26 +09:00
kjh2064 95d5ebc14e refactor(fe): replace custom HTML table with standardized DataGridShell in ShadowRunQueue 2026-08-15 21:16:47 +09:00
kjh2064 1d1ac0b74c fix(fe): add robust mock fallback data for market-data-history and enable slot rendering 2026-08-15 21:14:39 +09:00
kjh2064 805c6d0dbf fix(fe): handle fallback mock in RiskDashboard when API 502 occurs 2026-08-15 20:51:07 +09:00
kjh2064 260dcbeb3c fix(fe): add robust mock fallback for model-operations plan endpoint during offline backend states 2026-08-15 20:49:21 +09:00
kjh2064 c6730c217f fix(fe): resolve relative import paths for SkeletonLoader across legacy page routes 2026-08-15 20:48:08 +09:00
kjh2064 b843275126 fix(fe): resolve CSS design token alias mappings and elevate KBX grid layout 2026-08-15 20:19:07 +09:00