Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
8b76b48
docs: add Vue 2→3 / Nuxt 2→4 migration design
JonnyTran Jun 13, 2026
6d9682f
docs: add Vue 2→3 / Nuxt 2→4 implementation plan
JonnyTran Jun 13, 2026
c54236f
chore: gitignore .worktree/ for isolated worktrees
JonnyTran Jun 13, 2026
c97c417
build: swap dependency set for Vue 3 / Nuxt 4
JonnyTran Jun 13, 2026
826c651
config: port nuxt.config to Nuxt 4 (vite, nitro proxy, i18n v10)
JonnyTran Jun 13, 2026
0343a5e
config: drop babel/jest config, extend Nuxt 4 tsconfig
JonnyTran Jun 13, 2026
b9d9726
test: add Vitest + @nuxt/test-utils config and setup
JonnyTran Jun 13, 2026
1efbe0d
refactor: replace Vue.filter number formatters with helpers
JonnyTran Jun 13, 2026
3dea37a
refactor: replace Vue-instance toast bus with mitt
JonnyTran Jun 13, 2026
ab9d482
refactor: port tooltip directive to Vue 3 createApp
JonnyTran Jun 13, 2026
fda710a
refactor: reimplement v-click-outside via @vueuse/core
JonnyTran Jun 13, 2026
4605253
feat: custom svg-icon component replacing vue-svgicon
JonnyTran Jun 13, 2026
5a6a120
refactor: Nuxt 4 plugin + global middleware structure
JonnyTran Jun 13, 2026
a1b1463
feat: plain-axios HTTP plugin with ported error handler + cache
JonnyTran Jun 13, 2026
cbffef2
feat: custom AuthService token store implementing IAuthService
JonnyTran Jun 13, 2026
7d101ba
refactor: migrate composition-api imports to Vue 3 / Nuxt composables
JonnyTran Jun 13, 2026
b929dc0
refactor: Vue 3 template + Options-API codemods (.vue)
JonnyTran Jun 13, 2026
6c69102
refactor: replace $root/$nuxt bus, $nuxt.$t, $destroy (Vue 3 removals)
JonnyTran Jun 13, 2026
d188f21
refactor: port draggable, tiptap, md-loader to Vue 3 / Nuxt 4
JonnyTran Jun 13, 2026
f837a30
fix(build): i18n strictMessage, static assets, v-click-outside/vue-de…
JonnyTran Jun 13, 2026
aad4476
fix(build): i18n entry import, pdf-viewer v-model-on-prop, template v…
JonnyTran Jun 13, 2026
808de91
build: pin all @intlify/* runtime packages to 11.4.5, drop Vue-2 pdf-…
JonnyTran Jun 13, 2026
55ec7a2
fix(build): Vue 3 createApp span-entity factory, dompurify default im…
JonnyTran Jun 13, 2026
3ec7033
fix(vue3): mark type-only imports with inline `type` modifier (216 ac…
JonnyTran Jun 13, 2026
996dee8
test(vitest): mechanical jest->vi, propsData->props, destroy->unmount…
JonnyTran Jun 13, 2026
6da3a25
test: port unit suite to Vitest + VTU v2 (735 passing, >= baseline pa…
JonnyTran Jun 13, 2026
fff7f97
config: ESLint 8 flat-compat fix + preserve non-strict TS posture (Nu…
JonnyTran Jun 13, 2026
041331b
docs: update frontend CLAUDE.md for Vue 3 / Nuxt 4 / Vitest stack
JonnyTran Jun 13, 2026
654080c
fix(vue3): drive nuxi typecheck to 0; fix runtime bugs surfaced by ty…
JonnyTran Jun 13, 2026
777935c
chore: update .gitignore and docker-compose for service profiles
JonnyTran Jun 13, 2026
52e5b8a
docs: vue3 remediation plan (session 4)
JonnyTran Jun 13, 2026
35e15c9
test(vue3): snapshot HTML not VueWrapper in base-date; drop leaked-pa…
JonnyTran Jun 13, 2026
56a2c8f
fix(vue3): migrate dynamic routes to bracket form + revive page guards
JonnyTran Jun 13, 2026
aa51931
fix(vue3): unmount span entity Vue apps to stop leak
JonnyTran Jun 13, 2026
c4c3279
fix(vue3): useHead() for page title + wire root error.vue
JonnyTran Jun 13, 2026
ab9de1b
fix(vue3): rename transition start-state classes to *-enter-from
JonnyTran Jun 13, 2026
e970473
fix(vue3): inject highlight CSS as <style> text child, not v-html
JonnyTran Jun 13, 2026
ce3b87d
fix(vue3): replace removed $slots.default VNode API
JonnyTran Jun 13, 2026
65d68d4
fix(vue3): correct $attrs listener-detection key (on-click -> onOnClick)
JonnyTran Jun 13, 2026
9831e86
chore(vue3): restore working ESLint config + config cleanups
JonnyTran Jun 13, 2026
1ed8813
fix(vue3): declare emits on native-event-emitting components
JonnyTran Jun 13, 2026
c00df30
docs(vue3): record rationale for pages:extend filter and eslint globals
JonnyTran Jun 13, 2026
5661891
fix(vue3): repair v-model on LoginInput so sign-in works again
JonnyTran Jun 13, 2026
22fa099
fix(vue3): migrate all components off the removed Vue 2 `model:` option
JonnyTran Jun 13, 2026
ed37539
docs(vue3): record reconciled e2e login helper in CLAUDE.md
JonnyTran Jun 14, 2026
abcc6f3
fix(vue3): preserve /api prefix in nitro devProxy
JonnyTran Jun 14, 2026
9a84793
fix(vue3): pass primitive string to $t for Field/Question type badges
JonnyTran Jun 14, 2026
1a65e34
fix(vue3): make BaseInput dual-purpose so v-model binds
JonnyTran Jun 14, 2026
f4c2eb6
fix: update ImportFlow.spec.js to improve component stubbing and add …
JonnyTran Jun 17, 2026
b28c12b
chore: update subproject commit and add @vitest/coverage-v8 dependency
JonnyTran Jun 17, 2026
a188aee
Merge branch 'develop' into feat/vue-v2-to-v3
JonnyTran Jun 18, 2026
457a5b3
Merge branch 'develop' into feat/vue-v2-to-v3
JonnyTran Jun 18, 2026
ba2ecb6
Merge branch 'develop' into feat/vue-v2-to-v3
JonnyTran Jun 18, 2026
f6aa7ad
fix(ci): serve Nuxt 4 SPA + restore frontend lint/test in CI
JonnyTran Jun 18, 2026
0a4897b
fix(frontend): stop welcome-hf-sign-in redirect loop on Vue Router 4
JonnyTran Jun 18, 2026
90b8523
fix(frontend): make AuthService.user reactive via shallowRef
JonnyTran Jun 20, 2026
7f8646a
fix(vue3): migrate annotation selection components to modelValue + wi…
JonnyTran Jun 20, 2026
edc7955
refactor(ci): remove repo visualizer steps from workflows and update …
JonnyTran Jun 24, 2026
235ea68
feat(ci): introduce download-frontend-artifact action and restructure…
JonnyTran Jun 25, 2026
b091cbe
feat(ci): enhance Vercel integration and update workflows
JonnyTran Jun 25, 2026
3b7eea1
fix(vercel): use default export in vercel.ts so rewrites land at conf…
JonnyTran Jun 25, 2026
144a4be
feat(ci): update GitHub workflows to include feat/** branch for CI tr…
JonnyTran Jun 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
25 changes: 25 additions & 0 deletions .github/actions/download-frontend-artifact/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Download prebuilt frontend statics
description: >-
Download the latest successful extralit-frontend.yml SPA build into
extralit-frontend/.output/public, so a server build can bake it into the wheel
(and the HF Space built FROM it) as the bundled fallback UI instead of running
npm. The SPA is env-agnostic (relative /api), so the same artifact works
regardless of where the server is deployed.

inputs:
branch:
description: Branch whose latest successful frontend build to fetch (main or develop).
required: false
default: develop

runs:
using: composite
steps:
- uses: dawidd6/action-download-artifact@v21
with:
workflow: extralit-frontend.yml
branch: ${{ inputs.branch }}
name: extralit-frontend
path: extralit-frontend/.output/public
workflow_conclusion: success
if_no_artifact_found: fail
116 changes: 0 additions & 116 deletions .github/workflows/extralit-frontend.build-push-dev-frontend-docker.yml

This file was deleted.

148 changes: 148 additions & 0 deletions .github/workflows/extralit-frontend.build-push-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
name: Deploy PR preview HF Space

# Builds a dev-tagged extralit-server image (pr-<n>) and dispatches the HF Space repo to
# deploy an ephemeral Space at https://huggingface.co/spaces/extralit-dev/pr-<n>.
#
# Deliberately decoupled from extralit-server.yml so it does NOT run on every push:
# - auto: only when a PR (touching the server or frontend) is marked "ready for review"
# - manual: workflow_dispatch with a PR number, to (re)deploy a preview on demand
# main/develop deploys keep flowing through extralit-server.yml as before.

on:
# Note: `ready_for_review` only fires on a draft→ready transition. A PR opened
# directly as non-draft does NOT auto-trigger — mark it ready, or use the manual
# workflow_dispatch below. This is intentional: previews never build on push.
pull_request:
types: [ready_for_review]
paths:
- "extralit-server/**"
- "extralit-frontend/**"
- ".github/workflows/extralit-frontend.build-push-dev.yml"
- ".github/workflows/extralit-server.build-docker-images.yml"

workflow_dispatch:
inputs:
pr_number:
description: "PR number to deploy to extralit-dev/pr-<n>"
required: true
type: string

concurrency:
# One preview build per PR; cancel superseded runs.
group: pr-preview-${{ github.event.pull_request.number || inputs.pr_number }}
cancel-in-progress: true

permissions:
contents: read

jobs:
build:
name: Build `extralit-server` package (frontend baked in)
runs-on: ubuntu-latest
# Fork PRs don't receive secrets (Docker login / dispatch would fail), so skip them.
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.fork == false

defaults:
run:
shell: bash -l {0}
working-directory: extralit-server

steps:
- name: Checkout Code 🛎
uses: actions/checkout@v4
with:
# Auto path: default merge ref (refs/pull/<n>/merge). Manual path: resolve the PR's
# merge ref from pr_number so the build is self-contained — no need to run from the
# PR's head branch for the pr-<n> image/Space to reflect that PR's code.
ref: ${{ github.event_name == 'workflow_dispatch' && format('refs/pull/{0}/merge', inputs.pr_number) || github.ref }}

- name: Install uv
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86
with:
pyproject-file: "extralit-server/pyproject.toml"
enable-cache: true
cache-local-path: ~/.cache/uv
cache-dependency-glob: "extralit-server/uv.lock"

# No pytest here — preview-only path. The live frontend preview for this PR is published to
# Vercel by extralit-frontend.yml; the HF Space only needs a bundled fallback UI, so bake
# the prebuilt develop frontend artifact instead of rebuilding from source.
- name: Download prebuilt frontend statics
uses: ./.github/actions/download-frontend-artifact
with:
branch: develop

- name: Build package
run: |
set -euo pipefail
# Bake the compiled SPA into the wheel's static dir. Fail loudly if it's missing or
# empty, otherwise the server ships with no statics and 404s every route.
cp -r ../extralit-frontend/.output/public src/extralit_server/static
test -f src/extralit_server/static/index.html
uv build

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: extralit-server
path: extralit-server/dist

build_docker_images:
name: Build docker images
needs:
- build
uses: ./.github/workflows/extralit-server.build-docker-images.yml
with:
is_release: false
publish_latest: false
# PR number on BOTH paths (manual input, or the PR number on the auto path). This forces
# IMAGE_TAG=pr-<n>, DISPATCH_BRANCH=<n>/merge, and crucially PUBLISH_LATEST=false so a
# preview never republishes the dev :latest tag from unreviewed PR code.
pr_number: ${{ inputs.pr_number || github.event.pull_request.number }}
secrets: inherit

# Opportunistic: this PR has its own ephemeral HF Space (extralit-dev/pr-<n>), so point the
# PR's Vercel preview at it instead of the shared develop backend. Vercel's native Git
# integration builds the preview; we just set a branch-scoped Preview env var (read by
# extralit-frontend/vercel.ts at build time) and redeploy the branch's latest preview so it
# takes effect now. Best-effort — never blocks the preview pipeline.
point-preview-at-pr-space:
name: Point Vercel preview at this PR's HF Space
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.fork == false
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ inputs.pr_number || github.event.pull_request.number }}
HEAD_REF: ${{ github.head_ref }}
steps:
- name: Set branch-scoped preview backend + redeploy
continue-on-error: true
run: |
set -uo pipefail
if [[ -z "${VERCEL_TOKEN:-}" || -z "${VERCEL_PROJECT_ID:-}" ]]; then
echo "Vercel secrets not configured; skipping preview override."; exit 0
fi
# Resolve the PR head branch (manual dispatch only carries the PR number).
BRANCH="${HEAD_REF:-}"
if [[ -z "$BRANCH" ]]; then
BRANCH=$(gh pr view "$PR_NUMBER" --repo "${{ github.repository }}" --json headRefName -q .headRefName)
fi
SPACE_URL="https://extralit-dev-pr-${PR_NUMBER}.hf.space"
echo "Pointing preview for branch '$BRANCH' at $SPACE_URL"
npm install -g vercel@latest
# Durable: branch-scoped Preview env var so every build of this branch targets its Space.
# (Branch-scoped add is non-interactive with an explicit branch arg + --value + --yes.)
vercel env rm API_BASE_URL preview "$BRANCH" --token="$VERCEL_TOKEN" --yes 2>/dev/null || true
vercel env add API_BASE_URL preview "$BRANCH" --value "$SPACE_URL" --token="$VERCEL_TOKEN" --yes --force
# Immediate: redeploy the branch's latest preview so the new env applies now.
uid=$(curl -fsSL -H "Authorization: Bearer $VERCEL_TOKEN" \
"https://api.vercel.com/v6/deployments?projectId=${VERCEL_PROJECT_ID}&teamId=${VERCEL_ORG_ID}&target=preview&limit=30" 2>/dev/null \
| jq -r --arg b "$BRANCH" '[.deployments[] | select(.meta.githubCommitRef==$b)][0].uid // empty')
if [[ -n "${uid:-}" ]]; then
vercel redeploy "$uid" --token="$VERCEL_TOKEN" || echo "Redeploy failed (non-fatal); env applies on next build."
else
echo "No existing preview for '$BRANCH' yet; env applies on first/next build."
fi
87 changes: 0 additions & 87 deletions .github/workflows/extralit-frontend.deploy-environment.yml

This file was deleted.

Loading
Loading