Files
TX/artifacts/api-server/src/index.ts
T
riyadhafraa 84398de390 Task #511: Fully remove Chat feature
Destructive removal per user confirmation ("حذف نهائي ما يرجع").

Removed:
- API: routes/conversations.ts, schema/conversations.ts, all chat
  socket handlers in src/index.ts, /admin/users/:id/dependents/
  conversations+messages endpoints, conversation/message dependency
  counts in users/stats routes.
- Web: pages/chat.tsx, /chat route, dock chat filter, MessageSquare
  icon and messages StatCard on home, all chat-related UI in
  notifications + admin (dependency badges, delete-dialog rows,
  UserDependentConversations/Messages sections, count map keys).
- Locales: nav.chat, home.stats.messages, full chat.* block,
  admin.deleteUser conv/msgCount, admin.users.counts.conv/msg,
  admin.audit.unit.conversation_*/message_*, admin.dependents.user*.
- OpenAPI spec: tags, all /conversations/* paths, conv/msg dependent
  paths, related schemas (ConversationWithDetails, MessageWithSender,
  UserDependentConversation/MessageItem+Page, etc.), UserProfile and
  UserDeletionConflict conv/msg fields, HomeStats.unreadMessages.
  Regenerated client via orval.
- Database: dropped message_reads, messages,
  conversation_participants, conversations (CASCADE); deleted
  notifications with related_type='conversation' or type='chat';
  deleted apps row with slug='chat'; ran drizzle push-force.
- Seed: removed chat:access permission + user-role assignment +
  seeded chat app entry from scripts/src/seed.ts.
- Tests: deleted conversations-leave.test.mjs; cleaned chat refs from
  list-dependency-counts, delete-force-warnings, audit-log-coverage,
  and admin-inline-dependency-counts (e2e) — replaced chat dependents
  with note dependents where needed for force-delete coverage.

Notes preserved: notes.tsx noConversationsYet/conversationWith refer
to NOTE THREADS (not chat) and were intentionally NOT touched.

executive-meetings.ts not modified per replit.md restriction.
Pre-existing flaky test failures in executive-meetings/group/etc
suites remain unrelated to this task.
2026-05-12 10:51:31 +00:00

64 lines
1.7 KiB
TypeScript

import { createServer } from "http";
import { Server as SocketIOServer } from "socket.io";
import type { IncomingMessage, ServerResponse } from "http";
import app, { sessionMiddleware } from "./app";
import { logger } from "./lib/logger";
const rawPort = process.env["PORT"];
if (!rawPort) {
throw new Error(
"PORT environment variable is required but was not provided.",
);
}
const port = Number(rawPort);
if (Number.isNaN(port) || port <= 0) {
throw new Error(`Invalid PORT value: "${rawPort}"`);
}
const httpServer = createServer(app);
export const io = new SocketIOServer(httpServer, {
path: "/api/socket.io",
cors: {
origin: process.env.ALLOWED_ORIGINS
? process.env.ALLOWED_ORIGINS.split(",").map((o) => o.trim())
: true,
methods: ["GET", "POST"],
credentials: true,
},
});
io.engine.use(
(req: IncomingMessage, res: ServerResponse, next: (err?: unknown) => void) => {
sessionMiddleware(req as Parameters<typeof sessionMiddleware>[0], res as Parameters<typeof sessionMiddleware>[1], next);
},
);
io.use((socket, next) => {
const req = socket.request as IncomingMessage & { session?: { userId?: number } };
const userId = req.session?.userId;
if (!userId) {
return next(new Error("Unauthorized: no session"));
}
socket.data.userId = userId;
next();
});
io.on("connection", (socket) => {
const userId = socket.data.userId as number;
logger.info({ socketId: socket.id, userId }, "Socket connected");
socket.join(`user:${userId}`);
socket.on("disconnect", () => {
logger.info({ socketId: socket.id }, "Socket disconnected");
});
});
httpServer.listen(port, () => {
logger.info({ port }, "Server listening");
});