feat(api-server)!: Move WebUI metadata, compression, file-listing, and stream-file operations to the API server. - #2488
Draft
junhaoliao wants to merge 39 commits into
Draft
feat(api-server)!: Move WebUI metadata, compression, file-listing, and stream-file operations to the API server.#2488junhaoliao wants to merge 39 commits into
junhaoliao wants to merge 39 commits into
Conversation
BREAKING CHANGE: Remove the WebUI /api/compress, /api/compress-metadata, /api/os, /api/stream-files, and /api/archive-metadata endpoints.
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
junhaoliao
marked this pull request as draft
August 20, 2026 20:03
`ct lint` rejects chart template changes that don't bump the chart version, so `clp-package-helm / lint` fails on this branch's edits to `api-server-deployment.yaml`, `configmap.yaml`, and `values.yaml`.
`submitExtractStreamJob` now goes through the generated API client and rejects with a plain `Error`, but the handler still branched on `isAxiosError`. That branch is never taken, so every extraction failure rendered the literal "Unknown error." instead of the underlying message.
The API server returns a compression job's decoded `clp_config` as an opaque JSON value, which the generated client types as `unknown`. The Jobs table cast it straight to `ClpIoConfig`, dropping the schema check the removed Fastify route performed. Validate it against `ClpIoPartialConfigSchema` at the API boundary instead, so a malformed config fails with a clear error and the table no longer needs a cast.
`metadata_client` used the shared `QUERY_JOBS_TABLE_NAME` constant for one table but inlined `query_tasks` and `compression_jobs` as literals, so the same kind of value had two conventions in one file. Add the two missing constants alongside their siblings, mirroring `clp_py_utils.clp_config`, and use them.
Moving the compression-metadata and stream-file routes to the API server left `schemas/compress-metadata.ts`, `schemas/stream-files.ts`, and `EXTRACT_JOB_TYPES` without any consumer, alongside the `schemas/os.ts` and `schemas/archive-metadata.ts` that were already removed.
…, and dataset parsing.
hoophalab
self-requested a review
August 24, 2026 17:02
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Moves metadata queries, compression submission, filesystem listing, and stream-file extraction out of the WebUI server and into typed Rust API-server endpoints. The WebUI now consumes the generated OpenAPI client for these operations, and the obsolete Fastify routes and database/S3 managers are removed.
This also fixes the issues found while reviewing the original metadata branch and merged PR #2484: CLP text-mode table names now match Python's no-dataset convention; CLP-S aggregate counts decode without silently becoming null; S3 stream files use pre-signed URLs; extraction uses shared job enums, configured collection/target-size values, and an overall timeout; filesystem listing uses the generated snake_case contract and is contained to the configured read-only input root; compression requests preserve the timestamp-key contract and the scheduler's zstd-msgpack framing; compressed files retain host-absolute original paths by stripping the shared
/mnt/logscontainer prefix; timestamp-column names are de-duplicated and deterministically ordered; native search remains active until both result streams finish; and the WebUI proxy has no five-minute Undici timeout. Because all WebUI modes now depend on the migrated endpoints, package validation and Helm rendering reject WebUI deployments without an API server, including Presto deployments.The WebUI cleanup also removes 19 settings that no longer have readers, its unused Fastify MySQL plugin, and the AWS, MySQL, and MessagePack dependencies orphaned by the migration.
A follow-up audit also aligns compression-path display with the Jobs table, preserves API-server error details in the UI, restores the legacy compression-request validation, removes a superseded timestamp-column query, reduces ingestion-details queries to one scan per table, supports every configured AWS authentication mode, makes metadata table-set selection explicit, checks file-listing containment before probing the filesystem, removes the now-unreachable nullable API-server settings path, and safely handles omitted nullable timestamp fields. Focused unit coverage was added for path resolution, compression-config encoding, query construction, and dataset parsing.
The API-server container now receives the read-only filesystem-input and AWS configuration mounts in both Compose and Helm. Constraining
/os/lsand compression paths tologs_input.directoryis hardening for a pre-existing unrestricted listing surface, not a regression fix.Rust linting and formatting now use the known-good
nightly-2026-08-21snapshot instead of a rolling nightly. The 2026-08-22 compiler snapshot crashes internally while checkingclp-rust-utils; the same crash occurs on unchangedmain, so pinning makes the gate reproducible without changing production builds or runtime behavior.This is a breaking change because the WebUI routes
/api/compress,/api/compress-metadata,/api/os,/api/stream-files, and/api/archive-metadataare removed. Their replacements are served under/api/v1by the API server.The API server's own
/api/v1/column_metadata/{dataset_name}/timestamproute also moves to/api/v1/metadata/column_metadata/{dataset_name}/timestamp, so any direct consumer of that endpoint needs to be updated.Checklist
breaking change.
Validation performed
Final committed source:
b7cd0da67c1c5055838dff34d59e512f988b9011; repository:/home/junhao/.codex/worktrees/6905/clp. Unless noted otherwise, commands below exited 0.Baseline
At clean merged
mainSHAfcfe3aee252fc8ac0ad5a0942ea029e65ac17f1din/home/junhao/workspace/clp/.claude/worktrees/verify-main-fcfe3ae,task lint:check-rust,task lint:check-py,task lint:check-js,task lint:check-yaml,task tests:rust-all,task codegen:openapi && task codegen:webui-generate-api-client-schema, and a cleanpnpm install --frozen-lockfile && pnpm run buildall exited 0; Rust reported 62/62 tests and code generation produced no drift. The live baseline reproduced HTTP 500 responses from all CLP text metadata endpoints because they queriedclp_default_archives/clp_default_files, while the database containedclp_archives/clp_files. On CLP-S datasetsa,b, the pre-fix ingestion-details endpoint returnednum_files: nullandnum_messages: nullwhile the equivalent aggregate SQL returned numeric values, reproducing the DECIMAL decode problem.Required automated gates
task lint:fix-rust— exit 0; installednightly-2026-08-21(rustc 1.100.0-nightly (8925ea358 2026-08-20)), then Clippy and rustfmt completed without changing Rust source.task lint:check-rust— exit 0;cargo +nightly-2026-08-21 fmt --all -- --checkandcargo +nightly-2026-08-21 clippy --all-targets --all-features -- -D warningspassed.clp-rust-checks— passed in 15m28s on a clean runner, including lock validation, lint, and all Rust tests.task lint:check-py— exit 0; the task printed the same configured non-blocking mypy diagnostics as baseline.task lint:check-js— exit 0; 6/6 Turbo tasks passed.task lint:check-yaml— exit 0.task tests:rust-all— exit 0; 110/110 tests passed, including the API-server path/config/query tests and the AWS-authentication/config helper tests, and the task stopped its LocalStack container successfully.task codegen:openapi && task codegen:webui-generate-api-client-schema— exit 0; neither generated artifact changed.components/webui, old root/packagenode_modulesanddistdirectories were moved aside, thenpnpm install --frozen-lockfileandpnpm run buildran with a client cache miss — exit 0 after the generated nullable request adapter was corrected. On the current tree,pnpm exec turbo build --forcealso exited 0 with 5/5 uncached builds, including the client, server, generated API client, common package, and Log Viewer.task— exit 0 at the final head; the native binaries, Rust services, WebUI, package image, andbuild/clp-packagewere rebuilt.pnpm --filter @webui/server testfromcomponents/webui— exit 0; 4/4 tests passed.pnpm install --frozen-lockfilefromcomponents/webui— exit 0 across all six workspaces after regenerating the lockfile with the generated Log Viewer workspace present.webui.query_engineto Presto andapi_serverto null;validate_webui_configraised the expected Presto-specific API-server requirement.git diff --check— exit 0.Follow-up audit plan checks
Plans 005–024 were re-verified against the current branch, accepted, implemented, and split into one commit per plan. In addition to the branch-wide gates above:
ApiServerUrlnon-nullable; the server test suite remained 4/4. Helm rendered a stringApiServerUrlby default and rejectedclpConfig.api_server=nullwith the expected invariant message.clp-rust-utilsreached 31 passing focused tests, includingprofileandenv_varsauthentication and explicit metadata table-set naming.pnpm exec turbo build --forcecompleted 5/5 uncached package builds.CLP_HOME=/opt/clp, named-profile mounts for all S3 consumers, and environment credentials scoped to exactly the six services that access S3. Credential files were written with mode0600, stale credentials were cleared, and missing variables failed setup.Live deployments and issue-specific checks
The package image used for the deployment matrix was rebuilt from
818bad8122b537af498d6798b2bc66a51c886f5d;task packagewas run again successfully after merging currentorigin/mainatdfabec6b1401552a1dc75153bb4a9c626db25d93, and the fulltaskbuild passed after the CI toolchain pin at final headb7cd0da67c1c5055838dff34d59e512f988b9011../sbin/start-clp.shbrought up healthy database, scheduler, worker, API-server, and WebUI containers, then exited 1 because Docker Compose v5.3.1 reports intentionally zero-replica services as missing duringup --wait. A plaindocker compose up --detachcompleted. A real filesystem compression job succeeded (1 file, 11 messages);/metadata/time_range,/metadata/space_savings, and/metadata/ingestion_detailsreturned HTTP 200 through both ports 3001 and 4000 with populated values. Playwright showed the populated Ingest cards and expanded the configured input directory tosimple.txt../sbin/stop-clp.shexited 0.aandbsucceeded, producing 50 matches in ten archives. Withmax_num_results=5,sorted=truestreamed the exact newest timestamps1311208074120,1311208074120,1311207834960,1311207834960, and1311207595800.mongoshconfirmed all 50 documents and thetimestamp-descendingindex{timestamp: -1, _id: 1}. A Playwright route delayed aggregation results by 8 seconds; after table results arrived the UI remained Running with Cancel available until the aggregation stream finished./os/lsreturnedis_expandableandparent_path, Playwright expanded the configured directory and displayed its file, and/etcreturned HTTP 400 because it is outside the configured root./metadata/ingestion_details?dataset=a,breturned numeric0,0, not null, so the explicitCAST(... AS SIGNED)values decode correctly and the review's DECIMAL hypothesis was refuted. This fixture also confirmed that the current CLP-S compressor leaves its per-dataset files tables empty; populating those tables is separate database/data-pipeline work and is intentionally excluded from this PR.tools/scripts/localstack/start.py,create-bucket.py, andstop.pyall exited 0; cleanup ran successfully. Withstream_output.storage.type: s3,env_varsauthentication, a custom endpoint, a nondefault key prefix, andtarget_uncompressed_size: 1024, compression and both S3-backed and Mongo-buffered searches succeeded. The six scoped services received mode-0600credential files. Clicking a result caused/stream_files/extractto return HTTP 200 with a pre-signed S3 URL; after applying bucket CORS for the browser origin, the object GET returned HTTP 200 and the Log Viewer rendered 3 events with no console errors.curl http://127.0.0.1:4100/api/v1/delayexited 0 with HTTP 200 andtime_total=305.027806; the server loggedresponseTime=305025.92 ms, confirming Undici did not fail at 300 seconds. Both temporary processes were stopped.--setup-onlysucceeded for Presto with the API server enabled and rejectedapi_server: nullwith the expected message explaining that Presto also reads metadata through the API server. Helm enforces the same invariant, and the official Presto helper no longer disables the API server.Helm rendering
From the current working tree,
helm dependency build tools/deployment/package-helm,task lint:check-helm, and the defaulthelm template tools/deployment/package-helmrender exited 0. A complete S3 fixture with credentials also rendered successfully.helm template tools/deployment/package-helm --set clpConfig.api_server=nullexited nonzero with the new WebUI/API-server invariant instead of rendering a broken WebUI. The rendered settings JSON parsed successfully with 7 public and 9 server keys. The rendered API-server Deployment had a read-only logs-input mount only for filesystem input and an AWS-config mount when configured. A kind deployment was not run.