docs(02): add root causes from diagnosis

This commit is contained in:
curo1305
2026-05-31 20:28:57 +02:00
parent 52d6efb8a2
commit b2488c91c8
@@ -1,5 +1,5 @@
---
status: complete
status: diagnosed
phase: 02-users-authentication
source: [02-01-SUMMARY.md, 02-02-SUMMARY.md, 02-03-SUMMARY.md, 02-04-SUMMARY.md, 02-05-SUMMARY.md]
started: 2026-05-31T00:00:00Z
@@ -116,53 +116,96 @@ blocked: 2
reason: "User reported: I don't see an option to activate or setup a 2FA method."
severity: major
test: 4
artifacts: []
missing: []
root_cause: "AccountView.vue (which contains TotpEnrollment) is registered at /account but unreachable through the UI. The sidebar links to /settings (SettingsView.vue), which has only Preferences/AI/Cloud tabs — no Account or Security tab. /account is an orphaned route."
artifacts:
- path: "frontend/src/components/layout/AppSidebar.vue"
issue: "No navigation link to /account — sidebar only links to /settings"
- path: "frontend/src/views/SettingsView.vue"
issue: "No Account/Security tab that would surface AccountView's TOTP content"
missing:
- "Add Account/Security tab to SettingsView.vue (or sidebar link to /account)"
- "User account page should be discoverable from main navigation"
- truth: "Auth/login pages use AuthLayout (no sidebar, no user identity) so previously logged-in user info is never shown on public pages"
status: failed
reason: "User reported: I do see the sidebar every time when I login. I do not want the sidebar on the login page and I do not want to leak this information of the previous logged in user when no one is logged in. Confirmed again on logout: sidebar still visible while logged out."
severity: major
test: 6
artifacts: []
missing: []
root_cause: "App.vue renders <AppSidebar /> unconditionally in the root template — no route-meta check, no layout switching. AuthLayout.vue exists and is correctly implemented but is never imported or used anywhere. Auth routes only have meta: { public: true }; there is no meta.layout hint and App.vue never reads it."
artifacts:
- path: "frontend/src/App.vue"
issue: "<AppSidebar /> is an unconditional child in the root template — no v-if or layout switch"
- path: "frontend/src/router/index.js"
issue: "Auth routes missing meta: { layout: 'auth' } — no layout hint for App.vue to consume"
- path: "frontend/src/layouts/AuthLayout.vue"
issue: "Correctly implemented but dead — never imported or activated by any code path"
missing:
- "App.vue must become layout-aware: read route.meta.layout and conditionally render AuthLayout vs app shell"
- "Auth routes (/login, /register, /password-reset, /password-reset/confirm) need meta: { layout: 'auth' }"
- truth: "After logout, the sidebar (including user identity footer) is no longer visible — user is on the login page with AuthLayout only"
status: failed
reason: "User reported: I am logged out right now but I still see the sidebar, which is not a desired behaviour."
severity: major
test: 7
artifacts: []
missing: []
root_cause: "Same root cause as test 6 — App.vue always renders AppSidebar regardless of route. Fixed by the same App.vue layout-aware change."
artifacts:
- path: "frontend/src/App.vue"
issue: "Same as test 6 — AppSidebar always rendered"
missing:
- "Same fix as test 6 — covered by same plan task"
- truth: "TOTP enrollment flow: no QR code required (otpauth:// link + manual secret is acceptable), but the manual secret must be valid and correctly rendered so users can add it to an authenticator app"
- truth: "TOTP enrollment flow: QR code rendered so desktop users can scan without manually typing a 32-char secret"
status: failed
reason: "User reported: no QR code visible (expected — known MVP stub), security key doesn't work (possibly misspelled in display), otpauth:// link opens macOS Passwords app (expected behavior on Mac)."
reason: "User reported: no QR code visible, security key doesn't work (possibly misspelled in display), otpauth:// link opens macOS Passwords app instead of working on desktop."
severity: major
test: 9
artifacts: []
missing: []
root_cause: "TotpEnrollment.vue renders a plain <a href='otpauth://...'> hyperlink instead of a QR image. No QR library is installed (package.json has no qrcode/qr.js). The otpauth:// protocol has no default handler on desktop browsers. The backend secret is correct (valid base32, correct URI) — only the frontend rendering is wrong."
artifacts:
- path: "frontend/src/components/auth/TotpEnrollment.vue"
issue: "Renders <a href='otpauth://...'> text link instead of QR image — comment says 'no QR library dependency' confirming intentional omission"
- path: "frontend/package.json"
issue: "No QR code library installed (qrcode, qr.js, etc.)"
missing:
- "Add qrcode npm package"
- "Render QR image from qrUri in TotpEnrollment.vue step 1"
- truth: "Account settings (/account) is presented as a tab within a unified Settings page, not a standalone route"
status: failed
reason: "User requested: account page should be a tab inside a settings page (UX improvement)"
severity: minor
test: 9
artifacts: []
missing: []
root_cause: "AccountView.vue is a standalone route at /account. SettingsView.vue exists but has no Account/Security tab. User wants a unified settings experience."
artifacts:
- path: "frontend/src/views/SettingsView.vue"
issue: "Missing Account/Security tab"
- path: "frontend/src/views/AccountView.vue"
issue: "Standalone orphaned view — should be merged into settings as a tab"
missing:
- "Merge AccountView content into SettingsView as a new Account/Security tab"
- "Update router to redirect /account to /settings (account tab)"
- truth: "Non-admin users are blocked from /admin (redirected or shown 403); the Admin link is hidden in the sidebar for non-admins"
status: failed
reason: "User reported: can navigate to /admin as a non-admin user; all tabs visible but no data shown (backend blocks data but frontend does not block the route)"
severity: major
test: 14
artifacts: []
missing: []
root_cause: "The /admin route in router/index.js has no meta field at all. The beforeEach guard only checks accessToken — it never reads user.role. Any authenticated user passes through. The authStore.user (including role) is reliably populated before the guard completes, so there is no timing issue — the guard simply never checks role."
artifacts:
- path: "frontend/src/router/index.js"
issue: "/admin route definition has no meta property; beforeEach guard has zero role-checking logic"
missing:
- "Add meta: { requiresAdmin: true } to /admin route"
- "Add admin role check in beforeEach: if to.meta.requiresAdmin && user.role !== 'admin' → redirect to /"
- truth: "Admin can create a new user via the Users tab form — POST /api/admin/users returns 201 and the new user appears in the table"
status: failed
reason: "User reported: cannot create a new user as admin; form returns HTTP 500 error."
severity: blocker
test: 15
artifacts: []
missing: []
root_cause: "Missing 'await session.flush()' before write_audit_log() in the admin create_user handler. Three pending objects (User, Quota, AuditLog) flush without guaranteed ordering — on PostgreSQL, the FK constraint on audit_log.user_id causes an IntegrityError when AuditLog is flushed before the User row exists. SQLite (used in tests) has FK enforcement disabled by default, so all unit tests pass silently."
artifacts:
- path: "backend/api/admin.py"
issue: "Missing 'await session.flush()' after session.add(quota) and before write_audit_log() — User+Quota not persisted when AuditLog FK references users.id"
missing:
- "Add 'await session.flush()' after session.add(quota) in create_user handler — matches pattern already used in auth/register and bootstrap_admin"