Appearance
Decision Matrix
Use this matrix after consulting guides 01–12 to settle common architectural, authoring, and workflow choices. Each row highlights the default path, when to escalate or deviate, and where to read the full rationale.
How to Use It
- Start with the Default Choice column; it encodes the baseline that keeps the codebase cohesive.
- If constraints don’t fit the default, review When to Consider Another Option before diverging.
- Follow the References links for deeper context, samples, and edge-case guidance.
| Scenario | Default Choice | When to Consider Another Option | References |
|---|---|---|---|
| Naming a new file, symbol, or boolean flag | Apply PascalCase to components/types, camelCase to everything else, and positive-statement booleans (e.g., isOpen, canSubmit). | Only deviate when mirroring upstream APIs (DTOs keep backend snake_case) or when team-wide conventions for shared packages already exist. | 01.Naming |
| Placing new modules or assets | Follow the prescribed src/ layout (features under pages/<Module>/, shared items in components/, services/, queries/, etc.) and keep modules self-contained. | If a feature spans multiple products or repos, document the alternative structure in README.md and link back here so others understand the divergence. | 02.Folder-Structure |
| Building a UI feature | Use SFCs with <script setup lang="ts">, keep the logic order (imports → props → emits → composables → state → actions → lifecycle), and push shared logic into composables/services. | Reach for renderless helpers or Vapor mode only after profiling shows the need; prototype in a throwaway branch before committing to complex patterns. | 03.Components |
| Reusing stateful logic | Publish a use<Name> composable in src/composables/ with a stable return surface and matching consumer variable naming. | If the logic is page-specific or drives orchestrated workflows, colocate it under pages/<Module>/composables/ to avoid bloating the shared API. | 04.Composables |
| Fetching server data | Define query/mutation hooks in src/queries/<domain>.query.ts with key factories and named exports (useEntityQuery, useEntityMutation). | Inline fetches are acceptable only in one-off prototypes; convert them to queries before merging to keep caching/invalidation consistent. | 05.Queries-Mutations |
| Managing client-side state | Prefer Pinia setup stores per domain (use<Cart>Store) for UI flags, drafts, persisted preferences, and cross-component coordination. | If the data is authoritative on the server or requires cache invalidation, treat it as server state and move to the Query/Mutation layer instead. | 06.State-Management |
| Modeling types & dealing with unknowns | Keep DTOs and domain models separate, prefer unions/as const over enums, avoid any, and colocate shared helpers in src/types/. | Use any or non-null assertions only with inline justification when a dependency lacks typings and narrowing is impossible. | 07.TypeScript |
| Designing routes | Centralize route definitions in src/router/, group child routes per feature, and gate access with navigation guards or route meta where needed. | Introduce multiple routers or dynamic module injection only if you are bootstrapping micro-frontends; document the bootstrapping flow before rollout. | 08.Routing |
| Deciding how to test a change | Cover units and integration flows with Vitest + Testing Library; use Vue Test Utils only for low-level component mechanics that Testing Library cannot express; use Playwright for end-to-end flows. | Use Cypress only as a legacy or project-specific alternative when an existing project standard requires it. Skip automated tests only for disposable spikes; note the gap with a TODO(team) and tracker link so coverage lands before release. | 09.Testing |
| Enforcing style & quality gates | Run ESLint flat config and Prettier in CI and pre-commit, follow the documented rule overrides, and keep autofixes enabled. | When tooling blocks progress (e.g., upstream bug), gate the exception behind eslint-disable-next-line with context and open an issue to revert later. | 10.Lint-Format |
| Preparing commits & pull requests | Use Conventional Commits for PR titles and squash-merge every PR into a single commit on main. Keep PRs small and focused; split unrelated work into separate PRs. Include a succinct description with checklist, testing notes, and linked issues. | Keep individual branch commits for authoring or review when each commit is independently meaningful, deployable, and passes CI on its own, but still squash-merge the PR so only one commit reaches main. This is rare; the default remains squash merging. | 11.Commits-PRs |
| Documenting APIs, slots, and work-in-progress | Add JSDoc to all public surfaces, props/emits/slots, and use structured TODO(owner): / FIXME(owner): comments with tracker refs. | Skip comments only when the code is self-evident and private; otherwise, leaving intent undocumented slows reviews and future maintenance. | 12.Doc-Comments |
Escalation Checklist
- If a decision impacts multiple teams, raise it in the architecture channel and link the resolution back here.
- Record approved deviations inside the affected guide so the matrix stays authoritative.
- Re-review this matrix whenever a convention document changes scope or introduces a new default.