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.
This commit is contained in:
@@ -197,14 +197,6 @@ Omitted from single-user responses (GET /users/:id, PATCH, etc).
|
||||
admin list endpoint (GET /users).
|
||||
*/
|
||||
orderCount?: number;
|
||||
/** Number of conversations created by this user. Populated only by the
|
||||
admin list endpoint (GET /users).
|
||||
*/
|
||||
conversationCount?: number;
|
||||
/** Number of messages authored by this user. Populated only by the
|
||||
admin list endpoint (GET /users).
|
||||
*/
|
||||
messageCount?: number;
|
||||
}
|
||||
|
||||
export interface UpdateUserBody {
|
||||
@@ -371,8 +363,6 @@ export interface UserDeletionConflict {
|
||||
error: string;
|
||||
noteCount: number;
|
||||
orderCount: number;
|
||||
conversationCount: number;
|
||||
messageCount: number;
|
||||
}
|
||||
|
||||
export interface AppDeletionConflict {
|
||||
@@ -643,96 +633,6 @@ export interface BulkDeleteServiceOrdersResponse {
|
||||
failedIds: number[];
|
||||
}
|
||||
|
||||
export interface ParticipantInfo {
|
||||
id: number;
|
||||
username: string;
|
||||
/** @nullable */
|
||||
displayNameAr?: string | null;
|
||||
/** @nullable */
|
||||
displayNameEn?: string | null;
|
||||
/** @nullable */
|
||||
avatarUrl?: string | null;
|
||||
isAdmin: boolean;
|
||||
}
|
||||
|
||||
export type MessageWithSenderKind =
|
||||
(typeof MessageWithSenderKind)[keyof typeof MessageWithSenderKind];
|
||||
|
||||
export const MessageWithSenderKind = {
|
||||
user: "user",
|
||||
group_renamed: "group_renamed",
|
||||
members_added: "members_added",
|
||||
member_removed: "member_removed",
|
||||
member_left: "member_left",
|
||||
admin_promoted: "admin_promoted",
|
||||
} as const;
|
||||
|
||||
export type MessageWithSenderMeta = { [key: string]: unknown } | null;
|
||||
|
||||
export interface MessageWithSender {
|
||||
id: number;
|
||||
conversationId: number;
|
||||
senderId: number;
|
||||
content: string;
|
||||
kind: MessageWithSenderKind;
|
||||
meta?: MessageWithSenderMeta;
|
||||
sender: ParticipantInfo;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface ConversationWithDetails {
|
||||
id: number;
|
||||
/** @nullable */
|
||||
nameAr?: string | null;
|
||||
/** @nullable */
|
||||
nameEn?: string | null;
|
||||
/** @nullable */
|
||||
avatarUrl?: string | null;
|
||||
isGroup: boolean;
|
||||
createdBy: number;
|
||||
participants: ParticipantInfo[];
|
||||
lastMessage?: MessageWithSender | null;
|
||||
unreadCount: number;
|
||||
isMuted: boolean;
|
||||
isArchived: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface CreateConversationBody {
|
||||
participantIds: number[];
|
||||
/** @nullable */
|
||||
nameAr?: string | null;
|
||||
/** @nullable */
|
||||
nameEn?: string | null;
|
||||
/** @nullable */
|
||||
avatarUrl?: string | null;
|
||||
isGroup?: boolean;
|
||||
}
|
||||
|
||||
export interface UpdateConversationBody {
|
||||
/** @nullable */
|
||||
avatarUrl?: string | null;
|
||||
/** @nullable */
|
||||
nameAr?: string | null;
|
||||
/** @nullable */
|
||||
nameEn?: string | null;
|
||||
}
|
||||
|
||||
export interface UpdateConversationStateBody {
|
||||
isMuted?: boolean;
|
||||
isArchived?: boolean;
|
||||
}
|
||||
|
||||
export interface AddParticipantsBody {
|
||||
userIds: number[];
|
||||
}
|
||||
|
||||
export interface SendMessageBody {
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface Notification {
|
||||
id: number;
|
||||
userId: number;
|
||||
@@ -808,7 +708,6 @@ export interface HomeStats {
|
||||
totalApps: number;
|
||||
totalServices: number;
|
||||
unreadNotifications: number;
|
||||
unreadMessages: number;
|
||||
totalUsers: number;
|
||||
}
|
||||
|
||||
@@ -1224,47 +1123,6 @@ export interface UserDependentOrdersPage {
|
||||
nextOffset: number | null;
|
||||
}
|
||||
|
||||
export interface UserDependentConversationItem {
|
||||
id: number;
|
||||
/** @nullable */
|
||||
nameAr: string | null;
|
||||
/** @nullable */
|
||||
nameEn: string | null;
|
||||
isGroup: boolean;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface UserDependentConversationsPage {
|
||||
items: UserDependentConversationItem[];
|
||||
totalCount: number;
|
||||
limit: number;
|
||||
offset: number;
|
||||
/** @nullable */
|
||||
nextOffset: number | null;
|
||||
}
|
||||
|
||||
export interface UserDependentMessageItem {
|
||||
id: number;
|
||||
content: string;
|
||||
kind: string;
|
||||
createdAt: string;
|
||||
conversationId: number;
|
||||
/** @nullable */
|
||||
conversationNameAr: string | null;
|
||||
/** @nullable */
|
||||
conversationNameEn: string | null;
|
||||
conversationIsGroup: boolean;
|
||||
}
|
||||
|
||||
export interface UserDependentMessagesPage {
|
||||
items: UserDependentMessageItem[];
|
||||
totalCount: number;
|
||||
limit: number;
|
||||
offset: number;
|
||||
/** @nullable */
|
||||
nextOffset: number | null;
|
||||
}
|
||||
|
||||
export interface AuditLogActor {
|
||||
id: number;
|
||||
username: string;
|
||||
@@ -1381,14 +1239,6 @@ export type DeleteServiceParams = {
|
||||
force?: boolean;
|
||||
};
|
||||
|
||||
export type LeaveConversationBody = {
|
||||
/** When the leaver is the only admin, optionally name a specific
|
||||
remaining member to promote. Omit (or send null) to keep the
|
||||
automatic behavior of promoting the longest-tenured member.
|
||||
*/
|
||||
successorId?: number | null;
|
||||
};
|
||||
|
||||
export type ListUsersParams = {
|
||||
/**
|
||||
* Free-text search across username, email, and display names
|
||||
@@ -1822,27 +1672,3 @@ export type GetAdminUserDependentOrdersParams = {
|
||||
*/
|
||||
offset?: number;
|
||||
};
|
||||
|
||||
export type GetAdminUserDependentConversationsParams = {
|
||||
/**
|
||||
* @minimum 1
|
||||
* @maximum 200
|
||||
*/
|
||||
limit?: number;
|
||||
/**
|
||||
* @minimum 0
|
||||
*/
|
||||
offset?: number;
|
||||
};
|
||||
|
||||
export type GetAdminUserDependentMessagesParams = {
|
||||
/**
|
||||
* @minimum 1
|
||||
* @maximum 200
|
||||
*/
|
||||
limit?: number;
|
||||
/**
|
||||
* @minimum 0
|
||||
*/
|
||||
offset?: number;
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user