feat(backend): invites, notifications, chat, uploads, teams, groups, hardening
- Pending workspace invites with accept/decline + bell notifications; invite permission extendable via workspace.invite group right - Notifications API (list/unread, mark read, read-all) + realtime push to per-user socket rooms; chat messages notify other members - Workspace team chat API (list/post/delete) + chat:join socket rooms - Image uploads (multer, 5MB image-only) served from /uploads - Teams (managers/members), team-owned workspaces (TEAM badge), team task boards (team_id) and task assignees (workspace members only) - Permission groups with teams.create/edit/invite + workspace.invite, default Team Creators seeding, hasPerm/canManageTeam guards - Public registration disabled after install; admins create users (pending invites auto-link); users gain bg_glass setting - Crash fix: express-async-errors + 400 on malformed IDs instead of unhandled rejections killing the server
This commit is contained in:
+16
-1
@@ -1,4 +1,5 @@
|
||||
import 'dotenv/config';
|
||||
import 'express-async-errors';
|
||||
import http from 'node:http';
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
@@ -15,6 +16,12 @@ import bookRoutes from './routes/books.js';
|
||||
import taskRoutes from './routes/tasks.js';
|
||||
import timeRoutes from './routes/time.js';
|
||||
import adminRoutes from './routes/admin.js';
|
||||
import inviteRoutes from './routes/invites.js';
|
||||
import notificationRoutes from './routes/notifications.js';
|
||||
import chatRoutes from './routes/chat.js';
|
||||
import teamRoutes from './routes/teams.js';
|
||||
import groupRoutes from './routes/groups.js';
|
||||
import uploadRoutes from './routes/upload.js';
|
||||
import { initSocket } from './socket.js';
|
||||
|
||||
const app = express();
|
||||
@@ -51,6 +58,13 @@ app.use('/api/books', bookRoutes);
|
||||
app.use('/api/tasks', taskRoutes);
|
||||
app.use('/api/time', timeRoutes);
|
||||
app.use('/api/admin', adminRoutes);
|
||||
app.use('/api/invites', inviteRoutes);
|
||||
app.use('/api/notifications', notificationRoutes);
|
||||
app.use('/api/chat', chatRoutes);
|
||||
app.use('/api/teams', teamRoutes);
|
||||
app.use('/api/groups', groupRoutes);
|
||||
app.use('/api/upload', uploadRoutes);
|
||||
app.use('/uploads', express.static('uploads'));
|
||||
|
||||
app.get('/api/health', async (_req, res) => {
|
||||
try {
|
||||
@@ -62,7 +76,8 @@ app.get('/api/health', async (_req, res) => {
|
||||
});
|
||||
|
||||
app.use((err, _req, res, _next) => {
|
||||
console.error('[unhandled]', err);
|
||||
console.error('[unhandled]', err?.message || err);
|
||||
if (err?.code === '22P02') return res.status(400).json({ error: 'Invalid ID format' });
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user