Newer
Older
smart-home-server / webclient-vue / docs / scaffold.md
@Eugene Sukhodolskiy Eugene Sukhodolskiy 7 hours ago 5 KB Document Vue client migration plan

Vue Client Scaffold Specification

  • Vue 3
  • Vite
  • Vue Router
  • Pinia
  • JavaScript
  • gnexus-ui-kit for UI primitives and design system

Project decision: do not use TypeScript. Reliability should come from a small API normalization layer, explicit mappers, and runtime response validation where backend shapes are uncertain.

Directory Layout

webclient-vue/
  docs/
  public/
  src/
    app/
      App.vue
      main.js
      providers.js
    api/
      client.js
      errors.js
      http.js
      mappers.js
      modules/
        areas.js
        devices.js
        scripts.js
      schemas/
        areas.js
        common.js
        devices.js
        scripts.js
    assets/
    components/
      app/
      data/
      feedback/
      forms/
      layout/
      overlays/
    features/
      areas/
      devices/
      scripts/
    router/
      index.js
      routes.js
    stores/
      areas.js
      devices.js
      favorites.js
      scripts.js
      ui.js
    styles/
      main.scss
      tokens.scss
    utils/
      concurrency.js
      dates.js
      format.js
      storage.js
  index.html
  package.json
  vite.config.js

Route Mode

Use hash mode first.

Reason:

  • Current client uses #!/....
  • Hash mode does not require web server rewrite configuration.
  • It reduces deployment risk while the old and new clients coexist.

Target route mapping:

Route Component
/ Redirect to /areas/favorites.
/devices features/devices/pages/DevicesListPage.vue
/devices/scanning features/devices/pages/DevicesScanningPage.vue
/scripts/actions features/scripts/pages/ScriptActionsPage.vue
/scripts/regular features/scripts/pages/ScriptRegularPage.vue
/scripts/scopes features/scripts/pages/ScriptScopesPage.vue
/areas/favorites features/areas/pages/AreaFavoritesPage.vue
/areas/tree features/areas/pages/AreaTreePage.vue
fallback features/system/NotFoundPage.vue

Future option:

  • Switch to history mode after nginx/apache routing is explicitly configured.

Environment Variables

Use Vite environment variables:

VITE_API_BASE_URL=http://smart-home-serv.local
VITE_API_PROXY_PATH=/proxy.php
VITE_API_TIMEOUT_MS=10000

For local development with Vite dev server:

VITE_API_BASE_URL=http://localhost:5173
VITE_API_PROXY_PATH=/proxy.php

If proxy.php remains in the old webclient/ directory during development, either:

  • copy/adapt it into webclient-vue/public/proxy.php for PHP-served deployment;
  • or configure Vite dev proxy and call backend directly in dev.

API Client Requirements

The API client should be promise-based:

const result = await devicesApi.list();

if (!result.ok) {
  // normalized error
  return;
}

const devices = result.data.devices;

No UI component should parse raw backend envelopes directly.

Layering:

  • http.js - low-level fetch, timeout, abort, proxy path wrapping.
  • client.js - common request helpers and response normalization.
  • modules/*.js - domain-specific methods.
  • mappers.js - response field unification currently done by Helper.
  • schemas/*.js - lightweight runtime validators for uncertain response shapes.

UI Kit Integration Contract

The gnexus-ui-kit repository was not available from this environment, so exact package exports are intentionally not assumed in this spec.

Acceptable integration options, in preferred order:

  1. Install as package/git dependency if it exposes Vue components or CSS assets.
  2. Use a git dependency pinned by commit/tag in the lockfile.
  3. Add as git submodule only if package/git dependency is not viable.
  4. Avoid copying a versioned release into the project because the UI-kit updates often and should remain a live design dependency.

Whichever option is chosen, create one local compatibility layer:

src/components/ui/
  UiButton.vue
  UiBadge.vue
  UiCard.vue
  UiDialog.vue
  UiInput.vue
  UiSelect.vue
  UiTable.vue
  UiToast.vue

Application code should prefer local compatibility components for app-specific behavior, but these components must remain thin and track UI-kit public APIs. The goal is full UI-kit update compatibility, not a forked component library.

Initial Dependencies

Expected package dependencies:

{
  "dependencies": {
    "@vitejs/plugin-vue": "latest",
    "vite": "latest",
    "vue": "latest",
    "vue-router": "latest",
    "pinia": "latest"
  },
  "devDependencies": {
  }
}

Add exact gnexus-ui-kit dependency only after its packaging format is known.

Build Scripts

Recommended scripts:

{
  "scripts": {
    "dev": "vite --host 0.0.0.0",
    "build": "vite build",
    "preview": "vite preview --host 0.0.0.0"
  }
}

First Milestone Scaffold

Minimum files for the first working milestone:

  • src/app/main.js
  • src/app/App.vue
  • src/router/index.js
  • src/router/routes.js
  • src/api/client.js
  • src/api/modules/areas.js
  • src/stores/areas.js
  • src/features/areas/pages/AreaFavoritesPage.vue
  • src/components/layout/AppShell.vue
  • src/components/feedback/AppErrorState.vue
  • src/components/feedback/AppLoadingState.vue

The first milestone is complete when /areas/favorites can call GET /api/v1/areas/list, render favorite areas from localStorage, and show an empty state without using any code from the old client.