# Fchaty — الإصلاحات المطلوبة ثلاث مشاكل أساسية تحتاج إصلاح. لكل مشكلة: الملف المعني، السطر، وصف المشكلة، والحل المطلوب. --- ## Fix 1: حذف الرسائل المحلية عند فك الاقتران (unpair) **المشكلة:** عند `unpair()` الرسائل القديمة تبقى محفوظة بملف `messages.json` المحلي. عند إعادة الاقتران مع شخص جديد، المحادثة القديمة تظهر. **الملف:** `FchatyApp/Sources/FchatyApp/Session/AppSession.swift` **السطر:** 115-124 — دالة `unpair()` **الكود الحالي:** ```swift func unpair() { incomingMessagesTask?.cancel() incomingMessagesTask = nil KeychainStore.clearAll() let webSocket = webSocket Task { await webSocket.disconnect() } state = .unpaired } ``` **المطلوب:** 1. إضافة دالة `deleteAll()` في `MessageStore` تحذف ملف `messages.json` من الدسك. 2. استدعاء `deleteAll()` ومسح `messages` array في `unpair()`. **الملف الإضافي:** `FchatyApp/Sources/FchatyApp/Storage/MessageStore.swift` أضف هذه الدالة في `MessageStore`: ```swift func deleteAll() throws { let url = try messagesURL() if fileManager.fileExists(atPath: url.path) { try fileManager.removeItem(at: url) } } ``` وعدّل `unpair()` في `AppSession.swift`: ```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()` **الكود الحالي:** ```swift 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 ثانية: ```swift 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();`): ```javascript 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 السيرفر | عالية | ## الاختبارات بعد تنفيذ الإصلاحات: 1. `swift test --package-path FchatyApp` — لازم كل الاختبارات تنجح 2. تأكد إنو `unpair()` يمسح الرسائل — عمل pairing، أرسل رسائل، عمل unpair، تأكد إنو المحادثة فاضية 3. تأكد إنو الـ reconnect ما بيوقف — شغّل التطبيق، أوقف السيرفر، شغله بعد دقيقة، لازم يتصل تلقائياً 4. تأكد إنو الملفات تتحمل — أرسل ملف، أعد تشغيل السيرفر، حاول حمّل الملف