Commit Graph

605 Commits

Author SHA1 Message Date
kjh2064 a3fe301308 security(web): secure Hangfire Dashboard with cookie authentication filter
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 24s
Prepare Release / Build & Create Release (push) Successful in 1m0s
Prepare Release / Release Notification (push) Successful in 1s
Validators (Pushes and Pull Requests) / validate-core (push) Successful in 1m58s
2026-07-12 13:14:20 +09:00
kjh2064 bcc9b76212 fix(web): resolve User Edit routing mismatch and apply asp-page Tag Helpers
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 22s
Prepare Release / Build & Create Release (push) Successful in 58s
Prepare Release / Release Notification (push) Successful in 1s
Validators (Pushes and Pull Requests) / validate-core (push) Successful in 1m54s
2026-07-12 13:12:24 +09:00
kjh2064 7172de3623 docs: create missing REPORT_GUIDE.md to satisfy COMPLETION_HARNESS_INSTRUCTIONS_V1
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 23s
Prepare Release / Build & Create Release (push) Successful in 54s
Prepare Release / Release Notification (push) Successful in 0s
Validators (Pushes and Pull Requests) / validate-core (push) Successful in 1m56s
2026-07-12 13:08:15 +09:00
kjh2064 6582ffc02a chore: deprecate and remove blazor client code and project configurations
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 22s
Prepare Release / Build & Create Release (push) Failing after 58s
Prepare Release / Release Notification (push) Successful in 1s
Validators (Pushes and Pull Requests) / validate-core (push) Has been cancelled
2026-07-12 13:06:57 +09:00
kjh2064 f8ff3a2c46 ci: chain release build into production deploy
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 22s
Prepare Release / Build & Create Release (push) Successful in 1m0s
Prepare Release / Release Notification (push) Successful in 1s
Validators (Pushes and Pull Requests) / validate-core (push) Successful in 1m55s
2026-07-12 12:59:27 +09:00
kjh2064 ecc7deed08 ci: deploy production on main pushes
Deploy to Production / Deploy to Production (push) Successful in 5s
Deploy to Production / Health Check & Verification (push) Successful in 6s
Deploy to Production / Deployment Report (push) Successful in 1s
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 20s
Validators (Pushes and Pull Requests) / validate-core (push) Successful in 1m43s
2026-07-12 12:57:04 +09:00
kjh2064 ee0787683b ci: package only generated report artifacts
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 16s
Validators (Pushes and Pull Requests) / validate-core (push) Has been cancelled
2026-07-12 12:55:42 +09:00
kjh2064 f8d93de299 ci: emit contract-shaped missing-data artifacts
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 15s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 1m37s
2026-07-12 12:53:28 +09:00
kjh2064 7db7f74713 fix: treat paired missing packet metrics honestly
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 14s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 1m35s
2026-07-12 12:49:34 +09:00
kjh2064 fbb56400af ci: restore KIS collection credential contract
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 15s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 1m35s
2026-07-12 12:45:23 +09:00
kjh2064 744e9d6a7a ci: restore qualitative sell validation workflow
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 16s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 1m23s
2026-07-12 12:43:19 +09:00
kjh2064 521d1c0b3d test: make dotnet evidence tests runner portable
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 15s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 1m23s
2026-07-12 12:40:54 +09:00
kjh2064 d49e45b308 ci: install dotnet sdk before core tests
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 15s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 1m23s
2026-07-12 12:36:02 +09:00
kjh2064 49dc382a39 fix: remove circular WBS evidence dependency
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 15s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 56s
2026-07-12 12:33:46 +09:00
kjh2064 15b9840204 ci: regenerate completed WBS verdicts
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 15s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 54s
2026-07-12 12:30:44 +09:00
kjh2064 534582972d ci: isolate snapshot admin python dependencies
Snapshot Admin Validation / validate (push) Successful in 13s
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 20s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 58s
2026-07-12 12:28:59 +09:00
kjh2064 890ed68a0f fix: restore snapshot admin CI validation
Snapshot Admin Validation / validate (push) Failing after 7s
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Successful in 19s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 57s
2026-07-12 12:26:55 +09:00
kjh2064 92efa934a2 fix: restore authoritative database connection setting
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 15s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 54s
2026-07-12 12:22:17 +09:00
kjh2064 cc001fa263 test: verify market time series schema contract
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 15s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 54s
2026-07-12 12:20:44 +09:00
kjh2064 606664404b chore: protect external runtime connection settings
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 16s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 54s
2026-07-12 12:19:34 +09:00
kjh2064 a7f9b27a55 fix: require production database connection environment
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 16s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 54s
2026-07-12 12:16:22 +09:00
kjh2064 34991eca2d ci: enforce schema model evidence generation
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 16s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 55s
2026-07-12 12:13:02 +09:00
kjh2064 d833d386d0 feat: add postgres market time series schema
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 15s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 55s
2026-07-12 12:11:18 +09:00
kjh2064 daec1a0e1b chore: close verified M0 WBS tasks
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 16s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 53s
2026-07-12 12:10:21 +09:00
kjh2064 a9b8f46187 feat: complete dotnet formula and platform cutover gates
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 16s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 54s
2026-07-12 12:08:03 +09:00
kjh2064 eb48b7eb07 feat: add dotnet postgres json cutover gate
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 17s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 56s
2026-07-12 12:01:09 +09:00
kjh2064 187cdf99c0 fix: import logging for JSON seed ingestion
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 15s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 54s
2026-07-12 11:58:11 +09:00
kjh2064 21da79cb46 feat: ingest canonical JSON seeds into PostgreSQL
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 16s
Validators (Pushes and Pull Requests) / validate-core (push) Has been cancelled
2026-07-12 11:57:35 +09:00
kjh2064 49637f1b02 feat: export PostgreSQL training dataset as JSON
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 17s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 54s
2026-07-12 11:55:17 +09:00
kjh2064 e15e4c6e20 feat: connect formula decisions to learning ledger
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 17s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 55s
2026-07-12 11:54:06 +09:00
kjh2064 6e666844f0 feat: add canonical decision learning service
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 17s
Validators (Pushes and Pull Requests) / validate-core (push) Has been cancelled
2026-07-12 11:53:17 +09:00
kjh2064 3f6c21c86e chore: expose normalized learning validation
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 17s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 54s
2026-07-12 11:51:54 +09:00
kjh2064 6fb43fb411 test: validate normalized learning store contract
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 15s
Validators (Pushes and Pull Requests) / validate-core (push) Has been cancelled
2026-07-12 11:51:31 +09:00
kjh2064 5d89c6ad02 feat: wire normalized learning store into dotnet
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 16s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 54s
2026-07-12 11:48:32 +09:00
kjh2064 1d90580854 feat: add normalized PostgreSQL learning history
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 17s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 56s
2026-07-12 11:44:00 +09:00
kjh2064 c25e3bee7a ci: install pytest for parallel storage checks
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 15s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 54s
2026-07-12 11:39:31 +09:00
kjh2064 6e20a924db fix: make snapshot web smoke test clean-checkout safe
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 12s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 53s
2026-07-12 11:37:18 +09:00
kjh2064 780ccee1fe fix: reuse KIS tokens across concurrent requests
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 11s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 51s
2026-07-12 11:32:13 +09:00
kjh2064 129e2ec2d7 ci: parallelize independent validation jobs
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Failing after 11s
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 22s
2026-07-12 11:14:58 +09:00
kjh2064 4cd1cab466 ci: export isolated Python dependencies
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 20s
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Has been skipped
2026-07-12 11:12:19 +09:00
kjh2064 be043a85e3 ci: remove runner venv dependency
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 10s
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Has been skipped
2026-07-12 11:11:55 +09:00
kjh2064 1c46d7b558 fix: add admin collection start route
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 8s
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Has been skipped
2026-07-12 11:10:15 +09:00
kjh2064 7f0c9b9a27 ci: harden Python environment bootstrap
Validators (Pushes and Pull Requests) / validate-core (push) Failing after 7s
Validators (Pushes and Pull Requests) / validate-ui-and-storage (push) Has been skipped
2026-07-12 11:06:07 +09:00
kjh2064 42d45e85fb ci: validate main pushes automatically
Validators (Pull Requests Only) / validate-core (push) Failing after 8s
Validators (Pull Requests Only) / validate-ui-and-storage (push) Has been skipped
2026-07-12 11:03:52 +09:00
kjh2064 e7d1069222 feat: add quant engine WBS verification harness 2026-07-12 10:58:22 +09:00
kjh2064 a274ef448a fix: Auth cookies invalidated on every deployment (Data Protection discriminator)
User reported: "배포가 되면 인증이 풀린다" (auth resets after every
deployment).

