6.5 KiB
Fchaty — الإصلاحات المطلوبة
ثلاث مشاكل أساسية تحتاج إصلاح. لكل مشكلة: الملف المعني، السطر، وصف المشكلة، والحل المطلوب.
Fix 1: حذف الرسائل المحلية عند فك الاقتران (unpair)
المشكلة: عند unpair() الرسائل القديمة تبقى محفوظة بملف messages.json المحلي. عند إعادة الاقتران مع شخص جديد، المحادثة القديمة تظهر.
الملف: FchatyApp/Sources/FchatyApp/Session/AppSession.swift
السطر: 115-124 — دالة unpair()
الكود الحالي:
func unpair() {
incomingMessagesTask?.cancel()
incomingMessagesTask = nil
KeychainStore.clearAll()
let webSocket = webSocket
Task {
await webSocket.disconnect()
}
state = .unpaired
}
المطلوب:
- إضافة دالة
deleteAll()فيMessageStoreتحذف ملفmessages.jsonمن الدسك. - استدعاء
deleteAll()ومسحmessagesarray فيunpair().
الملف الإضافي: FchatyApp/Sources/FchatyApp/Storage/MessageStore.swift
أضف هذه الدالة في MessageStore:
func deleteAll() throws {
let url = try messagesURL()
if fileManager.fileExists(atPath: url.path) {
try fileManager.removeItem(at: url)
}
}
وعدّل unpair() في AppSession.swift:
func unpair() {
incomingMessagesTask?.cancel()
incomingMessagesTask = nil
messages = []
Task {
try? await messageStore.deleteAll()
}
KeychainStore.clearAll()
let webSocket = webSocket
Task {
await webSocket.disconnect()
}
state = .unpaired
}
Fix 2: جعل WebSocket reconnect لانهائي
المشكلة: الـ reconnect يحاول 5 مرات فقط (2, 4, 8, 16, 32 ثانية) ثم يتوقف نهائياً بدون إبلاغ المستخدم. رفيقك يشوف loading لانهائي لأن التطبيق توقف عن المحاولة.
الملف: FchatyApp/Sources/FchatyApp/Networking/WSClient.swift
السطر: 243-273 — دالة reconnect()
الكود الحالي:
private func reconnect(using token: String, id: UUID) async {
let delays: [UInt64] = [2, 4, 8, 16, 32]
for delay in delays {
do {
try await Task.sleep(nanoseconds: delay * 1_000_000_000)
} catch {
return
}
guard reconnectID == id, !isDisconnecting else {
return
}
do {
try await establishConnection(token: token)
if reconnectID == id {
reconnectID = nil
reconnectTask = nil
}
return
} catch {
continue
}
}
if reconnectID == id {
reconnectID = nil
reconnectTask = nil
}
}
المطلوب: تغيير الدالة لتحاول بشكل لانهائي مع exponential backoff بحد أقصى 60 ثانية:
private func reconnect(using token: String, id: UUID) async {
var delay: UInt64 = 2
while !Task.isCancelled {
do {
try await Task.sleep(nanoseconds: delay * 1_000_000_000)
} catch {
return
}
guard reconnectID == id, !isDisconnecting else {
return
}
do {
try await establishConnection(token: token)
if reconnectID == id {
reconnectID = nil
reconnectTask = nil
}
return
} catch {
delay = min(delay * 2, 60)
continue
}
}
}
Fix 3: تحميل fileRegistry من الدسك عند بدء السيرفر
المشكلة: fileRegistry هو Map في الذاكرة فقط. بعد إعادة تشغيل السيرفر (deploy جديد مثلاً)، كل الملفات المرفوعة تصبح 404 رغم إنها موجودة على الدسك.
الملف: relay-server/src/index.js
السطر: 42 — تعريف fileRegistry
المطلوب: إضافة دالة تقرأ الملفات الموجودة بمجلد /data/files/ وتعبّي الـ fileRegistry عند بدء السيرفر.
أضف هذه الدالة بعد سطر 42 (const fileRegistry = new Map();):
function loadFileRegistryFromDisk() {
if (!fs.existsSync(UPLOADS_DIR)) return;
for (const entry of fs.readdirSync(UPLOADS_DIR, { withFileTypes: true })) {
if (!entry.isFile()) continue;
const diskPath = path.join(UPLOADS_DIR, entry.name);
try {
const stats = fs.statSync(diskPath);
fileRegistry.set(entry.name, {
diskPath,
originalName: entry.name, // الاسم الأصلي ضايع — نستخدم الـ UUID كفولباك
size: stats.size,
});
} catch (_) {}
}
}
loadFileRegistryFromDisk();
console.log(`[files] loaded ${fileRegistry.size} files from disk`);
ملاحظة مهمة: الاسم الأصلي للملف (originalName) لا يُحفظ على الدسك حالياً — multer يحفظ الملف باسم UUID فقط. هذا الإصلاح يسترجع الملفات لكن بدون أسمائها الأصلية. لحل كامل، يجب حفظ metadata الملف (اسمه الأصلي وحجمه) بملف .meta.json بجانب كل ملف عند الرفع. هذا تحسين إضافي وليس ضرورياً الآن.
ملخص سريع
| # | الملف | المشكلة | الأولوية |
|---|---|---|---|
| 1 | AppSession.swift + MessageStore.swift |
الرسائل القديمة تظهر بعد unpair | عالية |
| 2 | WSClient.swift |
الاتصال يفشل نهائياً بعد 5 محاولات | عالية |
| 3 | relay-server/src/index.js |
الملفات 404 بعد restart السيرفر | عالية |
الاختبارات
بعد تنفيذ الإصلاحات:
swift test --package-path FchatyApp— لازم كل الاختبارات تنجح- تأكد إنو
unpair()يمسح الرسائل — عمل pairing، أرسل رسائل، عمل unpair، تأكد إنو المحادثة فاضية - تأكد إنو الـ reconnect ما بيوقف — شغّل التطبيق، أوقف السيرفر، شغله بعد دقيقة، لازم يتصل تلقائياً
- تأكد إنو الملفات تتحمل — أرسل ملف، أعد تشغيل السيرفر، حاول حمّل الملف