1. Performance: 25 pages switched from force-dynamic to revalidate=300 (ISR); 2 pages (community, developers) now fully static (SSG) 2. DB indexes: Added @@index on foreign keys for WebsiteArticles, WebsiteArticleReactions, WebsiteArticleComments, WebsiteHelpCenterTickets, WebsiteShopArticles, RadioSongRequests, StaffActivities 3. SEO: Added robots.ts, sitemap.ts, canonical URLs, Open Graph + Twitter Card metadata on root layout and news articles 4. A11Y: Replaced <details>/<summary> dropdowns with accessible button-based NavDropdown (aria-expanded, aria-haspopup, role=menu). MobileNav now uses translated aria-label, aria-expanded, aria-controls, role=menu 5. Code quality: Added try/catch to updateArticle/deleteArticle; deleteArticle now uses prisma. for atomicity 6. CI/CD: Added GitHub Actions workflow (typecheck + test) 7. i18n: Added openMenu/closeMenu keys to all 6 locales 8. Observability: Health endpoint now checks SMTP reachability when configured 9. Loading states: Added loading.tsx for root, admin, and news sections 10. Word filter cache: Added 60s TTL auto-refresh instead of manual cache bust
This commit is contained in:
1 parent
10523e58ce
commit
8bcbc501ba
48 files changed
+337
-98
No files matched your search
@@ -1,24 +1,42 @@
|
||||
import { apiJson } from "@/lib/api";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { rcon } from "@/lib/services/rcon";
|
||||
import { env } from "@/env";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
/**
|
||||
* Ops health probe: database reachability, emulator RCON reachability, and
|
||||
* runtime info. Returns HTTP 200 always (read the `status`/`database` fields),
|
||||
* so it's safe for uptime monitors that only care about reachability.
|
||||
* Ops health probe: database reachability, emulator RCON reachability, SMTP
|
||||
* (when configured), and runtime info. Returns HTTP 200 always (read the
|
||||
* `status`/`database` fields), so it's safe for uptime monitors that only care
|
||||
* about reachability.
|
||||
*/
|
||||
export async function GET() {
|
||||
const database = await prisma
|
||||
.$queryRaw`SELECT 1`.then(() => true)
|
||||
.catch(() => false);
|
||||
|
||||
const emulator = await rcon.send("ping", null).catch(() => false);
|
||||
|
||||
let smtp = null;
|
||||
if (env.SMTP_HOST) {
|
||||
const nodemailer = await import("nodemailer");
|
||||
const test = nodemailer.createTransport({
|
||||
host: env.SMTP_HOST,
|
||||
port: env.SMTP_PORT,
|
||||
secure: env.SMTP_SECURE,
|
||||
auth: env.SMTP_USER
|
||||
? { user: env.SMTP_USER, pass: env.SMTP_PASSWORD ?? "" }
|
||||
: undefined,
|
||||
});
|
||||
smtp = await test.verify().then(() => true).catch(() => false);
|
||||
}
|
||||
|
||||
return apiJson({
|
||||
status: database ? "ok" : "degraded",
|
||||
database,
|
||||
emulator,
|
||||
smtp,
|
||||
node: process.version,
|
||||
uptime: Math.round(process.uptime()),
|
||||
time: new Date().toISOString(),
|
||||
|
||||
Reference in new issue
Block a user