Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
be54387
Add design spec for Nuxt 2 to Vue 3 SPA migration
bmaeofu Jul 13, 2026
83be09e
Add implementation plan for Nuxt 2 to Vue 3 SPA migration
bmaeofu Jul 13, 2026
c97abfd
Split migration plan into per-task files for subagent dispatch
bmaeofu Jul 13, 2026
03b7026
chore: migrate from npm to pnpm
bmaeofu Jul 13, 2026
eabc808
Retarget migration to Vuetify 4 and pin vue-router 4
bmaeofu Jul 13, 2026
92aa7b3
Correct Task 1 plan: pnpm 11 reads hoisting config from pnpm-workspac…
bmaeofu Jul 13, 2026
2da0ae4
fix: Task 1 review findings
bmaeofu Jul 13, 2026
8f5407f
refactor: extract Express API from Nuxt serverMiddleware
bmaeofu Jul 13, 2026
3e19a49
feat: upgrade server to Mongoose 9, Express 5, Node 24
bmaeofu Jul 13, 2026
baff6fe
fix: bound Mongoose query buffering, sync plan to the upgraded server…
bmaeofu Jul 13, 2026
2396919
fix: keep the API speaking JSON on malformed requests (Express 5)
bmaeofu Jul 13, 2026
b9eda39
Record Task 2/2b review findings deferred to Tasks 13 and 15
bmaeofu Jul 13, 2026
872fe5c
feat: scaffold Vue 3 + Vite + Vuetify 4 app alongside Nuxt
bmaeofu Jul 13, 2026
89d4701
fix: run the old Nuxt app from a reference worktree, pin TypeScript 5
bmaeofu Jul 13, 2026
9e138d6
feat: add scripts/inspect-page.mjs — headless eyes for the port tasks
bmaeofu Jul 13, 2026
cef9226
feat: port app layout to Vue 3 + Vuetify 4
bmaeofu Jul 13, 2026
1e9849a
fix: correct the Mongo address, recapture baselines with real data
bmaeofu Jul 13, 2026
4baa68c
fix: nav drawer must default open, and needs `exact` (Task 4 review)
bmaeofu Jul 13, 2026
203e70d
Update progress ledger through Task 4
bmaeofu Jul 13, 2026
f5a826d
feat: port settings page and SimpleList to Vue 3 + Vuetify 4
bmaeofu Jul 13, 2026
4ca3e4a
fix: recapture baselines against a fully-working reference app
bmaeofu Jul 13, 2026
2bbf4ab
Relax porting guidance: lean on Vuetify 4 defaults, log deviations, d…
bmaeofu Jul 13, 2026
9a605c9
feat: port Client.vue to Vue 3 + Vuetify 4
bmaeofu Jul 13, 2026
6c312b6
feat: port Overview page to Vue 3 + Vuetify 4
bmaeofu Jul 13, 2026
f0ff08c
Correct the Vuetify conversion table: VRow props kept, add 5 silent t…
bmaeofu Jul 13, 2026
c56a386
feat: port the ten Modules/*Settings components to Vuetify 4
bmaeofu Jul 13, 2026
6e6c2ab
feat: port EncoderConfig, CacheConfig, Property and Module to Vuetify 4
bmaeofu Jul 13, 2026
556a5df
Conversion table: add VBtn/VAlert silent traps and a do-not-fix list
bmaeofu Jul 13, 2026
0574b17
feat: port globalconfig + TextDataTable to Vuetify 4, drop phantom la…
bmaeofu Jul 13, 2026
4dffa95
feat: port jobs page and JobDataTable to Vuetify 4
bmaeofu Jul 13, 2026
35269a5
feat: port client config page to Vuetify 4 — all port tasks complete
bmaeofu Jul 13, 2026
62e1d5c
feat!: remove Nuxt, cut over to the Vue 3 SPA
bmaeofu Jul 13, 2026
242124a
chore: remove the last Nuxt stub directories
bmaeofu Jul 13, 2026
9d56951
refactor: convert components to <script setup lang="ts">
bmaeofu Jul 13, 2026
a9371db
fix: close the last 7 strict-mode errors, all behaviour-neutral
bmaeofu Jul 13, 2026
4cf5b4a
chore: replace Nuxt ESLint config, update README
bmaeofu Jul 13, 2026
e897b69
fix: restore @nuxt/http's request timeout, empty-body and header sema…
bmaeofu Jul 13, 2026
747f0ae
Final ledger: migration complete
bmaeofu Jul 13, 2026
7e12c1c
fix: install the missing Roboto font and map dead typography classes
bmaeofu Jul 13, 2026
eafcc63
fix: pin the client card's status icons to 24px
bmaeofu Jul 13, 2026
1f86e77
fix: icon buttons must be variant="text" — Vuetify 4's `icon` no long…
bmaeofu Jul 13, 2026
b457f9f
fix: pin icon buttons to 44px — Vuetify 4's size="large" is 56px, not…
bmaeofu Jul 13, 2026
9fad632
fix: restore the CSS reset, un-hoist the system bar, unrotate the pro…
bmaeofu Jul 13, 2026
a01fccd
fix: restore Vuetify 2 button typography, stripe size, icon and log-r…
bmaeofu Jul 13, 2026
5e60102
fix: use proper Vuetify 4 idioms for inputs, card headers and list co…
bmaeofu Jul 13, 2026
1dbadca
fix: the striped progress bar — three stacked bugs
bmaeofu Jul 13, 2026
cbb02f7
fix: TextDataTable toolbar — transparent background and horizontal pa…
bmaeofu Jul 13, 2026
07e5158
docs: TOFIX.md — outstanding visual issues and the failure patterns b…
bmaeofu Jul 13, 2026
e19cf7e
fix: give the data-table toolbar a real surface colour and its paddin…
bmaeofu Jul 13, 2026
7936b64
fix: animate regardless of the OS reduce-motion setting, as Vuetify 2…
bmaeofu Jul 13, 2026
2ca8274
fix: resolution rows were 104px tall instead of 72px
bmaeofu Jul 13, 2026
d3d956e
fix: audio format columns collapsed because they had no v-row parent
bmaeofu Jul 13, 2026
90b819d
fix: caret sat below the text in the add-item field
bmaeofu Jul 13, 2026
b7c6e0d
fix: module page sliders, dead space under inputs, card contrast, but…
bmaeofu Jul 13, 2026
1433837
chore: drop the throwaway measurement scripts
bmaeofu Jul 13, 2026
89b9f36
fix: expanded client panel was 286px tall instead of 204px; retone th…
bmaeofu Jul 13, 2026
755ab62
docs: bring TOFIX in line with what is actually fixed
bmaeofu Jul 13, 2026
b601401
docs: rewrite the "X, not Y" comments as plain statements
bmaeofu Jul 13, 2026
210b2a2
fix: log margins, jobs list density, encoder tab, checkbox colour, al…
bmaeofu Jul 13, 2026
5f4c501
fix: checkboxes sat 20px right of the content they line up under
bmaeofu Jul 13, 2026
89dd879
style: give the log rows a little vertical padding back
bmaeofu Jul 13, 2026
40716a3
fix: two-line list rows, and disabled buttons no longer render as ena…
bmaeofu Jul 13, 2026
78293bb
fix: encoder tab — tag field misaligned, buttons off-centre, select s…
bmaeofu Jul 13, 2026
793452d
fix: module setting fields were stretched by the help button; pane co…
bmaeofu Jul 13, 2026
26c033e
fix: card title padding, module SETTINGS gap, slider bottom margin
bmaeofu Jul 13, 2026
ee47c10
docs: TOFIX reflects the finished state
bmaeofu Jul 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
node_modules
npm-debug*
.nuxt
dist
53 changes: 0 additions & 53 deletions .eslintrc.js

This file was deleted.

47 changes: 47 additions & 0 deletions .superpowers/sdd/progress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Migration progress ledger — COMPLETE

All 15 tasks done. Branch: migration/vue3 (38 commits off master @ 575ee82).

FINAL STATE, verified through the PRODUCTION path (pnpm build + node server/index.js):
lint PASS | typecheck PASS (strict) | build PASS
All 5 routes load with 0 app console errors and 0 warnings.
SPA fallback survives a hard refresh of /jobs. /api/clients returns the 5 real clients.

Stack: Vue 3.5.39 / Vuetify 4.1.4 / Vite 8.1.4 / vue-router 4.6.4 (unplugin-vue-router),
<script setup lang="ts"> throughout, TS strict. Express 5.2.1 + Mongoose 9.7.4 on Node 24.
One container, one port: Express serves dist/ AND /api.

ENVIRONMENT:
MongoDB mongodb://192.168.178.75:27017/Avior (the committed 10.11.194.75 was stale)
Daemons VDR-U/-1/-2 at 192.168.178.61:10000-10002 (live). Phoenix + VAVA genuinely offline.
Reference worktree: ../avior-nuxt-reference @ baff6fe — the old Nuxt app, for comparison.

STILL UNVERIFIED — needs the user:
- NO DOCKER BUILD HAS EVER RUN. Docker is not installed here; the user declared it out of
scope. The Dockerfile is rewritten as a multi-stage build but is UNTESTED, including
node:24-alpine and the VITE_COMMIT_SHA build arg (so the footer's commit hash is unproven).
- Pause / Resume / Shutdown on a live client were never clicked (real PUTs; shutdown is
irreversible). Someone should click Pause once on a real client.
- Client.vue's FileWalker / Mover render paths were never exercised (no daemon was in
those states).

PRE-EXISTING BUGS FOUND, DELIBERATELY NOT FIXED (report, don't smuggle in fixes):
- jobs.vue: selectedJobs.length means the Delete button never shows a count.
- jobs.vue: reassignJobs()'s `idx % 5` batching is INERT — idx is a client-ID string, so
both branches are always false, the batch never flushes, errorCount is always 0.
- Client.vue: a `:v-show=` binding that has never done anything; a duplicated
showProcessedLog=false; the author's own `//todo: BUGGED!!!!` dead branch.
- Client.vue emits offlineClient as an OBJECT from onclose but a bare STRING from onerror;
index.vue's handler would throw on the string. Unreachable today.
- Age/ErrorReplace/ErrorSkip/MaxSize Settings: a `watch` on `selectedFormat`, which does not
exist in their data or props — so they have NEVER emitted `newdata`. SizeApproxSettings has
the same problem via a missing `deep: true`. It does not matter in practice: settingsInternal
is the SAME object reference as config.Modules.X.Settings, so v-model mutates the config in
place. Proved by changing AgeModule MaxAge 5 -> 99 and confirming the export contained 99.
- config.vue: color="gray darken-3" is an invalid palette key ("grey" is real) — it was already
a no-op typo in Vuetify 2, so hyphenating it would ADD colour the page never had.
- v-col xs="6": dead in BOTH versions. Vuetify 2's VCol breakpoints were ['sm','md','lg','xl'].

ACCEPTED DEVIATIONS (Material Design 3):
Typography, elevation (25 levels -> 6), button casing, spacing, and the four dropped theme
colours (accent/info/warning/error/success now use Vuetify 4 defaults).
40 changes: 30 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
FROM node:20.1.0-alpine
FROM node:24-alpine AS build

# Vite inlines import.meta.env at build time, so the commit SHA has to be
# present in the build stage — setting it at runtime would have no effect.
ARG COMMIT=""
ENV VITE_COMMIT_SHA=${COMMIT}

WORKDIR /app
RUN corepack enable && corepack prepare pnpm@11.12.0 --activate

COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile

COPY . .
RUN pnpm build

FROM node:24-alpine AS runtime

ARG COMMIT=""
LABEL commit=${COMMIT}

RUN mkdir -p /app
WORKDIR /app
RUN corepack enable && corepack prepare pnpm@11.12.0 --activate

# Install software
COPY . /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile --prod

ENV NUXT_ENV_CURRENT_GIT_SHA=${COMMIT}
COPY server ./server
COPY --from=build /app/dist ./dist

RUN npm install
RUN npm run build
# NODE_ENV=production is load-bearing: without it Express uses its development
# error handler, which puts stack traces with absolute filesystem paths into
# HTTP response bodies.
ENV NODE_ENV=production
ENV PORT=10009
ENV MONGO_URL=mongodb://192.168.178.75:27017/Avior
EXPOSE 10009
ENV NUXT_HOST=0.0.0.0
ENV NUXT_PORT=10009
CMD [ "npm", "start" ]

CMD ["node", "server/index.js"]
94 changes: 74 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# Avior Nuxt frontend
# Avior frontend

Frontend for displaying data polled from the avior-go project.

## What is it?
Avior Nuxt features full configuration and monitoring for an avior-go instance.

Avior features full configuration and monitoring for an avior-go instance.
For documentation on avior-go, please confer the
[avior-go repository](https://www.github.com/Spiritreader/avior-go)

## Registering Clients

Go to frontend settings and add a client name and the address of the avior-go instance.
avior-go is only designed to work with a private network, as there is no authentication needed to update its configuration and start/stop it.
An instance is reachable via `http://network-ip:10000`.
Expand All @@ -24,9 +27,9 @@ You can start, pause and stop clients and view its log files
### Client settings
You can configure all available options there. Documentation is available in avior-go. These settings are individual to each client

### Global settings:
### Global settings:

You can add and remove clients that are eligible for receiving jobs here.
You can add and remove clients that are eligible for receiving jobs here.
**Clients**
- Priority determines which client will be filled wit jobs first, up to the maximum. After that, the next client will be chosen for new jobs
- Start and end time configure during which times a client can *encode files*. It does not influence the assignment rules
Expand All @@ -36,34 +39,85 @@ You can add and remove clients that are eligible for receiving jobs here.

This is a global configuration instance for the LogMatch module and the trimming feature of avior-go.

## Stack

- [Vue 3](https://vuejs.org/) + TypeScript, `<script setup>` throughout
- [Vuetify 4](https://vuetifyjs.com/) for UI components (Material Design 3)
- [Vite](https://vitejs.dev/) for dev server and bundling
- [vue-router](https://router.vuejs.org/), file-based via `unplugin-vue-router` (routes are just files under `src/pages`)
- [Express 5](https://expressjs.com/) + [Mongoose 9](https://mongoosejs.com/) for the API and MongoDB access

## Architecture

## Installation
This is a single-page app with no server-side rendering. Express serves two
things on the same port: the built static SPA (`dist/`) and the `/api` routes.

### Building manually
There are two independent data paths:
- **Browser → `/api` → Express → MongoDB.** This is the client registry
(which avior-go instances exist, their names/addresses/priorities/etc). App
code always calls `/api/...` with a relative path — no base URL is
configured anywhere, in dev or in production.
- **Browser → avior-go daemons, directly.** Once the client registry gives
the browser a daemon's LAN address, the browser talks to that daemon
directly (e.g. `http://network-ip:10000`) to start/stop jobs, stream logs,
etc. Express is never in this path, and nothing proxies it.

## Development

```bash
$ npm install
$ npm run dev
pnpm install

pnpm dev:api # Express API on :10009
pnpm dev # Vite dev server, normally :5173
```

Vite proxies `/api/*` requests to `http://localhost:10009` in dev, so the
app-origin `/api` calls work the same way they do in production. If port
5173 is already taken, Vite will pick the next free port and print which one
it used.

$ npm run build
$ npm run start
## Production

```bash
pnpm build # builds the SPA into dist/
node server/index.js # or: pnpm start
```

For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org).
Express serves the built `dist/` and `/api` together on a single `PORT`
(default `10009`).

## Configuration

Environment variables:
- `MONGO_URL` — MongoDB connection string. Defaults to
`mongodb://192.168.178.75:27017/Avior`. There is no `config.json` file or
volume mount for this anymore — set the environment variable instead.
- `PORT` — port Express listens on. Defaults to `10009`.

`VITE_COMMIT_SHA` is inlined into the app **at build time** by Vite (it shows
up in the footer). Setting it as a runtime environment variable on an
already-built `dist/` has no effect — it must be set when `pnpm build` runs.

Modify the config.json file and change the URL to your mongodb instance.
## Requirements

### Docker
- Node >= 20.19 (required by Mongoose 9)
- [pnpm](https://pnpm.io/) — this project uses pnpm exclusively; do not use
`npm install` or `yarn`.

This project is also available on dockerhub. Make sure to map a database configuration by creating a `config.json` like so:
```json
{
"url": "mongodb://your-url"
}
## Linting

```bash
pnpm lint
```

Then run the docker container:
ESLint flat config (`eslint.config.js`) covering `src/**/*.{ts,vue}` (Vue 3 +
TypeScript), `server/**/*.js` (CommonJS Node), and `scripts/*.mjs` (Node ESM).

## Docker

This project is also available on dockerhub. Pass your database URL as an
environment variable:

```docker
docker run --publish=10009:10009--volume=/<path-to-config>/config.json:app/api/config.json spiritreader/avior-nuxt
docker run --publish=10009:10009 --env MONGO_URL=mongodb://your-url/Avior spiritreader/avior-nuxt
```
91 changes: 0 additions & 91 deletions api/api.js

This file was deleted.

3 changes: 0 additions & 3 deletions api/config.json

This file was deleted.

7 changes: 0 additions & 7 deletions assets/README.md

This file was deleted.

4 changes: 0 additions & 4 deletions assets/variables.scss

This file was deleted.

Loading
Loading