Vue 3 + Vuetify 4 stack from Devkit. Standalone frontend or fullstack with Node/Swift. Cloned into downstream projects, kept up-to-date via upstream merges.
- Source of truth:
README.md+package.jsonscripts .claude/contains embedded settings and skills- Read
ERRORS.mdbefore proposing changes — append new mistakes as[YYYY-MM-DD] <scope>: <wrong> -> <right>
- Layered: UI → Store → API. Each layer references only the one below.
- Modules are independent — no cross-module imports without justification.
- Shared code in
src/modules/coreonly with justification. - Modularity, UI rules, and definition of done → see
/feature
- Ability helper:
src/lib/helpers/ability.jsexports reactiveability+updateAbilities(rules). - Plugin:
@casl/vueabilitiesPluginregistered inmain.js—$can()/$cannot()in templates. - Route guards:
meta.action+meta.subject(nevermeta.roles). Guard checksability.can()withisLoggedInfallback. - Navigation:
core.store.jsrefreshNav()uses same ability check. Sidenav items are sorted bymeta.orderascending (lower first), thenmeta.actiondesc as tiebreaker. Use increments of 10 (10,20, ...) so downstream projects can slot routes between stack ones. Routes withoutmeta.orderfall to the end.meta.position: 'bottom'moves an item to the bottom section;meta.orderthen controls position within that section. - Auth flow:
updateAbilities(res.data.abilities)on signin/token,updateAbilities([])on signout. - Organizations:
src/modules/organizations/— CRUD + members + switching. Switcher auto-hides when disabled or single-org. - Signup org step: Controlled by
serverConfig.organizations.enabled. Three-step: form → setup → app. - Subjects: PascalCase singular nouns matching backend models (
Task,Organization). - Actions:
read,create,update,delete,manage(= all).
| Script | Command | Description |
|---|---|---|
npm run dev |
vite |
Start dev server with HMR |
npm start |
npm run dev |
Alias for dev |
npm test |
vitest run |
Unit tests only (no infra needed) |
npm run test:all |
vitest run + Playwright |
All tests (unit + E2E, needs Node + MongoDB) |
npm run test:unit |
vitest run |
Same as npm test |
npm run test:watch |
vitest |
Unit tests in watch mode |
npm run test:e2e |
npx playwright test |
E2E tests only (needs Node + MongoDB) |
- Every new feature needs unit tests (store + component if applicable)
- E2E only for critical product flows (auth, org onboarding, invite/join); requires Node + Vue + MongoDB running
- Docker (mongo + node-api):
docker compose -f docker-compose.test.yml up -d
- Code knowledge graph (optional): install Graphify via
uv tool install graphifyy==0.5.0(Python tool, system-wide). Rungraphify update .to generategraph.json+ report undergraphify-out/. Pin v0.5.0 — Graphify ships fast (5 releases / 48h around 22-23 April 2026), expect breaking changes on minor bumps.
- Config layering: Module configs (
*.development.config.js) load first, then global overrides ({env}.config.js). Override in global config, not module configs, to avoid stack merge conflicts. - Post-login redirect: Set
sign.routein global config override. Used by signin, signup, and org flows. Default:/tasks. - Custom home page: Replace
home.router.jswith a project-specific router that maps/to a custom view. Setdisplay: falsein route meta to hide from sidenav.
src/main.jsis strictly stack-managed. Downstream projects MUST NOT add side-effect imports here — global CSS, analytics config, sentry tags, plugin bootstrap, etc. — because/update-stack --theirswill silently wipe them on the next sync.- Downstream-only side effects belong in a project-owned entry:
- A project view that always mounts (e.g.
src/modules/{project}/views/{project}.view.vue). - A project module index imported from a downstream-only file.
- A project-scoped barrel imported from a downstream-only
App.vueslot or layout.
- A project view that always mounts (e.g.
- If a downstream project has no such entry, the right escape hatch is to create one (issue pierreb-devkit/Vue#4093 — option C is reserved for future migration if option A friction grows).
- This rule applies retroactively: when
/update-stackreportssrc/main.jsas a conflict, the downstream side of the conflict must be moved to a project-only entry, never re-applied as a--ourspatch.
- Never commit secrets (
.env*, keys, tokens) - No cross-module coupling without justification
- Keep changes minimal and merge-friendly for downstream
- Every function: JSDoc header (
@param,@returns) - PRs: always use
/pull-request— never open manually - After user correction, evaluate if the pattern belongs in ERRORS.md
- No optional module names in core module code. Core modules (
core,auth,users,home,app) must not reference optional module names anywhere in their code — not in imports, not in string maps, not in route names, not in store references, not in config keys. Optional modules self-register their own behaviour and core modules read from config or a registry.
- Never push directly to master/main. Always create a branch, push, create a PR, wait for CI green + review, then merge.
- Never lower coverage thresholds in
vitest.config.js. If coverage drops after adding code, write tests for the new project modules to bring it back above thresholds. - Audit existing modules before implementing. Before creating new storage, utilities, or components, check
src/modules/for existing solutions. - Always run
/verifyafter any code change before declaring done. CI must be green.
| Skill | Description |
|---|---|
/feature |
Scope analysis → implement → DOD (includes /create-module if needed) |
/verify |
Lint + tests + build + UX audit |
/ui |
Design system, Vuetify 4 patterns, visual verification |
/naming |
File and folder naming conventions |
/pull-request |
Full PR lifecycle: draft → CI → monitor → iterate |
/update-stack |
Merge upstream stack updates |
/create-module |
Scaffold new module from tasks template |
Historical: older references to
weareopensource/Vueor "WeAreOpenSource" are upstream legacy — ignore.