Single frontend shared between:
- the web version (Nuxt 4),
- the desktop version (Tauri, Windows + macOS) — required for Vinted features (publishing + wardrobe sync).
| Route | Access | Purpose |
|---|---|---|
/ |
Public | Marketing landing (Vinted + eBay + wardrobe sync pitch). |
/request |
Public | Submit an access request (POST /access-requests). |
/login |
Public | JWT sign-in (rejects pending / rejected / banned). |
/setup-password/[token] |
Public | One-time password setup from an admin-issued link. |
/dashboard |
Auth | KPIs, revenue timeline, channel split (Vinted vs eBay). |
/articles, /articles/** |
Auth | Inventory CRUD, scan flow, batch publish. |
/settings |
Auth | Profile, notifications, security. |
/settings/marketplaces |
Auth | Toggle Vinted/eBay, link Vinted account (VintedAccountCard), eBay OAuth + onboarding. |
/users |
Admin | User list (avatar via PokeAPI, status, margin, Vinted/eBay flags) + approve / reject / ban / generate password link. |
/downloads |
Auth | Download the Tauri desktop bundle (Windows / macOS). |
The admin is the user seeded from the API (SEED_USER_EMAIL). The sidebar conditionally shows the Utilisateurs link when is_admin is true (useAuth().user). Admin-only pages are guarded by app/middleware/admin.ts.
- Web: Vinted publishing & wardrobe sync are disabled — the UI points users to
/downloads. - Desktop (Tauri): Vinted features call the local Python worker on
127.0.0.1:18766(configurable viaNUXT_PUBLIC_VINTED_LOCAL_BASE). Composables:useVintedPublishStream,useVintedBatchStream,useWardrobeLocalSync,useWardrobeSyncStream. The runtime is detected through the Tauri WebView. Intauri:dev, the app uses127.0.0.1:18767by default to avoid conflicts with an installed desktop app.- The desktop installer bundles the worker as a PyInstaller sidecar (
bundle.externalBin = ["binaries/goupix-vinted-worker"]). End users do not need a system-wide Python install. - The worker is spawned by
web/src-tauri/src/lib.rson app startup and killed on exit. In dev (tauri:dev),lib.rsfalls back topython desktop_vinted_server.pyfrom the localapi/folder so you can iterate without rebuilding the sidecar (setGOUPIX_PYTHONto override the interpreter). - Worker logs are written to
%LOCALAPPDATA%\GoupixDex\logs\vinted-worker.log(Windows) /~/Library/Logs/GoupixDex/vinted-worker.log(macOS) so they survive--noconsolePyInstaller mode.
- The desktop installer bundles the worker as a PyInstaller sidecar (
The Vinted worker drives a Chrome install via nodriver. At app startup the Tauri command check_browser_availability (Rust, see lib.rs) probes the standard install paths and:
- if Chrome is found → it is passed to the worker via
VINTED_CHROME_EXECUTABLE, - otherwise if Edge is found (always present on Win 10/11) → Edge is used as a fallback,
- otherwise the frontend mounts
BrowserMissingModal.vue(composable:useBrowserAvailability) blocking the UI until the user installs Chrome.
- Node.js 22+
- npm 10+
- For local Tauri: Rust toolchain installed
npm installExample in .env.example:
NUXT_PUBLIC_SITE_URL: canonical site URL (used for SEO + sitemap).NUXT_PUBLIC_API_BASE: remote GoupixDex API URL (prod or local).NUXT_PUBLIC_VINTED_LOCAL_BASE: local desktop worker URL (defaulthttp://127.0.0.1:18766, Tauri only).NUXT_PUBLIC_GITHUB_REPO:owner/reposlug for the/downloadspage.NUXT_PUBLIC_DESKTOP_RELEASE_CHANNEL:latestor a GitHub Release tag.NUXT_PUBLIC_GITHUB_API_BASE: GitHub API base (defaulthttps://api.github.com).
npm run devnpm run buildnpm run tauri:devThe script first runs vinted-worker:stub which writes an empty placeholder under web/src-tauri/binaries/goupix-vinted-worker-<host-triple>(.exe) so Tauri's bundle.externalBin validation passes. In cfg(debug_assertions) builds, lib.rs ignores the placeholder and spawns python desktop_vinted_server.py from api/ instead. The folder web/src-tauri/binaries/ is .gitignored.
To avoid collisions with a production desktop app running at the same time, tauri:dev defaults to:
- frontend local worker base:
http://127.0.0.1:18767 - worker listening port:
18767 - nodriver profile directory (outside the repo): on Windows
%LOCALAPPDATA%\GoupixDex\vinted-nodriver-profile-dev(seedev_vinted_nodriver_user_data_dirinweb/src-tauri/src/lib.rs)
If you see a Cargo error like:
this version of Cargo is older than the 2024 edition
update Rust/Cargo (Windows/macOS/Linux):
rustup self update
rustup update stable
rustup default stableThen restart your terminal and check:
cargo -V
rustc -VOn Windows, if the version does not change, ensure cargo points to ~/.cargo/bin:
where cargo
where rustcnpm run tauri:buildThe command first builds the Nuxt frontend in desktop mode (NUXT_DESKTOP_BUILD=1), then bundles the app with Tauri.
The desktop bundle ships a Python sidecar built from api/desktop_vinted_server.py via PyInstaller (api/desktop_vinted_server.spec) — see the CI/CD section below for the per-OS build steps.
deploy-web.yml— web build and deploy (Nitro + PM2).deploy-api.yml— backend build / VPS deployment (systemd + Xvfb for Vinted).desktop-release.yml— Windows/macOS desktop release builds (Windows binary without console) and a stable GitHub Release per version (v0.1.x, not prerelease). For each OS the workflow first sets up Python 3.11, installsapi/requirements.txt+ PyInstaller, and runspyinstaller desktop_vinted_server.specto producegoupix-vinted-worker-<rust-triple>(.exe)underweb/src-tauri/binaries/before invokingtauri-action. Both macOS targets (x86_64-apple-darwinandaarch64-apple-darwin) run onmacos-latest(Apple Silicon); the Intel job usesactions/setup-pythonwitharchitecture: x64so PyInstaller runs under Rosetta 2 (preinstalled on GitHub macOS runners) and produces a native Intel sidecar.
From the web/ folder, generate the keypair:
npx @tauri-apps/cli signer generate -w goupixdex.keyRead the private key (to copy into a GitHub secret):
cat goupixdex.keyIf you are using PowerShell:
Get-Content .\goupixdex.key -RawThen configure these 3 secrets in GitHub > Settings > Secrets and variables > Actions:
TAURI_SIGNING_PRIVATE_KEY- Value: full contents of
goupixdex.key(Tauri/minisign format, as-is, including line breaks). - Note: it is normal not to have
BEGIN PRIVATE KEY/END PRIVATE KEY.
- Value: full contents of
TAURI_SIGNING_PRIVATE_KEY_PASSWORD- Value: the password entered during
signer generate.
- Value: the password entered during
TAURI_UPDATER_PUBKEY- Value: the public key generated by the command (
signer generate) or the contents ofgoupixdex.key.pub.
- Value: the public key generated by the command (
Important:
- Never commit
goupixdex.keyorgoupixdex.key.pub. - Keep
goupixdex.keyin a secure location (secret manager, vault, etc.).