Adds the notifications system end-to-end (4 types, payload-versioned JSONB, SSE-based live unread badge, /notifications page, mark-read API, fan-out job for activity_published, daily 90-day retention purge). Bell icon in the navbar with unread badge. Side-findings from exercising the change: - Add 6-digit magic code to registration (mirrors login UX, mobile paste-friendly), with `[Register Magic Link]` console line in dev so the code is reachable without a real email transport. - Manual passkey/magic-link toggle on the register form (login already had it). - Restrict ALPN to http/1.1 in HTTPS dev so React Router's singleFetchAction CSRF check (Origin vs. Host) passes — Node doesn't synthesize Host from h2's :authority. Plain HTTP dev unaffected. - Followers/Following routes now use the locked-account rule from the profile route (owner + accepted followers see the list; others 404). Profile page renders the count chips as plain spans for viewers who can't see the lists, so private profiles don't surface dead links. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
43 lines
1.5 KiB
TypeScript
43 lines
1.5 KiB
TypeScript
import { reactRouter } from "@react-router/dev/vite";
|
|
import { sentryVitePlugin } from "@sentry/vite-plugin";
|
|
import tailwindcss from "@tailwindcss/vite";
|
|
import { defineConfig } from "vite";
|
|
import path from "node:path";
|
|
|
|
export default defineConfig({
|
|
build: {
|
|
sourcemap: "hidden",
|
|
},
|
|
plugins: [
|
|
tailwindcss(),
|
|
reactRouter(),
|
|
...(process.env.HTTPS === "1" ? [import("@vitejs/plugin-basic-ssl").then((m) => m.default())] : []),
|
|
sentryVitePlugin({
|
|
org: "trails-qq",
|
|
project: "journal",
|
|
release: { name: process.env.SENTRY_RELEASE },
|
|
sourcemaps: { filesToDeleteAfterUpload: ["./build/**/*.map"] },
|
|
disable: !process.env.SENTRY_AUTH_TOKEN,
|
|
telemetry: false,
|
|
}),
|
|
],
|
|
resolve: {
|
|
alias: {
|
|
"~": path.resolve(__dirname, "./app"),
|
|
},
|
|
},
|
|
server: {
|
|
port: 3000,
|
|
host: true,
|
|
// Force HTTP/1.1 over TLS in HTTPS dev. Vite v8 starts an
|
|
// `http2.createSecureServer({ allowHTTP1: true })` for any HTTPS
|
|
// config, so ALPN negotiates h2 by default. That breaks
|
|
// `useFetcher().Form` POSTs because React Router's CSRF check in
|
|
// `singleFetchAction` compares `Origin` against the `Host` header,
|
|
// which HTTP/2 replaces with `:authority` and Node doesn't
|
|
// synthesize back. Restricting ALPN to `http/1.1` keeps the Host
|
|
// header intact and lets fetcher form submissions through.
|
|
// Plain HTTP dev (the default) is unaffected.
|
|
https: process.env.HTTPS === "1" ? { ALPNProtocols: ["http/1.1"] } : undefined,
|
|
},
|
|
});
|