Private
Public Access
1
0

Phase 9: Admin & DevOps — health check, rate limiting, logging, site admin, Docker healthcheck

- Health check endpoint (GET /api/health) with DB probe and uptime
- In-memory sliding window rate limiting on login (10/60s) and register (5/3600s)
- Structured logging with pino (request timing in hooks, Socket.IO events in server.js)
- Site admin dashboard with tenant stats, CRUD, and requireSiteAdmin guard
- Tenant admin enhanced with tag and category management UI
- Docker HEALTHCHECK in Dockerfile and docker-compose.yml
- Backup documentation (docs/backup.md)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Catherine Renelle
2026-02-26 01:24:24 -05:00
parent 7559102479
commit 0bba161c12
19 changed files with 932 additions and 21 deletions
+7 -4
View File
@@ -2,8 +2,11 @@ import express from 'express';
import { createServer } from 'http';
import { Server } from 'socket.io';
import { PrismaClient } from '@prisma/client';
import pino from 'pino';
import { handler } from './build/handler.js';
const logger = pino({ name: 'pounce' });
const app = express();
const server = createServer(app);
@@ -64,7 +67,7 @@ io.use(async (socket, next) => {
}
next();
} catch (err) {
console.error('Socket auth error:', err);
logger.error({ err }, 'Socket auth error');
socket.data.user = null;
next();
}
@@ -73,7 +76,7 @@ io.use(async (socket, next) => {
// ─── Socket.IO connection handler ────────────────────────────
io.on('connection', (socket) => {
const user = socket.data.user;
console.log(`Socket connected: ${socket.id} (user: ${user?.name ?? 'anon'})`);
logger.info({ socketId: socket.id, user: user?.name ?? 'anon' }, 'Socket connected');
// Join user-specific room for notifications
if (user) {
@@ -122,7 +125,7 @@ io.on('connection', (socket) => {
});
socket.on('disconnect', () => {
console.log(`Socket disconnected: ${socket.id}`);
logger.info({ socketId: socket.id }, 'Socket disconnected');
for (const boardId of joinedBoards) {
if (presence.has(boardId)) {
presence.get(boardId).delete(socket.id);
@@ -152,5 +155,5 @@ const port = process.env.PORT || 3000;
const host = process.env.HOST || '0.0.0.0';
server.listen(port, host, () => {
console.log(`Server running on http://${host}:${port}`);
logger.info({ host, port }, 'Server running');
});