Files
portal/docs/adr/ADR-001-frontend-stack-vue-vuetify.md
T
Дмитрий c09b9ab7fd feat(adr): bootstrap docs/adr — ADR-000/001/002 + adr-kit guide (Task 4)
Three seed ADRs to the adr-kit 7-section template: ADR-000 (process + docs/adr vs registry vs docs/architecture boundary), ADR-001 (Vue 3 + Vuetify 3 stack, with an Enforcement block forbidding Inertia/React/framer-motion/Tailwind imports), ADR-002 (PostgreSQL RLS multi-tenancy, documentation-only).

adr-lint: 3/3 PASS strictly (completeness + consistency). markdownlint 0 errors. .claude/adr-kit-guide.md vendored from the plugin (replaces what adr-kit:init would write to CLAUDE.md — AK2). cspell glossary += ADR/rvdbreemen/secondsky/NNN/MMM. init/install-hooks NOT run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 04:54:43 +03:00

3.1 KiB

ADR-001 Build the frontend on Vue 3 and Vuetify 3

Status

Accepted, 2026-05-17.

Context

Лидерра's user interface is built with Vue 3 and the Vuetify 3 component library. The project explicitly excludes Tailwind, Inertia, Livewire, Filament, Flux UI, Nova, Folio, Volt, and Wayfinder (CLAUDE.md §2 and §5 п.2). framer-motion cannot be used at all — it is a React-only library and declares a react + react-dom peer dependency, so it crashes at runtime in a Vue application.

This decision predates the ADR process; it is recorded retroactively as the first technical ADR (see ADR-000) and given a machine-enforceable rule so the stack boundary cannot be crossed silently in a future change.

Decision

All user-interface code is authored as Vue 3 single-file components rendered with Vuetify 3. No alternative UI framework, and no React-coupled runtime library, may be imported anywhere under app/resources/js/.

Alternatives Considered

  • Inertia.js with a Vue adapter. Rejected: Inertia couples routing and page rendering to the Laravel backend; the project specification calls for a plain Vue SPA with client-side routing (vue-router), already in place.
  • Tailwind CSS for styling alongside Vuetify. Rejected: Vuetify 3 already provides the design system and theme tokens; a second styling system would fragment the visual language and enlarge the bundle for no functional gain.

Consequences

Positive:

  • Laravel Boost (via Roster auto-detection) serves only stack-relevant guidelines, because no excluded framework appears in composer.lock or package.json.
  • A single component library keeps the interface visually consistent and keeps contributor onboarding focused on one toolset.

Negative:

  • The project is committed to Vuetify's component set and theming model; a Vuetify major-version upgrade is coordinated work rather than a drop-in.
  • A genuinely needed React-only library has no path in; such a need would require a new superseding ADR.
  • ADR-000 — defines the ADR process under which this record was written.

References

  • CLAUDE.md §2 (stack) and §5 п.2 (excluded frameworks).
  • liderra_v8_handoff/docs/DEVELOPER_HANDOFF.md — Vuetify component handoff.
  • docs/Tooling_v8_3.md §9.2 — the framer-motion technical-block rationale.

Enforcement

{
  "forbid_import": [
    {
      "pattern": "@inertiajs/",
      "path_glob": "app/resources/js/**",
      "message": "Inertia is out of stack — frontend is a Vue 3 + Vuetify 3 SPA (ADR-001)."
    },
    {
      "pattern": "from\\s+['\"]react(-dom)?['\"]",
      "path_glob": "app/resources/js/**",
      "message": "React is not used — the frontend is Vue 3 (ADR-001)."
    },
    {
      "pattern": "['\"]framer-motion['\"]",
      "path_glob": "app/resources/js/**",
      "message": "framer-motion: React-only peer dependency, crashes in Vue (ADR-001)."
    },
    {
      "pattern": "['\"]tailwindcss['\"]",
      "path_glob": "app/resources/js/**",
      "message": "Tailwind is out of stack — Vuetify 3 is the design system (ADR-001)."
    }
  ],
  "require_pattern": [],
  "llm_judge": false
}