Moves phases 08–11 execution artifacts from .planning/phases/ to
.planning/milestones/v0.2-phases/ to keep .planning/phases/ clean
for the next milestone.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
toast.js (stores): Replaced the Phase 8 no-op stub with a full Pinia setup-store implementation. Exports { toasts, show, dismiss }. toasts is a ref([]) reactive array. show(message, type='success', duration=4000) pushes { id, message, type, duration } and schedules setTimeout(() => dismiss(id), duration) when duration > 0. dismiss(id) filters the array by id. The locked signature show(message, type, duration) is preserved — Phase 8 call sites in SettingsAccountTab.vue and TotpEnrollment.vue work unchanged.
ToastContainer.vue (components/ui): Options API component. Uses <Teleport to="body"> with <TransitionGroup name="toast">. Container div is fixed bottom-4 right-4 z-[9999] flex flex-col-reverse gap-2 pointer-events-none. Each toast item has data-test="toast" for testing, a colored left-accent bar (w-1 self-stretch), an <AppIcon> with type-driven name and color, and the message paragraph. Clicking dismisses via toastStore.dismiss(toast.id). CSS transition: all 0.2s ease with opacity: 0; transform: translateX(20px) for enter-from/leave-to.
App.vue: Added import ToastContainer and <ToastContainer /> placed after the <div v-else> layout block so it floats above all routes including AuthLayout.
Verification Results
Check
Result
npm run test -- --run toast (6 store + 4 container = 10 tests)
PASS
npm run test -- --run ToastContainer (4 tests)
PASS
npm run test -- --run SettingsAccountTab (regression)
PASS (7 tests)
npm run test -- --run TotpEnrollment (regression)
PASS (4 tests)
Locked signature grep
PASS (1 match)
<ToastContainer in App.vue
PASS (2 occurrences)
Teleport to="body" in ToastContainer
PASS
Deviations from Plan
None — plan executed exactly as written.
Known Stubs
None.
Threat Flags
None. Toast notification is a purely client-side display system with no network endpoints, auth paths, or file access.
Self-Check: PASSED
frontend/src/stores/toast.js — exists and contains implementation
frontend/src/components/ui/ToastContainer.vue — exists with Teleport + data-test attributes
frontend/src/App.vue — contains ToastContainer import and element