Root cause: Program.cs had no explicit Data Protection configuration.
Without SetApplicationName, ASP.NET Core derives the key-ring
discriminator from the app's physical content root path. Every
deployment lands in a brand-new directory
(~/deployments/quantengine_{tag}_{hash}/), so the discriminator
changed on every single release. The cookie authentication ticket is
encrypted/signed via this key ring, so once the discriminator
changed, every previously-issued auth cookie became undecryptable --
forcing all logged-in users to authenticate again after each deploy,
even well inside their 12-hour ExpireTimeSpan.

Fix: explicit .SetApplicationName("QuantEngine") pins a stable
discriminator across deployments, and .PersistKeysToFileSystem points
at %LOCALAPPDATA%/quantengine-keys (Linux: ~/.local/share/quantengine-keys
via User=kjh2064 in the systemd unit) -- a location outside the
versioned deployment directories, so the actual key material also
survives every redeploy and service restart instead of only the
discriminator being stable.
2026-07-12 02:04:03 +09:00
kjh2064 7283532c38 fix: Hangfire recurring-job initialization failing every startup
Discovered while verifying the new Operations page against a local
instance (SSH-tunneled to prod Postgres): every startup logged
'Hangfire setup failed: Cannot resolve scoped service
QuantEngine.Web.Services.SchedulerService from root provider' and
silently skipped InitializeSchedules() entirely.

