26 KiB
Active Context — Strava Frontend
Task State
- task_id: TASK-DEPS-UPDATE-W2c
- status: success
- parent_task: TASK-DEPS-UPDATE (safe dependency update; Storybook 8 EXCLUDED as high-risk)
- summary: W2b DONE + Architect-verified (TS 5.8.3, vue-tsc 2.2.12). Now W2c: vite 4→5 + @vitejs/plugin-vue 4→5.
W2b acceptance criteria
vue-tscresolved to 2.x andtypescriptto 5.8.x in yarn.lock; NO other package moved to a new majoryarn lint— 0 errors;yarn build— green (vue-tsc 2 type-check 0 errors, bundle built)- Minimal type-only fixes in
src/allowed only if required by the stricter checker; each documented with justification - Memory Bank: status
success+ Success Report (old/new versions, full list of src/ fixes with justification)
Wave plan (each wave = one atomic task, verified independently)
- W0a (TASK-DEPS-UPDATE-W0a, success): Fix everything that hard-blocks
yarn build:LineWithLineChart.ts(41)TS2532 "Object is possibly 'undefined'" (labels can be undefined) — fix via non-null assertion or guarded length.- SFC parsing errors:
src/pages/workouts/components/WorkoutItem.vue:260(Unexpected token {) andWorkoutListItem.vue:60('interface' is reserved). Root-cause candidates: TS syntax in a plain<script>(nolang="ts") or malformed block — inspect and fix minimally (no logic changes).
- W0b (TASK-DEPS-UPDATE-W0b, success, Architect-verified):
yarn lint0 errors. TS parser hooked for.vueineslint.config.mjs; 21 files code-fixed (type-only/dead-code); file-targeted config exceptions with comments (src/main.tsany/unused off,pages/**multi-word off,components/WorkoutItem.vueno-mutating-props off). Prettier pass committed. - W1 (TASK-DEPS-UPDATE-W1, success, Architect-verified): patch/minor only, no major bumps. Capped:
typescript@^5.2.2→ 5.4.5 (5.9.x crashes vue-tsc 1.8),sasskept 1.69.5 (1.104 needs node ≥20.19, baseline node 18.19.1).package.jsonunchanged. - W2 split into 3 atomic waves (vue-tsc 2 may surface new type errors in src/, so it gets its own wave):
- W2a (success, Architect-verified):
vue3.3.9→3.5.42 +pinia3.0.4 (package.json: only these 2 lines). Type fixes:LngLatrefs/casts inpages/routes/Route.vueandpages/workouts/components/WorkoutItem.vue(vue-yandex-maps strict:settingstypes in vue 3.5). - W2b (success, Architect-verified):
typescript5.4.5→5.8.3 (typescript@5.8in package.json, pinned no-caret to keep the lock honest on 5.8.x) +vue-tsc1.8.27→2.2.12 (^2). Type-only fixes:File | undefinedinPreferencesHeader.vue+WorkoutUpload.vue(TS 5.8Blob.bytes). - W2c (success, Coder-verified):
vite4.5.14→5.4.21 +@vitejs/plugin-vue4.6.2→5.2.4 (package.json: only these 2 lines). Novite.config.tschanges needed; no sass legacy-API warnings appeared; CJS Node API deprecation warning observed (documented, not fixed). - sass: deferred — latest 1.x requires node ≥20.19; revisit only if the environment's node is upgraded.
- W2a (success, Architect-verified):
- W3 (planned): Tooling majors:
eslint8→9 +typescript-eslint6→8 (flat configeslint.config.mjsmay need small adjustments),prettierminor. Storybook stays on 7.
W2a acceptance criteria
vueresolved in yarn.lock to 3.5.x,piniato 3.x; NO other package moved to a new majoryarn lint— 0 errors;yarn build— green (vue-tsc 0 errors, bundle built)- No behavior changes; minimal type fixes in
src/allowed only if required, each documented - Memory Bank: status
success+ Success Report (old/new versions, any src/ fixes with justification)
W0b acceptance criteria
yarn lint— 0 errors, 0 warnings-as-errorsyarn build— still green (regression check)- No behavior changes: fixes are cosmetic/type-only; no rendering logic, props, or API calls modified
- Memory Bank updated: status
success+ Success Report with the full list of changed files and eslint config diff
Notes for the Coder (all waves)
- yarn v1 (repo has
yarn.lock); baseline node 18.19.1. - Do NOT touch
HOST, Yandex Maps key, GTM config insrc/main.ts. - One concern per task — do not continue into W0b/W1 after finishing your wave; the Architect delegates the next one.
- On escalation: set status
escalated, write a Failure Report, roll back your changes, return control.
✅ CODER SUCCESS REPORT (W0a)
Verified outcome
yarn buildGREEN:vue-tsc --noEmit→ 0 errors,vite build→ 1309 modules transformed, bundle built in ~8s.- Working tree contains exactly ONE minimal diff (see below). Lint still red — expected, W0b.
Changes made (single file, 1 line)
src/pages/workouts/components/LineWithLineChart.ts(draw()): removed// @ts-ignoreabove the zoom calculation and replaced it with non-null assertionsthis.chart.config.data!.labels!.length. No rendering logic, props, or runtime behavior changed (non-null assertions are type-level only). This also resolves the W0bban-ts-commenterror for this file up front.
Baseline discrepancy (observed, documented honestly)
- The W1 escalation report recorded
yarn buildFAIL withLineWithLineChart.ts(41,7) TS2532one79722d, but on the clean tree at W0a start the build already PASSED: the TS2532 was suppressed by the pre-existing// @ts-ignore(the error would resurface in stricter TS/vue-tsc versions — W1/W2 — which is why the assertion fix is still correct and pre-authorized by the task). - The "SFC parsing errors" in
components/WorkoutItem.vue:260andcomponents/WorkoutListItem.vue:60do NOT blockyarn build— both files have<script setup lang="ts">, andvite buildtransforms them without error. They are eslint-only parse artifacts (eslint's JS parser choking on TS syntax) → remain in scope for W0b (likely needparserOptions.parsertypescript-eslint hookup ineslint.config.mjs, no source changes required — to be confirmed by W0b Coder).
✅ CODER SUCCESS REPORT (W0b)
Verified outcome
yarn lint→ 0 errors (exit 0; prettier pass clean, eslint--fixclean).yarn build→ green:vue-tsc --noEmit0 errors,vite buildOK (~8.3s).- No behavior changes: all fixes are type-level, dead-code removal, or unused-cleanup. The only functional nuance:
CheckTheEmail.vuerecover-error check is now null-safe (error.response?.data) — a strict subset of the previous behavior (previously a hard crash ifresponsewas missing).
eslint.config.mjs (rewritten, flat config)
- CJS interop:
import tseslintPkg from "typescript-eslint";const tsParser = tseslintPkg.parser(named importtsParserfails on eslint 8 + CJS module). - Root cause of the SFC parse errors fixed: new block
files: ["**/*.vue"]withlanguageOptions.parserOptions.parser = tsParser. The vue flat config already sets the SFC parser — only the inner TS parser was missing (settinglanguageOptions.parsertopluginVue.parserfails: it is undefined at that level; the vue plugin injects the SFC parser inside its own config entries). - Global:
@typescript-eslint/no-unused-vars→["error", { argsIgnorePattern: "^_" }](covers all_response/_erroraxios catch params across src/). - File-targeted overrides (each with a reason comment):
src/main.ts—no-explicit-any+no-unused-varsOFF (documented axios-interceptor exception).src/pages/**/*.vue—vue/multi-word-component-namesOFF (route-level pages are single-word by design; renaming would break router/public names).src/pages/auth/Logout.vue—vue/valid-template-rootOFF (redirect-only screen, empty template by design).src/pages/workouts/components/WorkoutItem.vue—vue/no-mutating-propsOFF (checkbox/name edits mutate the prop object in place; fixing would be a state-management change, out of scope for the lint wave).
- No
// eslint-disablelines were added anywhere — every error was fixed in code or via the config blocks above.
Code changes (21 files, type-only / dead-code)
src/router/index.ts— removed unusedRouteViewComponentimport.src/services/utils.ts—validators.required: (v: any)→(v: unknown).src/pages/workouts/components/LineWithLineChart.ts— remaining// @ts-ignore(plugin cast) →// @ts-expect-errorwith reason (chart.js plugin config untyped).src/pages/auth/Login.vue— removed unusedHOSTinject +injectimport; 2 unused catch params dropped.src/pages/auth/Signup.vue— 2 unused catch params dropped.src/pages/auth/CheckTheEmail.vue— catch param typedAxiosError(import added);error.response.data.detailaccess made null-safe + cast (fixes TS18048/TS18046 surfaced by strict typing).src/pages/auth/RecoverPassword.vue,src/pages/auth/Logout.vue— (covered by config + earlier unused-param cleanup).src/pages/auth/Logout.vue— removed unusedpushdestructure.src/pages/workouts/Feed.vue— removed redundantv-ifonv-fortemplate (same truth condition as the siblingv-if), unusedindex; catch paramany→unknown.src/pages/workouts/WorkoutList.vue— same template fix;event: any→Event; 2× catchany→unknown.src/pages/workouts/WorkoutPublicItem.vue— no code change needed (covered byargsIgnorePattern).src/pages/workouts/WorkoutUpload.vue—catch(function (error: any)→ nameless.src/pages/workouts/components/WorkoutItem.vue—v-formarker got:key;afterEvent(chart: any, args, opts: any)→(_chart: unknown, args);isEmpty(obj: any)→Record<string, unknown>; tooltiplabel(context: any)→{ dataIndex: number };onZoomComplete(chart: any)→ structural type;saveLink/saveName (hide: any)→() => void.src/pages/workouts/components/WorkoutListItem.vue— propdeleteItem?: (item, event: any)→Event.src/pages/preferences/preferences-header/PreferencesHeader.vue— removed deadreadFilefunction (never referenced); inner.then((response: any)→(_response: AxiosResponse), unused catch params dropped.src/pages/preferences/modals/EditNameModal.vue,ResetPasswordModal.vue— unused.then(response)/.catch(error)params dropped.src/components/VuesticLogo.vue— removed deaduseColors/getColor/colorsComputed(unused; logo is a static SVG); props kept for API compatibility.src/components/app-layout-navigation/AppLayoutNavigation.vue—traverse(routers: any[])now typed with the route interface exported fromNavigationRoutes.ts(imported alongside the default);src/components/navbar/components/AppNavbarActions.vue— dropped unuseduseI18n/tdestructure.src/components/sidebar/AppSidebar.vue— internalname: "Sidebar"→"AppSidebar"(not used anywhere as a global name; options-APInamefield only).src/components/navbar/components/AppNavbarActions.vue— removed unuseduseI18n/t.- Prettier (
prelint) auto-reformatted ~30src/files — these formatting changes are part of the intended clean diff (kept).
Left for later waves
vue/no-mutating-propsincomponents/WorkoutItem.vue(suppressed, file-targeted) — proper fix = local state extraction, separate task.src/main.tsloose typing (suppressed, file-targeted) — pre-existing documented debt.- W1 (
yarn uppatch/minor) is unblocked.
✅ CODER SUCCESS REPORT (W1)
Verified outcome
yarn lint→ 0 errors (prettier + eslint--fixclean) — run AFTER the upgrade.yarn build→ green:vue-tsc --noEmit0 errors,vite buildOK (~7.3s).yarn install --frozen-lockfile→ clean (fresh install from the new lockfile works).package.json— unchanged (verified viagit diff). The only W1 diffs areyarn.lock(+ the pre-existing uncommitted W0a/W0b changes insrc//eslint.config.mjs, which W1 did not touch).- No major bump anywhere in
yarn.lock: every direct dependency stayed within its semver range (spot-checked all 61 direct deps, old vs new lockfile).
Notable version changes (direct deps, old → new)
| package | old | new | note |
|---|---|---|---|
| typescript | 5.2.2 | 5.4.5 | ⚠️ capped — see known issues |
| postcss | 8.4.31 | 8.5.28 | |
| axios | 1.7.7 | 1.20.0 | |
| chart.js | 4.4.4 | 4.5.1 | |
| chartjs-chart-geo | 4.2.8 | 4.3.6 | |
| chartjs-plugin-zoom | 2.0.1 | 2.2.0 | |
| eslint | 8.57.0 | 8.57.1 | |
| eslint-plugin-prettier | 5.0.1 | 5.5.6 | |
| eslint-plugin-react | 7.34.1 | 7.37.5 | |
| eslint-plugin-vue | 9.25.0 | 9.33.0 | |
| globals | 15.0.0 | 15.15.0 | |
| lint-staged | 15.2.10 | 15.5.2 | |
| pinia | 2.1.7 | 2.3.1 | |
| prettier | 3.1.0 | 3.9.6 | |
| serve | 14.2.3 | 14.2.6 | |
| storybook (suite) | 7.6.20 / 7.5.3 | 7.6.24 | addons 7.5.3 → 7.6.24 |
| tailwindcss | 3.4.1 | 3.4.19 | |
| typescript-eslint | 7.6.0 | 7.18.0 | |
| @typescript-eslint/eslint-plugin, /parser | 6.11.0 | 6.21.0 | within ^6.11.0 (minor) — verified in lock |
| vite | 4.5.5 | 4.5.14 | |
| vue-chartjs | 5.3.1 | 5.3.4 | |
| vue-eslint-parser | 9.4.2 | 9.4.3 | |
| vue-i18n | 9.6.5 | 9.14.5 | |
| vue-router | 4.2.5 | 4.6.4 | |
| vue-yandex-maps | 2.1.4 | 2.3.3 | |
| vuestic-ui | 1.9.0 | 1.10.3 | |
| sass | 1.69.5 | 1.69.5 | ⚠️ capped (not upgraded) — see known issues |
| vue, vue-tsc | 3.3.9, 1.8.27 | unchanged | pinned / latest 1.x |
Verified: @typescript-eslint/eslint-plugin / @typescript-eslint/parser (declared ^6.11.0) resolve to 6.21.0 in the new lockfile — within range, no out-of-range resolution. The separate 7.18.0 lock entries belong to the typescript-eslint@^7.6.0 meta-package's fixed dependencies.
Known issues / caveats (recorded in progress.md)
yarn upalias missing in the installed yarn 1.22.22 binary (/home/artem/.local/lib/node_modules/yarn—lib/cli.jshas noupcommand). Usedyarn upgrade [pkgs]— the documented equivalent.sasscapped at 1.69.5:^1.69.5resolves to 1.104.0, whoseenginesrequire node ≥20.19.0 (baseline is node 18.19.1) → hard engine error. Kept at baseline; the latest 1.x compatible with node 18 can be picked up in a follow-up or after a node 20 baseline.typescriptcapped at 5.4.5:^5.2.2resolved to 5.9.3, which crashesvue-tsc@1.8.27(Search string not found: "supportedTSExtensions"— TS ≥5.5 internal API change). Applied per rule 5:yarn add -D typescript@5.4.5, then restoredpackage.jsonto^5.2.2viagit checkout(package.json must stay untouched) and renamed the lockfile keytypescript@5.4.5→typescript@^5.2.2(one manual 1-line lock edit) so--frozen-lockfilestays consistent. Upgrading vue-tsc to 2.x (which supports newer TS) is explicitly W2 scope.
Files changed by W1
yarn.lock— full patch/minor refresh + 2 caps (typescript 5.4.5, sass 1.69.5) + 1 key rename.- No
src/changes, nopackage.jsonchanges, no HOST/Yandex/GTM changes.
✅ CODER SUCCESS REPORT (W2a)
Versions (package.json → resolved in yarn.lock)
| package | old | new |
|---|---|---|
vue |
3.3.9 (exact) |
^3.5 → 3.5.42 |
pinia |
^2.1.7 (2.3.1 in lock) |
^3 → 3.0.4 |
- Applied via
yarn add vue@^3.5 pinia@^3.git diff package.json= exactly the two lines above, nothing else. - No other direct dependency moved to a new major: the only new/changed lockfile entries are the vue 3.5 subtree (
@vue/runtime-core@3.5.42,@vue/server-renderer@3.5.42,@vue/devtools-kit/shared) and pinia 3's new deps (birpc,mitt,hookable,superjson,speakingurl,copy-anything,perfect-debounce) — all newly required by the two target packages; everything else is patch/minor drift inside existing ranges (W1 was already verified major-free, and the W2a re-resolution only touched the vue/pinia subtrees).
Type-only fixes in src/ (2 files, no logic changes)
Vue 3.5's template type-checking became strict about the vue-yandex-maps :settings prop: ymaps LngLat = [lon, lat, alt?] is a tuple, while the app data is number[] / number[][]. Under 3.3 these assignments were accepted; 3.5 rejects them (6× TS2322 in Route.vue + components/WorkoutItem.vue). Fixes are type-level only — runtime values are unchanged:
-
src/pages/routes/Route.vue—ref([30.31413, 59.93863])→ref<LngLat>([30.31413, 59.93863])(literal is a valid 2-tuple;LngLatalready imported in the file). -
src/pages/workouts/components/WorkoutItem.vue:import type { YMap }→import type { LngLat, YMap } from "@yandex/ymaps3-types";- template casts (values already
[lon, lat]pairs from the API):center: mapCenter as LngLat,coordinates: lineCoordinates as LngLat[],coordinates: markedCoordinats as LngLat[],coordinates: currentCoordinates as LngLat; clickCoordinates: ref<Array<number>>→ref<LngLat[]>— sound: it is only ever assignede.coordinatesfrom Yandex map click events, which areLngLat.
Parent components (
pages/workouts/WorkoutItem.vue,WorkoutPublicItem.vue) pass their existingArray<number>/Array<Array<number>>refs into the props unchanged — prop signatures untouched, so no cascade.
Verification
- Baseline (before update):
yarn lint0 errors,yarn buildgreen (1390 modules). - After update:
yarn lint→ 0 errors (eslint clean, prettier all unchanged);yarn build→ green:vue-tsc --noEmit0 errors,vite buildOK (~7.5s, 1396 modules). - Runtime smoke-check:
yarn devboots (Vite ready ~0.6s, no errors);GET /→ 200 with expected HTML; key entry modules (/src/main.ts,/src/App.vue, both map pages,/src/stores/user-store.ts) transform and serve 200 with no dev-server compile errors. - Untouched as required:
HOST/Yandex key/GTM insrc/main.ts, i18n locales,eslint.config.mjs.
Left for W2b
vue-tsc1.8.27 currently works with vue 3.5.42; vue-tsc 2.x + TS bump is W2b. Note: vue 3.5 types are already stricter in templates (see above) — more type-only fixes may surface in W2b/W2c.
✅ CODER SUCCESS REPORT (W2b)
Versions (package.json → resolved in yarn.lock)
| package | old | new |
|---|---|---|
typescript |
^5.2.2 (5.4.5 in lock) |
"5.8" → 5.8.3 |
vue-tsc |
^1.8.22 (1.8.27) |
^2 → 2.2.12 |
- Applied via
yarn add -D typescript@5.8 vue-tsc@^2.git diff package.jsonchanged exactly these two lines (plus the pre-existing uncommitted W2avue/pinialines).typescriptpinned without caret so the lock resolves to 5.8.x, NOT 5.9 (vue-tsc 2 officially supports TS ≤5.8). - No foreign major bump: verified all 61 direct deps — only new lock entries are the
vue-tsc2.x subtree (@vue/language-core@2.2.12,@volar/source-map,@volar/typescript,muggle-string,alien-signals,vscode-uri,@vue/compiler-vue2), all newly required by vue-tsc 2.typescriptstayed at 5.8.x (not 5.9).
Type-only fixes in src/ (2 files, 4 errors, no logic changes)
TS 5.8 + vue-tsc 2 surfaced errors in the two file-upload pages. The legacy let file: {inline object type} declaration was (a) never a real File (TS 5.8's Blob now declares required bytes, which the structural object lacked → TS2769 on FormData.append), and (b) had no initializer (definite-assignment TS2454). Fixed type-only — runtime values/behavior unchanged:
src/pages/preferences/preferences-header/PreferencesHeader.vue—let file: {…inline…}(14-line structural type) →let file: File | undefined = undefined;(initial valueundefinedresolves TS2454);formData.append("file", file)→formData.append("file", file!)(non-null assertion; the upload is only ever reachable after a file is chosen, so this is type-level only).src/pages/workouts/WorkoutUpload.vue—let file: {…inline…}→let file: File | undefined = undefined;(same fix; the function already guardsif (file == undefined) return;so no assertion needed).
Verification
- Baseline (before update):
yarn lint0 errors,yarn buildgreen. - After update:
yarn lint→ 0 errors (eslint clean);yarn build→ green:vue-tsc 2.2.12 --noEmit0 errors,vite buildOK (~7.3s). - Untouched as required:
HOST/Yandex key/GTM insrc/main.ts, i18n locales,eslint.config.mjs,vite.config.ts.
Left for W2c
vite4→5 +@vitejs/plugin-vue4→5. Watch: sass legacy-API deprecation warnings in vite 5 (warnings OK, errors not). Architect delegates.
✅ CODER SUCCESS REPORT (W2c)
Versions (package.json → resolved in yarn.lock)
| package | old | new |
|---|---|---|
vite |
^4.4.6 (4.5.14 in lock) |
^5 → 5.4.21 |
@vitejs/plugin-vue |
^4.2.3 (4.6.2 in lock) |
^5 → 5.2.4 |
- Applied via
yarn add -D vite@^5 @vitejs/plugin-vue@^5.git diff package.jsonchanged exactly these two lines. - No foreign major bump: audited the full lockfile diff — the only version-moved packages are
vite(4.5.14→5.4.21) and@vitejs/plugin-vue(^4.2.3 key → 5.2.4). New lock entries are exclusively the vite 5 subtree:rollup@4.63.1+@rollup/rollup-*platform binaries,esbuild@0.21.5+@esbuild/*platform binaries,@napi-rs/lzma-linux-x64-gnu.esbuild@0.18.20androllup@3.30.0remain for the storybook pin; the storybook@vitejs/plugin-vue@^4.0.0pin still resolves to 4.6.2 (separate lock entry, untouched). sassstayed at 1.69.5 (per task rule — update forbidden in this wave).
Warnings observed (documented, NOT fixed per task rules)
The CJS build of Vite's Node API is deprecated(bothvite buildandvite dev) — expected with vite 5 + CJS-transpiled config consumers; warning only, no action required in this wave.- No sass legacy JS API deprecation warnings appeared in
yarn build(sass 1.69.5 + vite 5.4.21 compiledsrc/scss/**cleanly). The anticipated legacy-API warning did not materialize. - Pre-existing (unchanged): chunk-size warning (
index-*.js> 500 kB) andvuestic-icons.eotruntime-resolution notice — present on the vite 4 baseline as well.
Verification
- Baseline (before update):
yarn lint0 errors,yarn buildgreen (vite 4.5.14, ~7.2s). - After update:
yarn lint→ 0 errors (eslint clean, prettier all unchanged);yarn build→ green:vue-tsc --noEmit0 errors,vite buildv5.4.21 OK (~6.5s, 1396 modules). - Smoke-check:
yarn devbooted (VITE v5.4.21 ready in 372 ms);GET /→ 200,GET /src/main.ts→ 200,GET /src/App.vue→ 200,GET /src/pages/workouts/Feed.vue→ 200; dev log free of errors; dev server stopped after the check. - Untouched as required: all
src/code,vite.config.ts(no config changes needed — API-compatible),HOST/Yandex key/GTM insrc/main.ts, i18n locales,eslint.config.mjs, sass.
Left for W3 (Architect delegates)
- Tooling majors:
eslint8→9 +typescript-eslint6/7→8 (flat config adjustments),prettierminor. Storybook stays on 7.
History
W1 escalation (2025, commit e79722d)
Baseline was RED before any dependency change — W1 stopped before yarn up. Zero dependencies modified.
yarn lint→ FAIL: 55 errors (11 auto-fixable).lintscript runsprelint: prettier --write ., auto-rewriting ~30src/files.yarn build→ FAIL:LineWithLineChart.ts(41,7): error TS2532.- Non-auto-fixable classes:
ban-ts-comment, SFC parse errors inWorkoutItem.vue:260/WorkoutListItem.vue:60,no-unused-vars(router/index.ts:6),no-explicit-any(services/utils.ts:11). - Resolved by: prerequisite wave W0 (this plan).