Add multi-user auth, background generation, and chat UX improvements

Phase 5: Multi-user authentication with session cookies, bcrypt passwords,
first-user-is-admin pattern, per-user data isolation, backup/restore,
Docker Swarm production stack with secrets and network isolation.

Phase 5.1: Chat UX improvements:
- Background generation architecture (GenerationBuffer + asyncio task)
  with SSE fan-out, reconnect support, and periodic DB flushes
- LLM-generated conversation titles (first exchange + every 10th message)
- Stop generation button with cancel_event and partial content preservation
- Relative timestamps in sidebar (5m ago, 3h ago, then dates)
- Empty chat auto-cleanup on navigation away
- Save-as-note uses LLM for title generation, tags notes with "chat"
- Summarize-as-note also tags with "chat"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-11 14:36:30 -05:00
parent db01106714
commit cbfdf5289e
49 changed files with 3105 additions and 369 deletions
+28
View File
@@ -1,5 +1,6 @@
import { createRouter, createWebHistory } from "vue-router";
import HomeView from "@/views/HomeView.vue";
import { useAuthStore } from "@/stores/auth";
const router = createRouter({
history: createWebHistory(),
@@ -9,6 +10,18 @@ const router = createRouter({
name: "home",
component: HomeView,
},
{
path: "/login",
name: "login",
component: () => import("@/views/LoginView.vue"),
meta: { public: true },
},
{
path: "/register",
name: "register",
component: () => import("@/views/RegisterView.vue"),
meta: { public: true },
},
{
path: "/notes",
name: "notes",
@@ -67,4 +80,19 @@ const router = createRouter({
],
});
router.beforeEach(async (to) => {
if (to.meta.public) return;
const authStore = useAuthStore();
// Wait for initial auth check if still loading
if (authStore.loading && !authStore.isAuthenticated) {
await authStore.checkAuth();
}
if (!authStore.isAuthenticated) {
return { name: "login", query: { redirect: to.fullPath } };
}
});
export default router;