SchedulerService is registered AddScoped, but UseHangfireSetup()
resolved it directly from app.Services (the root/singleton-level
provider), which cannot construct scoped services without an active
scope. This has apparently been broken for a while -- the 4 recurring
jobs (daily-collection, hourly-price-update, weekly-report,
monthly-optimization) only kept showing up because Hangfire persists
recurring job definitions in PostgreSQL from whatever earlier
deployment last managed to register them; any code change to those
schedules would silently never take effect on redeploy.

Fixed by creating an explicit scope (serviceProvider.CreateScope())
before resolving SchedulerService. Verified locally: the warning is
gone and the log now shows "Hangfire schedules initialized
successfully" followed by the dispatchers starting.
2026-07-12 01:57:08 +09:00
kjh2064 489da25f1b fix: Remove fake hardcoded data, rebuild admin layout with real Tabler components
Root cause: user asked why logout was missing. Playwright audit against
production found logout works fine, but surfaced two real defects and
led to a wider audit that found extensive fabricated data across the
admin pages -- none of it backed by the database despite CLAUDE.md's
policy that all data must come from DB records.

Layout (_AdminLayout.cshtml):
- Full rewrite using Tabler's actual navbar-vertical/page-wrapper/footer
  component structure instead of ad-hoc inline CSS. The old layout had
  no footer element at all, and its mobile breakpoint CSS hid the
  sidebar off-screen (left: -260px) with no hamburger button to bring
  it back -- verified via Playwright screenshot at 375px width that
  the entire nav menu was inaccessible on mobile, leaving only Logout
  reachable. Tabler's navbar-toggler + Bootstrap collapse (bundled in
  tabler.min.js) now restores it; verified the toggle actually opens
  the menu via Playwright.
