feat(v2-ui): v2 frontend vertical slice — schemas, records, search, reference review#230
Open
JonnyTran wants to merge 29 commits into
Open
feat(v2-ui): v2 frontend vertical slice — schemas, records, search, reference review#230JonnyTran wants to merge 29 commits into
JonnyTran wants to merge 29 commits into
Conversation
Roborev job 131 (Low): dtypeDefaultEditor matched pandas interval[...] as a number via the broad 'int' prefix — now requires a digit (int64/uint8/float32). QuestionType intentionally omits the API's 'span' variant (rejected on write); documented at the type and cast site.
Roborev job 133 (Low): add SchemaRepository.getSchema URL+mapping assertion and
a GetSchemaSettingsUseCase test verifying all three repo calls fire and the
{ schema, versions, questions } shape is returned.
The pager lived inside the results-only v-else, so advancing onto an empty page (approximate totals let 'next' run one page past the last full page) hid all controls and stranded the user with currentOffset advanced. Move the pager outside the results branch and show it whenever currentOffset > 0, so 'previous' stays available to recover.
… 140) Mirror useSchemasViewModel: a rejected getSettings fetch now sets loadFailed and renders the schemas.loadError branch instead of a blank page (both isLoading and settings were falsy). Adds a test asserting loadFailed toggles on rejection.
…puts (reuse-don't-fork)
…upsert (roborev job 143)
Add ProjectionRepository.test.ts asserting the percent-encoded slashed-DOI URL
(seam B) with workspace_id params and the full ProjectionView->DTO mapping, plus
an upsertResponse(null, 'discarded') case asserting the { values: null } body.
…ans and version tolerance
Add a two-schema projection case asserting each ReviewRecord resolves against its own schema — distinct schemaName, cells (questions), and context fields — exercising the schemaId-keyed contexts/records/version maps that single-schema tests can't.
The emitting boolean reset synchronously before the async watcher, so every committed cell edit rebuilt the tabulator and lost focus. Replace it with a last-emitted-value signature guard (flush-timing independent) and split the watchers so column/editable changes always rebuild while the value-echo doesn't. Adds mount-level tests asserting a committed edit does not rebuild but an external modelValue change does; mock now records construction count and stores handlers.
…nce and orphan surfacing
…job 150)
Add ReviewCellInput.test.ts with stubs that emit on-selected/on-reorder after
mutating their bound options, exercising the adapter-invocation handlers: single
label -> scalar, multi label -> array (multiple flag), rating -> number, ranking
-> [{value,rank}]. Previously only the text path ran end-to-end (leaves stubbed inert).
…slashed-DOI scenarios Note: live e2e run is gated to CI or a live-stack session — local Playwright chromium can't launch on the Orin host and the specs need a seeded backend on :6900 + remote chromium (ccui:9222), both unavailable here. Statically verified: ruff on the seed script, playwright --list resolves the v2 project and both specs, config/fixtures parse.
…cenarios Live run gated to CI / live-stack session (Orin chromium + seeded :6900 backend unavailable here). Scenario 4 (draft-lifecycle) is itself the seam-C gate: the plan's curl-based seam-C server check requires the live stack, so it's pending — if a draft projects, this spec fails and surfaces the server bug per §10.3. Statically verified: playwright --list collects all 5 v2 specs.
…v job 153) The /schemas list renders for the auto-selected (first) workspace, so asserting the seeded schema flaked when another workspace sorted ahead of e2e-v2. Pre-seed the persisted selection (localStorage extralit-selected-workspace-id) with the seeded workspace id via addInitScript so saveWorkspaces() restores it deterministically.
Type-friction only, no logic change: bridge the opaque columns_cache cast through unknown, cast tabulator editor:false (runtime-valid, absent from @types) and the mock's static test hooks, and cast empty-tuple mock.calls indexing. npx nuxi typecheck now reports 0 errors; full suite (861) still green.
…(roborev job 154) review-loop and draft-lifecycle both mutated the shared seed record's response, racing under fullyParallel and — since draft-lifecycle sorts first and leaves a submitted response — breaking review-loop's clean-Suggestion precondition in serial order. Add createIsolatedRecord (own reference + seeded suggestion via the API) so each mutating spec runs on its own record: parallel-safe and order-independent.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
Summary
First v2 UI vertical slice — schemas → records → search → annotation → reference review — built as an isolated
v2/DDD module inextralit-frontend/, consuming the shipped/api/v2surface and producing the reference-agnosticProjectionReviewForm.Implements Tasks 4–17 of
docs/superpowers/plans/2026-07-10-v2-frontend-vertical-slice.md(Tasks 1–3 landed earlier). Executed task-by-task with TDD.What's included
Domain + infrastructure (
v2/)Schema,SchemaVersion,ColumnMeta,Question,V2Record,RecordsPage,SearchCriteria,ReferenceReview/ReviewCell/ReviewRecord,SuggestionHint, widget mapping + adapters.SchemaRepository,V2RecordRepository,AnnotationRepository,ProjectionRepository; response value double-wrap/unwrap; two-shape 422 normalizer.v2/ts-injecty DI container loaded after v1's inplugins/3.di.ts; reference-keyed Pinia storage.Pages & components
/schemas,/schemas/[id](records table + FTS search + status filter),/schemas/[id]/settings(read-only inspector + rebuild-index),/references/[...reference](review page).ProjectionReviewForm(record cards → per-type widget dispatch, provenance badges, not-applicable + orphaned-value surfacing) and a lean ~300-LOCV2TableEditortabulator wrapper.schemas.*/review.*i18n families (en; fallback covers de/es/ja).Reuse-don't-fork
git mv'd tocomponents/base/inputs/, v1 wrappers re-pointed — no copy-paste.e2e (
e2e/v2/)v2project (isolated from legacy specs), CDP-remote-chromium fixture, deterministic Python seed script, and 5 seam-gating scenarios (bearer auth, slashed-DOI encoding, suggestion→response loop, draft lifecycle, search freshness). Response-mutating specs use per-spec isolated records.Verification
npm run test— 861 passingnpm run lint(eslint --quiet) — cleannpx nuxi typecheck— 0 errorsnpm run gen:api:types— no OpenAPI types driftv2/imports only the allowed v1 seams; v1 never importsv2/9 roborev review findings were surfaced and fixed during implementation (all closed) — including a real
V2TableEditorself-emit rebuild bug and the e2e shared-record isolation issue.Notes / follow-ups (deferred per plan §ledger)
draft-lifecyclee2e spec but not yet verified against a live stack — if a draft projects, that spec fails and surfaces the server bug.columns_cache, span questions, Queue UI (Phase 5), and v1 retirements (Phase 6) are out of scope.