- Active nav-link highlighting moved from client-side JS string
  matching to a server-side Razor helper against Context.Request.Path.

Fake/hardcoded data removed or replaced with real DB/Hangfire state:
- Dashboard: deleted the "최근 시스템 이벤트" table (3 rows hardcoded
  from DateTime.Now with fake descriptions like "시스템 초기화" /
  "데이터베이스 백업" -- no backing table exists). Removed hardcoded
  "정상"/"연결됨" status badges and "버전: v0.1.0"/"업타임: 정상";
  replaced with a real IsDatabaseConnected flag (true only if the
  page's actual DB queries succeeded) and the real
  IWebHostEnvironment.EnvironmentName.
- Monitoring: removed hardcoded "API 서버: 운영 중" (no real signal
  backs it) and wired "데이터베이스: 연결 정상/끊김" to the same
  real success/failure state as the page's own DB calls.
- Operations: this page was entirely fabricated -- ScheduledJobs,
  RecentExecutions, IsJobProcessorRunning, PendingJobsCount, and
  StatusMessage were all static values with zero connection to
  Hangfire, despite Hangfire actually running in production
  (confirmed via journalctl: ServerWatchdog, RecurringJobScheduler
  dispatchers active) with 4 real recurring jobs registered in
  SchedulerService (daily-collection, hourly-price-update,
  weekly-report, monthly-optimization). Rewrote to query
  JobStorage.Current.GetConnection().GetRecurringJobs() and
  GetMonitoringApi() directly: real scheduled jobs, real succeeded/
  failed executions, real server count, real enqueued count. Verified
  locally (SSH-tunneled to prod DB) that this now returns the actual
  4 registered jobs with correct next-run times and one real
  RunDailyCollectionAsync execution.

Also fixed the page-title duplication on Monitoring/Operations
(ViewData["Title"] included "- QuantEngine" AND the layout appended
it again -> "모니터링 - QuantEngine - QuantEngine" in the browser tab).

Separately discovered (not fixed in this commit, flagging for
follow-up): Hangfire's SchedulerService.InitializeSchedules() fails
every startup with "Cannot resolve scoped service 'SchedulerService'
from root provider" -- the 4 recurring jobs above still show up
because they persist from an earlier successful registration, but
re-registration is silently broken on every current boot.

Verified end-to-end with Playwright against a local instance (SSH
tunnel to production Postgres): login, all 5 admin pages render
without errors, mobile hamburger opens the sidebar, and Operations
shows genuine Hangfire data.
2026-07-12 01:54:00 +09:00
kjh2064 4b29fafcff fix: Use KST (Asia/Seoul) instead of UTC for release date component
User caught this directly: it's already 2026-07-12 in Korea, but
Run #2008's release was tagged quant_20260711.3.7150737 -- the wrong
date.

Confirmed: UTC was still 2026-07-11 16:2x when KST was already
2026-07-12 01:2x (9-hour offset). prepare-release.yml computed
TODAY via `TZ=UTC date +%Y%m%d`, which is only "correct" if the team
operates on UTC -- but this project's production server logs,
deployment cadence, and team are all Korea Standard Time. Any release
cut between midnight and 9am KST would silently tag itself with
yesterday's date.

Fixed by using `TZ=Asia/Seoul date +%Y%m%d` instead.
2026-07-12 01:29:14 +09:00
kjh2064 71507374ca fix: Reset release sequence number to 0 on each new date
Per spec: the sequence number is a per-day counter that resets on
date change and starts at 0, not 1. The first release of a day is
quant_YYYYMMDD.0.hash, the second .1, etc.

Previous commit fixed *counting* today's releases via the Gitea API
(instead of the always-empty local git tags from a shallow checkout),
but still added +1 on top, which would have produced 1, 2, 3... for
the first, second, third releases of a day instead of 0, 1, 2.
DEPLOY_COUNT is now just RELEASES_TODAY directly.
2026-07-12 01:23:56 +09:00