INSERT IGNORE INTO categories(id,slug,sort_order) VALUES(1,'android',10);
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(1,'fr','Android');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(1,'ar','أندرويد');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(1,'en','Android');
INSERT IGNORE INTO categories(id,slug,sort_order) VALUES(2,'web',20);
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(2,'fr','Développement Web');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(2,'ar','تطوير الويب');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(2,'en','Web Development');
INSERT IGNORE INTO categories(id,slug,sort_order) VALUES(3,'automation',30);
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(3,'fr','Automatisation');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(3,'ar','الأتمتة');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(3,'en','Automation');
INSERT IGNORE INTO categories(id,slug,sort_order) VALUES(4,'data',40);
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(4,'fr','Data & SQL');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(4,'ar','البيانات و SQL');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(4,'en','Data & SQL');
INSERT IGNORE INTO categories(id,slug,sort_order) VALUES(5,'security',50);
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(5,'fr','Sécurité');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(5,'ar','الأمن');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(5,'en','Security');
INSERT IGNORE INTO categories(id,slug,sort_order) VALUES(6,'architecture',60);
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(6,'fr','Architecture');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(6,'ar','هندسة البرمجيات');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(6,'en','Architecture');
INSERT IGNORE INTO categories(id,slug,sort_order) VALUES(7,'tech',70);
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(7,'fr','Tech & Outils');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(7,'ar','التقنية والأدوات');
INSERT IGNORE INTO category_translations(category_id,locale,name) VALUES(7,'en','Tech & Tools');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(1,'android-offline-first',1,'assets/img/covers/android-offline-first.jpg','published',1,8,'2026-07-02 09:07:00','2026-07-02 09:07:00','2026-07-02 09:07:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(1,'fr','Android offline-first : construire une synchronisation fiable','Guide pratique sur sync locale/serveur, files d’attente, conflits et reprise, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Android offline-first : construire une synchronisation fiable » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est sync locale/serveur, files d’attente, conflits et reprise. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour sync locale/serveur, files d’attente, conflits et reprise, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>val state = repository.observe().stateIn(scope, SharingStarted.WhileSubscribed(5_000), UiState.Loading)</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Android offline-first : construire une synchronisation fiable, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour sync locale/serveur, files d’attente, conflits et reprise, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Android offline-first : construire une synchronisation fiable','Guide pratique sur sync locale/serveur, files d’attente, conflits et reprise, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(1,'ar','بناء تطبيق أندرويد يعمل دون اتصال مع مزامنة موثوقة','دليل عملي حول بناء تطبيق أندرويد يعمل دون اتصال مع مزامنة موثوقة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «بناء تطبيق أندرويد يعمل دون اتصال مع مزامنة موثوقة» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>val pending = repository.observePending()</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','بناء تطبيق أندرويد يعمل دون اتصال مع مزامنة موثوقة','دليل عملي حول بناء تطبيق أندرويد يعمل دون اتصال مع مزامنة موثوقة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(1,'en','Android offline-first: building reliable synchronization','A practical guide to android offline-first: building reliable synchronization, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Android offline-first: building reliable synchronization is worth discussing when it is tied to a concrete constraint. The focus here is Android. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>val pending = outbox.observePending().distinctUntilChanged()</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Android offline-first: building reliable synchronization','A practical guide to android offline-first: building reliable synchronization, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(2,'android-performance-field-app',1,'assets/img/covers/android-performance-field-app.jpg','published',1,9,'2026-07-03 09:14:00','2026-07-03 09:14:00','2026-07-03 09:14:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(2,'fr','Accélérer une application Android terrain sur smartphone et tablette','Guide pratique sur profilage, listes, mémoire, cartes et entrées clavier, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Accélérer une application Android terrain sur smartphone et tablette » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est profilage, listes, mémoire, cartes et entrées clavier. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour profilage, listes, mémoire, cartes et entrées clavier, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>val state = repository.observe().stateIn(scope, SharingStarted.WhileSubscribed(5_000), UiState.Loading)</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Accélérer une application Android terrain sur smartphone et tablette, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour profilage, listes, mémoire, cartes et entrées clavier, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Accélérer une application Android terrain sur smartphone et tablette','Guide pratique sur profilage, listes, mémoire, cartes et entrées clavier, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(2,'ar','تسريع تطبيق أندرويد ميداني على الهاتف واللوحي','دليل عملي حول تسريع تطبيق أندرويد ميداني على الهاتف واللوحي مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «تسريع تطبيق أندرويد ميداني على الهاتف واللوحي» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>val pending = repository.observePending()</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','تسريع تطبيق أندرويد ميداني على الهاتف واللوحي','دليل عملي حول تسريع تطبيق أندرويد ميداني على الهاتف واللوحي مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(2,'en','Speeding up a field Android app on phones and tablets','A practical guide to speeding up a field android app on phones and tablets, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Speeding up a field Android app on phones and tablets is worth discussing when it is tied to a concrete constraint. The focus here is Android. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>val pending = outbox.observePending().distinctUntilChanged()</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Speeding up a field Android app on phones and tablets','A practical guide to speeding up a field android app on phones and tablets, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(3,'android-search-architecture',1,'assets/img/covers/android-search-architecture.jpg','published',1,10,'2026-07-04 09:21:00','2026-07-04 09:21:00','2026-07-04 09:21:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(3,'fr','Concevoir une recherche Android qui affiche vraiment tous les résultats','Guide pratique sur index local, normalisation, ranking et filtres, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Concevoir une recherche Android qui affiche vraiment tous les résultats » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est index local, normalisation, ranking et filtres. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour index local, normalisation, ranking et filtres, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>val state = repository.observe().stateIn(scope, SharingStarted.WhileSubscribed(5_000), UiState.Loading)</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Concevoir une recherche Android qui affiche vraiment tous les résultats, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour index local, normalisation, ranking et filtres, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Concevoir une recherche Android qui affiche vraiment tous les résultats','Guide pratique sur index local, normalisation, ranking et filtres, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(3,'ar','تصميم بحث أندرويد يعرض كل النتائج فعلياً','دليل عملي حول تصميم بحث أندرويد يعرض كل النتائج فعلياً مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «تصميم بحث أندرويد يعرض كل النتائج فعلياً» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>val pending = repository.observePending()</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','تصميم بحث أندرويد يعرض كل النتائج فعلياً','دليل عملي حول تصميم بحث أندرويد يعرض كل النتائج فعلياً مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(3,'en','Designing Android search that actually returns every result','A practical guide to designing android search that actually returns every result, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Designing Android search that actually returns every result is worth discussing when it is tied to a concrete constraint. The focus here is Android. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>val pending = outbox.observePending().distinctUntilChanged()</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Designing Android search that actually returns every result','A practical guide to designing android search that actually returns every result, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(4,'android-keyboard-insets',1,'assets/img/covers/android-keyboard-insets.jpg','published',1,11,'2026-07-05 09:28:00','2026-07-05 09:28:00','2026-07-05 09:28:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(4,'fr','Clavier Android : éviter que l’IME masque les champs et les actions','Guide pratique sur WindowInsets, scroll et Compose/View, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Clavier Android : éviter que l’IME masque les champs et les actions » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est WindowInsets, scroll et Compose/View. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour WindowInsets, scroll et Compose/View, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>val state = repository.observe().stateIn(scope, SharingStarted.WhileSubscribed(5_000), UiState.Loading)</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Clavier Android : éviter que l’IME masque les champs et les actions, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour WindowInsets, scroll et Compose/View, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Clavier Android : éviter que l’IME masque les champs et les actions','Guide pratique sur WindowInsets, scroll et Compose/View, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(4,'ar','لوحة مفاتيح أندرويد: منعها من إخفاء الحقول والأزرار','دليل عملي حول لوحة مفاتيح أندرويد: منعها من إخفاء الحقول والأزرار مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «لوحة مفاتيح أندرويد: منعها من إخفاء الحقول والأزرار» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>val pending = repository.observePending()</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','لوحة مفاتيح أندرويد: منعها من إخفاء الحقول والأزرار','دليل عملي حول لوحة مفاتيح أندرويد: منعها من إخفاء الحقول والأزرار مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(4,'en','Android keyboard: keeping fields and actions above the IME','A practical guide to android keyboard: keeping fields and actions above the ime, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Android keyboard: keeping fields and actions above the IME is worth discussing when it is tied to a concrete constraint. The focus here is Android. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>val pending = outbox.observePending().distinctUntilChanged()</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Android keyboard: keeping fields and actions above the IME','A practical guide to android keyboard: keeping fields and actions above the ime, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(5,'android-map-large-data',1,'assets/img/covers/android-map-large-data.jpg','published',1,12,'2026-07-06 09:35:00','2026-07-06 09:35:00','2026-07-06 09:35:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(5,'fr','Cartes Android avec beaucoup de points : clusters, viewport et pagination','Guide pratique sur chargement par zone visible, clustering et cache, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Cartes Android avec beaucoup de points : clusters, viewport et pagination » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est chargement par zone visible, clustering et cache. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour chargement par zone visible, clustering et cache, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>val state = repository.observe().stateIn(scope, SharingStarted.WhileSubscribed(5_000), UiState.Loading)</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Cartes Android avec beaucoup de points : clusters, viewport et pagination, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour chargement par zone visible, clustering et cache, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Cartes Android avec beaucoup de points : clusters, viewport et pagination','Guide pratique sur chargement par zone visible, clustering et cache, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(5,'ar','خرائط أندرويد مع آلاف النقاط: التجميع ونطاق العرض','دليل عملي حول خرائط أندرويد مع آلاف النقاط: التجميع ونطاق العرض مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «خرائط أندرويد مع آلاف النقاط: التجميع ونطاق العرض» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>val pending = repository.observePending()</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','خرائط أندرويد مع آلاف النقاط: التجميع ونطاق العرض','دليل عملي حول خرائط أندرويد مع آلاف النقاط: التجميع ونطاق العرض مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(5,'en','Android maps with large datasets: clustering and viewport loading','A practical guide to android maps with large datasets: clustering and viewport loading, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Android maps with large datasets: clustering and viewport loading is worth discussing when it is tied to a concrete constraint. The focus here is Android. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>val pending = outbox.observePending().distinctUntilChanged()</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Android maps with large datasets: clustering and viewport loading','A practical guide to android maps with large datasets: clustering and viewport loading, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(6,'android-multilingual-rtl',1,'assets/img/covers/android-multilingual-rtl.jpg','published',1,13,'2026-07-07 09:42:00','2026-07-07 09:42:00','2026-07-07 09:42:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(6,'fr','FR, AR, EN sur Android : i18n, RTL et contenu métier','Guide pratique sur ressources, sens du layout et contenu partageable, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « FR, AR, EN sur Android : i18n, RTL et contenu métier » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est ressources, sens du layout et contenu partageable. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour ressources, sens du layout et contenu partageable, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>val state = repository.observe().stateIn(scope, SharingStarted.WhileSubscribed(5_000), UiState.Loading)</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur FR, AR, EN sur Android : i18n, RTL et contenu métier, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour ressources, sens du layout et contenu partageable, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','FR, AR, EN sur Android : i18n, RTL et contenu métier','Guide pratique sur ressources, sens du layout et contenu partageable, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(6,'ar','تطبيق أندرويد FR/AR/EN: الترجمة وRTL والمحتوى المهني','دليل عملي حول تطبيق أندرويد FR/AR/EN: الترجمة وRTL والمحتوى المهني مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «تطبيق أندرويد FR/AR/EN: الترجمة وRTL والمحتوى المهني» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>val pending = repository.observePending()</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','تطبيق أندرويد FR/AR/EN: الترجمة وRTL والمحتوى المهني','دليل عملي حول تطبيق أندرويد FR/AR/EN: الترجمة وRTL والمحتوى المهني مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(6,'en','FR/AR/EN Android apps: i18n, RTL and business content','A practical guide to fr/ar/en android apps: i18n, rtl and business content, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>FR/AR/EN Android apps: i18n, RTL and business content is worth discussing when it is tied to a concrete constraint. The focus here is Android. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>val pending = outbox.observePending().distinctUntilChanged()</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','FR/AR/EN Android apps: i18n, RTL and business content','A practical guide to fr/ar/en android apps: i18n, rtl and business content, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(7,'android-workmanager-sync',1,'assets/img/covers/android-workmanager-sync.jpg','published',0,14,'2026-07-08 09:49:00','2026-07-08 09:49:00','2026-07-08 09:49:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(7,'fr','WorkManager pour la synchronisation silencieuse sans bloquer l’UI','Guide pratique sur contraintes réseau, retry et idempotence, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « WorkManager pour la synchronisation silencieuse sans bloquer l’UI » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est contraintes réseau, retry et idempotence. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour contraintes réseau, retry et idempotence, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>val state = repository.observe().stateIn(scope, SharingStarted.WhileSubscribed(5_000), UiState.Loading)</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur WorkManager pour la synchronisation silencieuse sans bloquer l’UI, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour contraintes réseau, retry et idempotence, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','WorkManager pour la synchronisation silencieuse sans bloquer l’UI','Guide pratique sur contraintes réseau, retry et idempotence, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(7,'ar','WorkManager للمزامنة الصامتة دون تعطيل الواجهة','دليل عملي حول WorkManager للمزامنة الصامتة دون تعطيل الواجهة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «WorkManager للمزامنة الصامتة دون تعطيل الواجهة» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>val pending = repository.observePending()</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','WorkManager للمزامنة الصامتة دون تعطيل الواجهة','دليل عملي حول WorkManager للمزامنة الصامتة دون تعطيل الواجهة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(7,'en','WorkManager for silent sync without blocking the UI','A practical guide to workmanager for silent sync without blocking the ui, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>WorkManager for silent sync without blocking the UI is worth discussing when it is tied to a concrete constraint. The focus here is Android. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>val pending = outbox.observePending().distinctUntilChanged()</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','WorkManager for silent sync without blocking the UI','A practical guide to workmanager for silent sync without blocking the ui, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(8,'android-room-migrations',1,'assets/img/covers/android-room-migrations.jpg','published',0,7,'2026-07-09 09:56:00','2026-07-09 09:56:00','2026-07-09 09:56:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(8,'fr','Room : migrations de base sans perdre les données terrain','Guide pratique sur versions de schéma, migrations testées et rollback, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Room : migrations de base sans perdre les données terrain » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est versions de schéma, migrations testées et rollback. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour versions de schéma, migrations testées et rollback, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>val state = repository.observe().stateIn(scope, SharingStarted.WhileSubscribed(5_000), UiState.Loading)</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Room : migrations de base sans perdre les données terrain, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour versions de schéma, migrations testées et rollback, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Room : migrations de base sans perdre les données terrain','Guide pratique sur versions de schéma, migrations testées et rollback, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(8,'ar','Room: ترحيل قاعدة البيانات دون فقد بيانات الميدان','دليل عملي حول Room: ترحيل قاعدة البيانات دون فقد بيانات الميدان مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «Room: ترحيل قاعدة البيانات دون فقد بيانات الميدان» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>val pending = repository.observePending()</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','Room: ترحيل قاعدة البيانات دون فقد بيانات الميدان','دليل عملي حول Room: ترحيل قاعدة البيانات دون فقد بيانات الميدان مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(8,'en','Room migrations without losing field data','A practical guide to room migrations without losing field data, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Room migrations without losing field data is worth discussing when it is tied to a concrete constraint. The focus here is Android. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>val pending = outbox.observePending().distinctUntilChanged()</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Room migrations without losing field data','A practical guide to room migrations without losing field data, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(9,'php-mvc-shared-hosting',2,'assets/img/covers/php-mvc-shared-hosting.jpg','published',0,8,'2026-07-10 09:03:00','2026-07-10 09:03:00','2026-07-10 09:03:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(9,'fr','MVC PHP propre sur hébergement mutualisé sans framework lourd','Guide pratique sur front controller, routeur, services et sécurité, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « MVC PHP propre sur hébergement mutualisé sans framework lourd » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est front controller, routeur, services et sécurité. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour front controller, routeur, services et sécurité, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT * FROM items WHERE team_id = ? AND updated_at &gt; ?&#x27;);
$stmt-&gt;execute([$teamId, $cursor]);</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur MVC PHP propre sur hébergement mutualisé sans framework lourd, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour front controller, routeur, services et sécurité, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','MVC PHP propre sur hébergement mutualisé sans framework lourd','Guide pratique sur front controller, routeur, services et sécurité, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(9,'ar','MVC PHP نظيف على استضافة مشتركة بدون إطار ثقيل','دليل عملي حول MVC PHP نظيف على استضافة مشتركة بدون إطار ثقيل مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «MVC PHP نظيف على استضافة مشتركة بدون إطار ثقيل» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','MVC PHP نظيف على استضافة مشتركة بدون إطار ثقيل','دليل عملي حول MVC PHP نظيف على استضافة مشتركة بدون إطار ثقيل مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(9,'en','Clean PHP MVC on shared hosting without a heavy framework','A practical guide to clean php mvc on shared hosting without a heavy framework, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Clean PHP MVC on shared hosting without a heavy framework is worth discussing when it is tied to a concrete constraint. The focus here is web. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id, status FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Clean PHP MVC on shared hosting without a heavy framework','A practical guide to clean php mvc on shared hosting without a heavy framework, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(10,'php-rest-api-security',5,'assets/img/covers/php-rest-api-security.jpg','published',0,9,'2026-07-11 09:10:00','2026-07-11 09:10:00','2026-07-11 09:10:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(10,'fr','Sécuriser une API REST PHP pour une application mobile','Guide pratique sur authentification, quotas, validation et journaux, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Sécuriser une API REST PHP pour une application mobile » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est authentification, quotas, validation et journaux. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour authentification, quotas, validation et journaux, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT * FROM items WHERE team_id = ? AND updated_at &gt; ?&#x27;);
$stmt-&gt;execute([$teamId, $cursor]);</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Sécuriser une API REST PHP pour une application mobile, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour authentification, quotas, validation et journaux, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Sécuriser une API REST PHP pour une application mobile','Guide pratique sur authentification, quotas, validation et journaux, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(10,'ar','تأمين REST API بلغة PHP لتطبيق الهاتف','دليل عملي حول تأمين REST API بلغة PHP لتطبيق الهاتف مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «تأمين REST API بلغة PHP لتطبيق الهاتف» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','تأمين REST API بلغة PHP لتطبيق الهاتف','دليل عملي حول تأمين REST API بلغة PHP لتطبيق الهاتف مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(10,'en','Securing a PHP REST API for a mobile app','A practical guide to securing a php rest api for a mobile app, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Securing a PHP REST API for a mobile app is worth discussing when it is tied to a concrete constraint. The focus here is security. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id, status FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Securing a PHP REST API for a mobile app','A practical guide to securing a php rest api for a mobile app, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(11,'php-mysql-fast-queries',4,'assets/img/covers/php-mysql-fast-queries.jpg','published',0,10,'2026-07-12 09:17:00','2026-07-12 09:17:00','2026-07-12 09:17:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(11,'fr','MySQL : rendre les recherches rapides avec les bons index','Guide pratique sur EXPLAIN, index composites et pagination, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « MySQL : rendre les recherches rapides avec les bons index » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est EXPLAIN, index composites et pagination. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour EXPLAIN, index composites et pagination, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>EXPLAIN SELECT id, status, updated_at FROM jobs WHERE team_id = 12 AND status = &#x27;pending&#x27; ORDER BY updated_at DESC LIMIT 50;</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur MySQL : rendre les recherches rapides avec les bons index, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour EXPLAIN, index composites et pagination, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','MySQL : rendre les recherches rapides avec les bons index','Guide pratique sur EXPLAIN, index composites et pagination, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(11,'ar','MySQL: تسريع البحث باستخدام الفهارس المناسبة','دليل عملي حول MySQL: تسريع البحث باستخدام الفهارس المناسبة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «MySQL: تسريع البحث باستخدام الفهارس المناسبة» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>EXPLAIN SELECT id FROM jobs WHERE status=&#x27;pending&#x27;;</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','MySQL: تسريع البحث باستخدام الفهارس المناسبة','دليل عملي حول MySQL: تسريع البحث باستخدام الفهارس المناسبة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(11,'en','MySQL: making searches fast with the right indexes','A practical guide to mysql: making searches fast with the right indexes, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>MySQL: making searches fast with the right indexes is worth discussing when it is tied to a concrete constraint. The focus here is data. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>EXPLAIN SELECT id FROM jobs WHERE team_id=12 AND status=&#x27;pending&#x27;;</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','MySQL: making searches fast with the right indexes','A practical guide to mysql: making searches fast with the right indexes, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(12,'php-session-security',5,'assets/img/covers/php-session-security.jpg','published',0,11,'2026-07-13 09:24:00','2026-07-13 09:24:00','2026-07-13 09:24:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(12,'fr','Sessions PHP : cookies, rotation et protections essentielles','Guide pratique sur session fixation, CSRF et cookies sécurisés, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Sessions PHP : cookies, rotation et protections essentielles » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est session fixation, CSRF et cookies sécurisés. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour session fixation, CSRF et cookies sécurisés, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT * FROM items WHERE team_id = ? AND updated_at &gt; ?&#x27;);
$stmt-&gt;execute([$teamId, $cursor]);</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Sessions PHP : cookies, rotation et protections essentielles, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour session fixation, CSRF et cookies sécurisés, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Sessions PHP : cookies, rotation et protections essentielles','Guide pratique sur session fixation, CSRF et cookies sécurisés, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(12,'ar','جلسات PHP: الكوكيز والتدوير والحماية الأساسية','دليل عملي حول جلسات PHP: الكوكيز والتدوير والحماية الأساسية مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «جلسات PHP: الكوكيز والتدوير والحماية الأساسية» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','جلسات PHP: الكوكيز والتدوير والحماية الأساسية','دليل عملي حول جلسات PHP: الكوكيز والتدوير والحماية الأساسية مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(12,'en','PHP sessions: cookies, rotation and essential protections','A practical guide to php sessions: cookies, rotation and essential protections, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>PHP sessions: cookies, rotation and essential protections is worth discussing when it is tied to a concrete constraint. The focus here is security. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id, status FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','PHP sessions: cookies, rotation and essential protections','A practical guide to php sessions: cookies, rotation and essential protections, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(13,'php-cache-file',2,'assets/img/covers/php-cache-file.jpg','published',0,12,'2026-07-14 09:31:00','2026-07-14 09:31:00','2026-07-14 09:31:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(13,'fr','Cache fichier PHP : gagner en vitesse sans Redis','Guide pratique sur TTL, invalidation et concurrence, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Cache fichier PHP : gagner en vitesse sans Redis » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est TTL, invalidation et concurrence. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour TTL, invalidation et concurrence, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT * FROM items WHERE team_id = ? AND updated_at &gt; ?&#x27;);
$stmt-&gt;execute([$teamId, $cursor]);</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Cache fichier PHP : gagner en vitesse sans Redis, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour TTL, invalidation et concurrence, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Cache fichier PHP : gagner en vitesse sans Redis','Guide pratique sur TTL, invalidation et concurrence, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(13,'ar','تخزين مؤقت بالملفات في PHP دون Redis','دليل عملي حول تخزين مؤقت بالملفات في PHP دون Redis مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «تخزين مؤقت بالملفات في PHP دون Redis» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','تخزين مؤقت بالملفات في PHP دون Redis','دليل عملي حول تخزين مؤقت بالملفات في PHP دون Redis مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(13,'en','PHP file caching: speed without Redis','A practical guide to php file caching: speed without redis, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>PHP file caching: speed without Redis is worth discussing when it is tied to a concrete constraint. The focus here is web. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id, status FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','PHP file caching: speed without Redis','A practical guide to php file caching: speed without redis, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(14,'seo-multilingual-dev-blog',2,'assets/img/covers/seo-multilingual-dev-blog.jpg','published',0,13,'2026-07-15 09:38:00','2026-07-15 09:38:00','2026-07-15 09:38:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(14,'fr','SEO multilingue FR/AR/EN pour un blog de développeur','Guide pratique sur URLs, canonical, hreflang et contenu localisé, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « SEO multilingue FR/AR/EN pour un blog de développeur » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est URLs, canonical, hreflang et contenu localisé. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour URLs, canonical, hreflang et contenu localisé, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>&lt;link rel=&quot;alternate&quot; hreflang=&quot;fr&quot; href=&quot;https://example.com/fr/article&quot;&gt;</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur SEO multilingue FR/AR/EN pour un blog de développeur, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour URLs, canonical, hreflang et contenu localisé, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','SEO multilingue FR/AR/EN pour un blog de développeur','Guide pratique sur URLs, canonical, hreflang et contenu localisé, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(14,'ar','SEO متعدد اللغات لمدونة مطور FR/AR/EN','دليل عملي حول SEO متعدد اللغات لمدونة مطور FR/AR/EN مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «SEO متعدد اللغات لمدونة مطور FR/AR/EN» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>&lt;link rel=&quot;canonical&quot; href=&quot;https://example.com/ar/article&quot;&gt;</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','SEO متعدد اللغات لمدونة مطور FR/AR/EN','دليل عملي حول SEO متعدد اللغات لمدونة مطور FR/AR/EN مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(14,'en','Multilingual SEO for a developer blog in FR/AR/EN','A practical guide to multilingual seo for a developer blog in fr/ar/en, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Multilingual SEO for a developer blog in FR/AR/EN is worth discussing when it is tied to a concrete constraint. The focus here is web. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>&lt;link rel=&quot;canonical&quot; href=&quot;https://example.com/en/article&quot;&gt;</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Multilingual SEO for a developer blog in FR/AR/EN','A practical guide to multilingual seo for a developer blog in fr/ar/en, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(15,'schema-software-portfolio',2,'assets/img/covers/schema-software-portfolio.jpg','published',0,14,'2026-07-16 09:45:00','2026-07-16 09:45:00','2026-07-16 09:45:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(15,'fr','Données structurées pour présenter des applications et leurs versions','Guide pratique sur SoftwareApplication, BlogPosting et JSON-LD, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Données structurées pour présenter des applications et leurs versions » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est SoftwareApplication, BlogPosting et JSON-LD. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour SoftwareApplication, BlogPosting et JSON-LD, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>{
  &quot;type&quot;: &quot;event&quot;,
  &quot;version&quot;: 3,
  &quot;idempotency_key&quot;: &quot;device-42:operation-981&quot;
}</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Données structurées pour présenter des applications et leurs versions, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour SoftwareApplication, BlogPosting et JSON-LD, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Données structurées pour présenter des applications et leurs versions','Guide pratique sur SoftwareApplication, BlogPosting et JSON-LD, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(15,'ar','البيانات المنظمة لعرض التطبيقات وإصداراتها','دليل عملي حول البيانات المنظمة لعرض التطبيقات وإصداراتها مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «البيانات المنظمة لعرض التطبيقات وإصداراتها» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>{&quot;version&quot;:3,&quot;idempotency_key&quot;:&quot;device-42:981&quot;}</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','البيانات المنظمة لعرض التطبيقات وإصداراتها','دليل عملي حول البيانات المنظمة لعرض التطبيقات وإصداراتها مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(15,'en','Structured data for software projects and versions','A practical guide to structured data for software projects and versions, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Structured data for software projects and versions is worth discussing when it is tied to a concrete constraint. The focus here is web. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>{&quot;version&quot;:3,&quot;idempotency_key&quot;:&quot;device-42:981&quot;}</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Structured data for software projects and versions','A practical guide to structured data for software projects and versions, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(16,'rss-importer-editorial',2,'assets/img/covers/rss-importer-editorial.jpg','published',0,7,'2026-07-17 09:52:00','2026-07-17 09:52:00','2026-07-17 09:52:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(16,'fr','Importer des flux RSS sans transformer son blog en copie','Guide pratique sur déduplication, brouillons, attribution et valeur ajoutée, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Importer des flux RSS sans transformer son blog en copie » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est déduplication, brouillons, attribution et valeur ajoutée. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour déduplication, brouillons, attribution et valeur ajoutée, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT * FROM items WHERE team_id = ? AND updated_at &gt; ?&#x27;);
$stmt-&gt;execute([$teamId, $cursor]);</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Importer des flux RSS sans transformer son blog en copie, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour déduplication, brouillons, attribution et valeur ajoutée, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Importer des flux RSS sans transformer son blog en copie','Guide pratique sur déduplication, brouillons, attribution et valeur ajoutée, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(16,'ar','استيراد RSS دون تحويل المدونة إلى نسخة مكررة','دليل عملي حول استيراد RSS دون تحويل المدونة إلى نسخة مكررة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «استيراد RSS دون تحويل المدونة إلى نسخة مكررة» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','استيراد RSS دون تحويل المدونة إلى نسخة مكررة','دليل عملي حول استيراد RSS دون تحويل المدونة إلى نسخة مكررة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(16,'en','Importing RSS without turning your blog into a copy','A practical guide to importing rss without turning your blog into a copy, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Importing RSS without turning your blog into a copy is worth discussing when it is tied to a concrete constraint. The focus here is web. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id, status FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Importing RSS without turning your blog into a copy','A practical guide to importing rss without turning your blog into a copy, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(17,'seo-content-clusters',2,'assets/img/covers/seo-content-clusters.jpg','published',0,8,'2026-07-18 09:59:00','2026-07-18 09:59:00','2026-07-18 09:59:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(17,'fr','Construire des clusters de contenu techniques qui restent utiles','Guide pratique sur pillar pages, maillage interne et intention, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Construire des clusters de contenu techniques qui restent utiles » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est pillar pages, maillage interne et intention. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour pillar pages, maillage interne et intention, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>Décision → hypothèse → mesure → résultat → prochaine action.</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Construire des clusters de contenu techniques qui restent utiles, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour pillar pages, maillage interne et intention, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Construire des clusters de contenu techniques qui restent utiles','Guide pratique sur pillar pages, maillage interne et intention, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(17,'ar','بناء مجموعات محتوى تقنية تبقى مفيدة','دليل عملي حول بناء مجموعات محتوى تقنية تبقى مفيدة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «بناء مجموعات محتوى تقنية تبقى مفيدة» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>قرار ← فرضية ← قياس ← نتيجة</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','بناء مجموعات محتوى تقنية تبقى مفيدة','دليل عملي حول بناء مجموعات محتوى تقنية تبقى مفيدة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(17,'en','Building technical content clusters that remain useful','A practical guide to building technical content clusters that remain useful, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Building technical content clusters that remain useful is worth discussing when it is tied to a concrete constraint. The focus here is web. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>Decision -&gt; hypothesis -&gt; measurement -&gt; result.</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Building technical content clusters that remain useful','A practical guide to building technical content clusters that remain useful, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(18,'core-web-vitals-practical',2,'assets/img/covers/core-web-vitals-practical.jpg','published',0,9,'2026-07-19 09:06:00','2026-07-19 09:06:00','2026-07-19 09:06:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(18,'fr','Core Web Vitals : optimisations pratiques sans sur-ingénierie','Guide pratique sur images, JS, polices et rendu, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Core Web Vitals : optimisations pratiques sans sur-ingénierie » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est images, JS, polices et rendu. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour images, JS, polices et rendu, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>const controller = new AbortController();
fetch(&#x27;/api/search?q=&#x27; + encodeURIComponent(q), { signal: controller.signal });</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Core Web Vitals : optimisations pratiques sans sur-ingénierie, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour images, JS, polices et rendu, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Core Web Vitals : optimisations pratiques sans sur-ingénierie','Guide pratique sur images, JS, polices et rendu, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(18,'ar','Core Web Vitals: تحسينات عملية دون تعقيد','دليل عملي حول Core Web Vitals: تحسينات عملية دون تعقيد مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «Core Web Vitals: تحسينات عملية دون تعقيد» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>requestAnimationFrame(() =&gt; render(items));</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','Core Web Vitals: تحسينات عملية دون تعقيد','دليل عملي حول Core Web Vitals: تحسينات عملية دون تعقيد مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(18,'en','Core Web Vitals: practical optimization without overengineering','A practical guide to core web vitals: practical optimization without overengineering, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Core Web Vitals: practical optimization without overengineering is worth discussing when it is tied to a concrete constraint. The focus here is web. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>requestAnimationFrame(() =&gt; render(items));</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Core Web Vitals: practical optimization without overengineering','A practical guide to core web vitals: practical optimization without overengineering, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(19,'javascript-progressive-enhancement',2,'assets/img/covers/javascript-progressive-enhancement.jpg','published',0,10,'2026-07-20 09:13:00','2026-07-20 09:13:00','2026-07-20 09:13:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(19,'fr','JavaScript progressif : une interface moderne qui reste robuste','Guide pratique sur HTML d’abord, comportements ensuite, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « JavaScript progressif : une interface moderne qui reste robuste » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est HTML d’abord, comportements ensuite. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour HTML d’abord, comportements ensuite, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>const controller = new AbortController();
fetch(&#x27;/api/search?q=&#x27; + encodeURIComponent(q), { signal: controller.signal });</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur JavaScript progressif : une interface moderne qui reste robuste, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour HTML d’abord, comportements ensuite, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','JavaScript progressif : une interface moderne qui reste robuste','Guide pratique sur HTML d’abord, comportements ensuite, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(19,'ar','JavaScript تدريجي: واجهة حديثة وقوية','دليل عملي حول JavaScript تدريجي: واجهة حديثة وقوية مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «JavaScript تدريجي: واجهة حديثة وقوية» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>requestAnimationFrame(() =&gt; render(items));</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','JavaScript تدريجي: واجهة حديثة وقوية','دليل عملي حول JavaScript تدريجي: واجهة حديثة وقوية مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(19,'en','Progressive JavaScript: modern UI that stays robust','A practical guide to progressive javascript: modern ui that stays robust, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Progressive JavaScript: modern UI that stays robust is worth discussing when it is tied to a concrete constraint. The focus here is web. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>requestAnimationFrame(() =&gt; render(items));</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Progressive JavaScript: modern UI that stays robust','A practical guide to progressive javascript: modern ui that stays robust, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(20,'css-responsive-no-wasted-space',2,'assets/img/covers/css-responsive-no-wasted-space.jpg','published',0,11,'2026-07-21 09:20:00','2026-07-21 09:20:00','2026-07-21 09:20:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(20,'fr','Responsive CSS : supprimer l’espace perdu du mobile à la tablette','Guide pratique sur fluid type, grid, container queries et densité, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Responsive CSS : supprimer l’espace perdu du mobile à la tablette » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est fluid type, grid, container queries et densité. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour fluid type, grid, container queries et densité, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>.grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,18rem),1fr)); gap:clamp(.75rem,2vw,1.25rem); }</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Responsive CSS : supprimer l’espace perdu du mobile à la tablette, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour fluid type, grid, container queries et densité, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Responsive CSS : supprimer l’espace perdu du mobile à la tablette','Guide pratique sur fluid type, grid, container queries et densité, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(20,'ar','CSS متجاوب: إزالة المساحات الضائعة من الهاتف للوح','دليل عملي حول CSS متجاوب: إزالة المساحات الضائعة من الهاتف للوح مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «CSS متجاوب: إزالة المساحات الضائعة من الهاتف للوح» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>.grid { display:grid; gap:1rem; }</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','CSS متجاوب: إزالة المساحات الضائعة من الهاتف للوح','دليل عملي حول CSS متجاوب: إزالة المساحات الضائعة من الهاتف للوح مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(20,'en','Responsive CSS: removing wasted space from phone to tablet','A practical guide to responsive css: removing wasted space from phone to tablet, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Responsive CSS: removing wasted space from phone to tablet is worth discussing when it is tied to a concrete constraint. The focus here is web. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>.grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(18rem,1fr)); }</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Responsive CSS: removing wasted space from phone to tablet','A practical guide to responsive css: removing wasted space from phone to tablet, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(21,'rest-idempotency',6,'assets/img/covers/rest-idempotency.jpg','published',0,12,'2026-07-22 09:27:00','2026-07-22 09:27:00','2026-07-22 09:27:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(21,'fr','Idempotence REST : éviter doublons et créations multiples','Guide pratique sur clés d’idempotence, retry et journal, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Idempotence REST : éviter doublons et créations multiples » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est clés d’idempotence, retry et journal. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour clés d’idempotence, retry et journal, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>POST /api/v1/jobs HTTP/1.1
Idempotency-Key: device-42-job-981</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Idempotence REST : éviter doublons et créations multiples, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour clés d’idempotence, retry et journal, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Idempotence REST : éviter doublons et créations multiples','Guide pratique sur clés d’idempotence, retry et journal, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(21,'ar','Idempotence في REST لمنع التكرار','دليل عملي حول Idempotence في REST لمنع التكرار مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «Idempotence في REST لمنع التكرار» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>Idempotency-Key: device-42-job-981</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','Idempotence في REST لمنع التكرار','دليل عملي حول Idempotence في REST لمنع التكرار مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(21,'en','REST idempotency: preventing duplicate writes','A practical guide to rest idempotency: preventing duplicate writes, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>REST idempotency: preventing duplicate writes is worth discussing when it is tied to a concrete constraint. The focus here is architecture. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>Idempotency-Key: device-42-job-981</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','REST idempotency: preventing duplicate writes','A practical guide to rest idempotency: preventing duplicate writes, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(22,'sync-conflict-resolution',6,'assets/img/covers/sync-conflict-resolution.jpg','published',0,13,'2026-07-23 09:34:00','2026-07-23 09:34:00','2026-07-23 09:34:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(22,'fr','Résoudre les conflits de synchronisation sans perdre le travail utilisateur','Guide pratique sur versions, horodatage, merge métier, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Résoudre les conflits de synchronisation sans perdre le travail utilisateur » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est versions, horodatage, merge métier. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour versions, horodatage, merge métier, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>Décision → hypothèse → mesure → résultat → prochaine action.</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Résoudre les conflits de synchronisation sans perdre le travail utilisateur, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour versions, horodatage, merge métier, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Résoudre les conflits de synchronisation sans perdre le travail utilisateur','Guide pratique sur versions, horodatage, merge métier, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(22,'ar','حل تعارضات المزامنة دون فقد عمل المستخدم','دليل عملي حول حل تعارضات المزامنة دون فقد عمل المستخدم مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «حل تعارضات المزامنة دون فقد عمل المستخدم» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>قرار ← فرضية ← قياس ← نتيجة</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','حل تعارضات المزامنة دون فقد عمل المستخدم','دليل عملي حول حل تعارضات المزامنة دون فقد عمل المستخدم مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(22,'en','Resolving sync conflicts without losing user work','A practical guide to resolving sync conflicts without losing user work, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Resolving sync conflicts without losing user work is worth discussing when it is tied to a concrete constraint. The focus here is architecture. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>Decision -&gt; hypothesis -&gt; measurement -&gt; result.</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Resolving sync conflicts without losing user work','A practical guide to resolving sync conflicts without losing user work, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(23,'audit-log-design',6,'assets/img/covers/audit-log-design.jpg','published',0,14,'2026-07-24 09:41:00','2026-07-24 09:41:00','2026-07-24 09:41:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(23,'fr','Concevoir un journal d’audit exploitable par un manager','Guide pratique sur qui, quoi, quand, avant/après et recherche, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Concevoir un journal d’audit exploitable par un manager » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est qui, quoi, quand, avant/après et recherche. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour qui, quoi, quand, avant/après et recherche, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>EXPLAIN SELECT id, status, updated_at FROM jobs WHERE team_id = 12 AND status = &#x27;pending&#x27; ORDER BY updated_at DESC LIMIT 50;</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Concevoir un journal d’audit exploitable par un manager, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour qui, quoi, quand, avant/après et recherche, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Concevoir un journal d’audit exploitable par un manager','Guide pratique sur qui, quoi, quand, avant/après et recherche, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(23,'ar','تصميم سجل تدقيق مفيد للمدير','دليل عملي حول تصميم سجل تدقيق مفيد للمدير مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «تصميم سجل تدقيق مفيد للمدير» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>EXPLAIN SELECT id FROM jobs WHERE status=&#x27;pending&#x27;;</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','تصميم سجل تدقيق مفيد للمدير','دليل عملي حول تصميم سجل تدقيق مفيد للمدير مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(23,'en','Designing an audit log a manager can actually use','A practical guide to designing an audit log a manager can actually use, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Designing an audit log a manager can actually use is worth discussing when it is tied to a concrete constraint. The focus here is architecture. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>EXPLAIN SELECT id FROM jobs WHERE team_id=12 AND status=&#x27;pending&#x27;;</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Designing an audit log a manager can actually use','A practical guide to designing an audit log a manager can actually use, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(24,'rbac-multi-team',5,'assets/img/covers/rbac-multi-team.jpg','published',0,7,'2026-07-25 09:48:00','2026-07-25 09:48:00','2026-07-25 09:48:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(24,'fr','RBAC multi-équipe : rôles, permissions et périmètres de données','Guide pratique sur roles, permissions, scopes et héritage, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « RBAC multi-équipe : rôles, permissions et périmètres de données » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est roles, permissions, scopes et héritage. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour roles, permissions, scopes et héritage, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>EXPLAIN SELECT id, status, updated_at FROM jobs WHERE team_id = 12 AND status = &#x27;pending&#x27; ORDER BY updated_at DESC LIMIT 50;</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur RBAC multi-équipe : rôles, permissions et périmètres de données, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour roles, permissions, scopes et héritage, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','RBAC multi-équipe : rôles, permissions et périmètres de données','Guide pratique sur roles, permissions, scopes et héritage, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(24,'ar','RBAC لفرق متعددة: الأدوار والصلاحيات ونطاق البيانات','دليل عملي حول RBAC لفرق متعددة: الأدوار والصلاحيات ونطاق البيانات مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «RBAC لفرق متعددة: الأدوار والصلاحيات ونطاق البيانات» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>EXPLAIN SELECT id FROM jobs WHERE status=&#x27;pending&#x27;;</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','RBAC لفرق متعددة: الأدوار والصلاحيات ونطاق البيانات','دليل عملي حول RBAC لفرق متعددة: الأدوار والصلاحيات ونطاق البيانات مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(24,'en','Multi-team RBAC: roles, permissions and data scopes','A practical guide to multi-team rbac: roles, permissions and data scopes, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Multi-team RBAC: roles, permissions and data scopes is worth discussing when it is tied to a concrete constraint. The focus here is security. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>EXPLAIN SELECT id FROM jobs WHERE team_id=12 AND status=&#x27;pending&#x27;;</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Multi-team RBAC: roles, permissions and data scopes','A practical guide to multi-team rbac: roles, permissions and data scopes, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(25,'secure-file-upload',5,'assets/img/covers/secure-file-upload.jpg','published',0,8,'2026-07-26 09:55:00','2026-07-26 09:55:00','2026-07-26 09:55:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(25,'fr','Upload de fichiers : validation, stockage et sécurité côté serveur','Guide pratique sur MIME, taille, noms, accès et antivirus, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Upload de fichiers : validation, stockage et sécurité côté serveur » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est MIME, taille, noms, accès et antivirus. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour MIME, taille, noms, accès et antivirus, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT * FROM items WHERE team_id = ? AND updated_at &gt; ?&#x27;);
$stmt-&gt;execute([$teamId, $cursor]);</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Upload de fichiers : validation, stockage et sécurité côté serveur, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour MIME, taille, noms, accès et antivirus, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Upload de fichiers : validation, stockage et sécurité côté serveur','Guide pratique sur MIME, taille, noms, accès et antivirus, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(25,'ar','رفع الملفات بأمان: التحقق والتخزين','دليل عملي حول رفع الملفات بأمان: التحقق والتخزين مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «رفع الملفات بأمان: التحقق والتخزين» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','رفع الملفات بأمان: التحقق والتخزين','دليل عملي حول رفع الملفات بأمان: التحقق والتخزين مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(25,'en','Secure file uploads: validation, storage and server-side safety','A practical guide to secure file uploads: validation, storage and server-side safety, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Secure file uploads: validation, storage and server-side safety is worth discussing when it is tied to a concrete constraint. The focus here is security. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id, status FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Secure file uploads: validation, storage and server-side safety','A practical guide to secure file uploads: validation, storage and server-side safety, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(26,'api-pagination',6,'assets/img/covers/api-pagination.jpg','published',0,9,'2026-07-27 09:02:00','2026-07-27 09:02:00','2026-07-27 09:02:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(26,'fr','Pagination d’API : offset, cursor et gros volumes','Guide pratique sur latence, tri stable et cohérence, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Pagination d’API : offset, cursor et gros volumes » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est latence, tri stable et cohérence. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour latence, tri stable et cohérence, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>POST /api/v1/jobs HTTP/1.1
Idempotency-Key: device-42-job-981</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Pagination d’API : offset, cursor et gros volumes, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour latence, tri stable et cohérence, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Pagination d’API : offset, cursor et gros volumes','Guide pratique sur latence, tri stable et cohérence, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(26,'ar','ترقيم صفحات API: offset وcursor والبيانات الكبيرة','دليل عملي حول ترقيم صفحات API: offset وcursor والبيانات الكبيرة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «ترقيم صفحات API: offset وcursor والبيانات الكبيرة» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>Idempotency-Key: device-42-job-981</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','ترقيم صفحات API: offset وcursor والبيانات الكبيرة','دليل عملي حول ترقيم صفحات API: offset وcursor والبيانات الكبيرة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(26,'en','API pagination: offset, cursors and large datasets','A practical guide to api pagination: offset, cursors and large datasets, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>API pagination: offset, cursors and large datasets is worth discussing when it is tied to a concrete constraint. The focus here is architecture. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>Idempotency-Key: device-42-job-981</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','API pagination: offset, cursors and large datasets','A practical guide to api pagination: offset, cursors and large datasets, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(27,'database-zero-loss-sync',4,'assets/img/covers/database-zero-loss-sync.jpg','published',0,10,'2026-07-28 09:09:00','2026-07-28 09:09:00','2026-07-28 09:09:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(27,'fr','Base locale + serveur : viser zéro perte de données','Guide pratique sur outbox, ack, retry, tombstones, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Base locale + serveur : viser zéro perte de données » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est outbox, ack, retry, tombstones. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour outbox, ack, retry, tombstones, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>EXPLAIN SELECT id, status, updated_at FROM jobs WHERE team_id = 12 AND status = &#x27;pending&#x27; ORDER BY updated_at DESC LIMIT 50;</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Base locale + serveur : viser zéro perte de données, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour outbox, ack, retry, tombstones, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Base locale + serveur : viser zéro perte de données','Guide pratique sur outbox, ack, retry, tombstones, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(27,'ar','قاعدة محلية وخادم: تصميم لتقليل فقد البيانات','دليل عملي حول قاعدة محلية وخادم: تصميم لتقليل فقد البيانات مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «قاعدة محلية وخادم: تصميم لتقليل فقد البيانات» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>EXPLAIN SELECT id FROM jobs WHERE status=&#x27;pending&#x27;;</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','قاعدة محلية وخادم: تصميم لتقليل فقد البيانات','دليل عملي حول قاعدة محلية وخادم: تصميم لتقليل فقد البيانات مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(27,'en','Local + server databases: designing for near-zero data loss','A practical guide to local + server databases: designing for near-zero data loss, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Local + server databases: designing for near-zero data loss is worth discussing when it is tied to a concrete constraint. The focus here is data. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>EXPLAIN SELECT id FROM jobs WHERE team_id=12 AND status=&#x27;pending&#x27;;</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Local + server databases: designing for near-zero data loss','A practical guide to local + server databases: designing for near-zero data loss, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(28,'sql-explain-field-guide',4,'assets/img/covers/sql-explain-field-guide.jpg','published',0,11,'2026-07-01 09:16:00','2026-07-01 09:16:00','2026-07-01 09:16:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(28,'fr','Lire EXPLAIN MySQL comme un outil de diagnostic','Guide pratique sur type, key, rows et filesort, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Lire EXPLAIN MySQL comme un outil de diagnostic » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est type, key, rows et filesort. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour type, key, rows et filesort, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>EXPLAIN SELECT id, status, updated_at FROM jobs WHERE team_id = 12 AND status = &#x27;pending&#x27; ORDER BY updated_at DESC LIMIT 50;</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Lire EXPLAIN MySQL comme un outil de diagnostic, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour type, key, rows et filesort, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Lire EXPLAIN MySQL comme un outil de diagnostic','Guide pratique sur type, key, rows et filesort, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(28,'ar','قراءة EXPLAIN في MySQL كأداة تشخيص','دليل عملي حول قراءة EXPLAIN في MySQL كأداة تشخيص مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «قراءة EXPLAIN في MySQL كأداة تشخيص» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>EXPLAIN SELECT id FROM jobs WHERE status=&#x27;pending&#x27;;</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','قراءة EXPLAIN في MySQL كأداة تشخيص','دليل عملي حول قراءة EXPLAIN في MySQL كأداة تشخيص مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(28,'en','Reading MySQL EXPLAIN as a diagnostic tool','A practical guide to reading mysql explain as a diagnostic tool, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Reading MySQL EXPLAIN as a diagnostic tool is worth discussing when it is tied to a concrete constraint. The focus here is data. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>EXPLAIN SELECT id FROM jobs WHERE team_id=12 AND status=&#x27;pending&#x27;;</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Reading MySQL EXPLAIN as a diagnostic tool','A practical guide to reading mysql explain as a diagnostic tool, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(29,'excel-vba-robot-architecture',3,'assets/img/covers/excel-vba-robot-architecture.jpg','published',0,12,'2026-06-02 09:23:00','2026-06-02 09:23:00','2026-06-02 09:23:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(29,'fr','Robot Excel/VBA : passer du macro-script à une architecture fiable','Guide pratique sur queues, workers, logs, locks et reprise, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Robot Excel/VBA : passer du macro-script à une architecture fiable » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est queues, workers, logs, locks et reprise. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour queues, workers, logs, locks et reprise, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>If JobExists(entryId) Then Exit Sub
Call LockJob(entryId)
On Error GoTo Fail</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Robot Excel/VBA : passer du macro-script à une architecture fiable, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour queues, workers, logs, locks et reprise, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Robot Excel/VBA : passer du macro-script à une architecture fiable','Guide pratique sur queues, workers, logs, locks et reprise, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(29,'ar','روبوت Excel/VBA: من ماكرو بسيط إلى بنية موثوقة','دليل عملي حول روبوت Excel/VBA: من ماكرو بسيط إلى بنية موثوقة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «روبوت Excel/VBA: من ماكرو بسيط إلى بنية موثوقة» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>If JobExists(entryId) Then Exit Sub</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','روبوت Excel/VBA: من ماكرو بسيط إلى بنية موثوقة','دليل عملي حول روبوت Excel/VBA: من ماكرو بسيط إلى بنية موثوقة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(29,'en','Excel/VBA automation: from macro script to reliable architecture','A practical guide to excel/vba automation: from macro script to reliable architecture, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Excel/VBA automation: from macro script to reliable architecture is worth discussing when it is tied to a concrete constraint. The focus here is automation. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>If JobExists(entryId) Then Exit Sub</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Excel/VBA automation: from macro script to reliable architecture','A practical guide to excel/vba automation: from macro script to reliable architecture, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(30,'outlook-vba-safe-processing',3,'assets/img/covers/outlook-vba-safe-processing.jpg','published',0,13,'2026-06-03 09:30:00','2026-06-03 09:30:00','2026-06-03 09:30:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(30,'fr','Automatiser Outlook sans retraiter deux fois le même email','Guide pratique sur identifiants, verrouillage et état, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Automatiser Outlook sans retraiter deux fois le même email » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est identifiants, verrouillage et état. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour identifiants, verrouillage et état, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>If JobExists(entryId) Then Exit Sub
Call LockJob(entryId)
On Error GoTo Fail</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Automatiser Outlook sans retraiter deux fois le même email, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour identifiants, verrouillage et état, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Automatiser Outlook sans retraiter deux fois le même email','Guide pratique sur identifiants, verrouillage et état, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(30,'ar','أتمتة Outlook دون معالجة نفس البريد مرتين','دليل عملي حول أتمتة Outlook دون معالجة نفس البريد مرتين مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «أتمتة Outlook دون معالجة نفس البريد مرتين» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>If JobExists(entryId) Then Exit Sub</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','أتمتة Outlook دون معالجة نفس البريد مرتين','دليل عملي حول أتمتة Outlook دون معالجة نفس البريد مرتين مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(30,'en','Automating Outlook without processing the same email twice','A practical guide to automating outlook without processing the same email twice, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Automating Outlook without processing the same email twice is worth discussing when it is tied to a concrete constraint. The focus here is automation. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>If JobExists(entryId) Then Exit Sub</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Automating Outlook without processing the same email twice','A practical guide to automating outlook without processing the same email twice, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(31,'vba-error-observability',3,'assets/img/covers/vba-error-observability.jpg','published',0,14,'2026-06-04 09:37:00','2026-06-04 09:37:00','2026-06-04 09:37:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(31,'fr','VBA : journaliser les erreurs sans polluer l’utilisateur','Guide pratique sur logs structurés, niveaux et support, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « VBA : journaliser les erreurs sans polluer l’utilisateur » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est logs structurés, niveaux et support. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour logs structurés, niveaux et support, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>If JobExists(entryId) Then Exit Sub
Call LockJob(entryId)
On Error GoTo Fail</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur VBA : journaliser les erreurs sans polluer l’utilisateur, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour logs structurés, niveaux et support, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','VBA : journaliser les erreurs sans polluer l’utilisateur','Guide pratique sur logs structurés, niveaux et support, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(31,'ar','VBA: تسجيل الأخطاء دون إزعاج المستخدم','دليل عملي حول VBA: تسجيل الأخطاء دون إزعاج المستخدم مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «VBA: تسجيل الأخطاء دون إزعاج المستخدم» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>If JobExists(entryId) Then Exit Sub</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','VBA: تسجيل الأخطاء دون إزعاج المستخدم','دليل عملي حول VBA: تسجيل الأخطاء دون إزعاج المستخدم مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(31,'en','VBA error logging without bothering the user','A practical guide to vba error logging without bothering the user, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>VBA error logging without bothering the user is worth discussing when it is tied to a concrete constraint. The focus here is automation. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>If JobExists(entryId) Then Exit Sub</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','VBA error logging without bothering the user','A practical guide to vba error logging without bothering the user, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(32,'automation-job-queue',3,'assets/img/covers/automation-job-queue.jpg','published',0,7,'2026-06-05 09:44:00','2026-06-05 09:44:00','2026-06-05 09:44:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(32,'fr','Créer une file de jobs simple pour des robots bureautiques','Guide pratique sur états, workers et reprise après incident, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Créer une file de jobs simple pour des robots bureautiques » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est états, workers et reprise après incident. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour états, workers et reprise après incident, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>EXPLAIN SELECT id, status, updated_at FROM jobs WHERE team_id = 12 AND status = &#x27;pending&#x27; ORDER BY updated_at DESC LIMIT 50;</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Créer une file de jobs simple pour des robots bureautiques, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour états, workers et reprise après incident, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Créer une file de jobs simple pour des robots bureautiques','Guide pratique sur états, workers et reprise après incident, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(32,'ar','إنشاء طابور مهام بسيط لروبوتات المكتب','دليل عملي حول إنشاء طابور مهام بسيط لروبوتات المكتب مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «إنشاء طابور مهام بسيط لروبوتات المكتب» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>EXPLAIN SELECT id FROM jobs WHERE status=&#x27;pending&#x27;;</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','إنشاء طابور مهام بسيط لروبوتات المكتب','دليل عملي حول إنشاء طابور مهام بسيط لروبوتات المكتب مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(32,'en','Building a simple job queue for desktop automation','A practical guide to building a simple job queue for desktop automation, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Building a simple job queue for desktop automation is worth discussing when it is tied to a concrete constraint. The focus here is automation. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>EXPLAIN SELECT id FROM jobs WHERE team_id=12 AND status=&#x27;pending&#x27;;</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Building a simple job queue for desktop automation','A practical guide to building a simple job queue for desktop automation, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(33,'barcode-scanning-android',1,'assets/img/covers/barcode-scanning-android.jpg','published',0,8,'2026-06-06 09:51:00','2026-06-06 09:51:00','2026-06-06 09:51:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(33,'fr','Scanner code-barres Android : pipeline fiable après la lecture','Guide pratique sur normalisation, validation et feedback, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Scanner code-barres Android : pipeline fiable après la lecture » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est normalisation, validation et feedback. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour normalisation, validation et feedback, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>val state = repository.observe().stateIn(scope, SharingStarted.WhileSubscribed(5_000), UiState.Loading)</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Scanner code-barres Android : pipeline fiable après la lecture, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour normalisation, validation et feedback, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Scanner code-barres Android : pipeline fiable après la lecture','Guide pratique sur normalisation, validation et feedback, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(33,'ar','مسح الباركود في أندرويد: معالجة موثوقة بعد القراءة','دليل عملي حول مسح الباركود في أندرويد: معالجة موثوقة بعد القراءة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «مسح الباركود في أندرويد: معالجة موثوقة بعد القراءة» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>val pending = repository.observePending()</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','مسح الباركود في أندرويد: معالجة موثوقة بعد القراءة','دليل عملي حول مسح الباركود في أندرويد: معالجة موثوقة بعد القراءة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(33,'en','Android barcode scanning: a reliable post-scan pipeline','A practical guide to android barcode scanning: a reliable post-scan pipeline, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Android barcode scanning: a reliable post-scan pipeline is worth discussing when it is tied to a concrete constraint. The focus here is Android. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>val pending = outbox.observePending().distinctUntilChanged()</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Android barcode scanning: a reliable post-scan pipeline','A practical guide to android barcode scanning: a reliable post-scan pipeline, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(34,'gps-reverse-geocoding',1,'assets/img/covers/gps-reverse-geocoding.jpg','published',0,9,'2026-06-07 09:58:00','2026-06-07 09:58:00','2026-06-07 09:58:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(34,'fr','GPS et reverse geocoding : remplir ville et quartier intelligemment','Guide pratique sur permissions, cache et fallback, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « GPS et reverse geocoding : remplir ville et quartier intelligemment » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est permissions, cache et fallback. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour permissions, cache et fallback, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>val state = repository.observe().stateIn(scope, SharingStarted.WhileSubscribed(5_000), UiState.Loading)</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur GPS et reverse geocoding : remplir ville et quartier intelligemment, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour permissions, cache et fallback, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','GPS et reverse geocoding : remplir ville et quartier intelligemment','Guide pratique sur permissions, cache et fallback, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(34,'ar','GPS والترميز الجغرافي العكسي لملء المدينة والحي','دليل عملي حول GPS والترميز الجغرافي العكسي لملء المدينة والحي مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «GPS والترميز الجغرافي العكسي لملء المدينة والحي» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>val pending = repository.observePending()</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','GPS والترميز الجغرافي العكسي لملء المدينة والحي','دليل عملي حول GPS والترميز الجغرافي العكسي لملء المدينة والحي مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(34,'en','GPS and reverse geocoding for smart city/neighborhood filling','A practical guide to gps and reverse geocoding for smart city/neighborhood filling, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>GPS and reverse geocoding for smart city/neighborhood filling is worth discussing when it is tied to a concrete constraint. The focus here is Android. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>val pending = outbox.observePending().distinctUntilChanged()</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','GPS and reverse geocoding for smart city/neighborhood filling','A practical guide to gps and reverse geocoding for smart city/neighborhood filling, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(35,'notifications-routing',6,'assets/img/covers/notifications-routing.jpg','published',0,10,'2026-06-08 09:05:00','2026-06-08 09:05:00','2026-06-08 09:05:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(35,'fr','Notifications métier : informer la bonne personne au bon moment','Guide pratique sur événements, destinataires, priorités et accusés, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Notifications métier : informer la bonne personne au bon moment » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est événements, destinataires, priorités et accusés. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour événements, destinataires, priorités et accusés, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>Décision → hypothèse → mesure → résultat → prochaine action.</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Notifications métier : informer la bonne personne au bon moment, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour événements, destinataires, priorités et accusés, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Notifications métier : informer la bonne personne au bon moment','Guide pratique sur événements, destinataires, priorités et accusés, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(35,'ar','الإشعارات المهنية: الشخص الصحيح في الوقت الصحيح','دليل عملي حول الإشعارات المهنية: الشخص الصحيح في الوقت الصحيح مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «الإشعارات المهنية: الشخص الصحيح في الوقت الصحيح» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>قرار ← فرضية ← قياس ← نتيجة</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','الإشعارات المهنية: الشخص الصحيح في الوقت الصحيح','دليل عملي حول الإشعارات المهنية: الشخص الصحيح في الوقت الصحيح مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(35,'en','Business notifications: the right person at the right time','A practical guide to business notifications: the right person at the right time, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Business notifications: the right person at the right time is worth discussing when it is tied to a concrete constraint. The focus here is architecture. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>Decision -&gt; hypothesis -&gt; measurement -&gt; result.</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Business notifications: the right person at the right time','A practical guide to business notifications: the right person at the right time, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(36,'dashboard-decision-design',6,'assets/img/covers/dashboard-decision-design.jpg','published',0,11,'2026-06-09 09:12:00','2026-06-09 09:12:00','2026-06-09 09:12:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(36,'fr','Dashboard manager : concevoir pour décider, pas pour décorer','Guide pratique sur KPI, exceptions, drill-down et carte, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Dashboard manager : concevoir pour décider, pas pour décorer » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est KPI, exceptions, drill-down et carte. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour KPI, exceptions, drill-down et carte, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>Décision → hypothèse → mesure → résultat → prochaine action.</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Dashboard manager : concevoir pour décider, pas pour décorer, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour KPI, exceptions, drill-down et carte, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Dashboard manager : concevoir pour décider, pas pour décorer','Guide pratique sur KPI, exceptions, drill-down et carte, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(36,'ar','لوحة المدير: صمم لاتخاذ القرار لا للزينة','دليل عملي حول لوحة المدير: صمم لاتخاذ القرار لا للزينة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «لوحة المدير: صمم لاتخاذ القرار لا للزينة» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>قرار ← فرضية ← قياس ← نتيجة</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','لوحة المدير: صمم لاتخاذ القرار لا للزينة','دليل عملي حول لوحة المدير: صمم لاتخاذ القرار لا للزينة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(36,'en','Manager dashboards: design for decisions, not decoration','A practical guide to manager dashboards: design for decisions, not decoration, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Manager dashboards: design for decisions, not decoration is worth discussing when it is tied to a concrete constraint. The focus here is architecture. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>Decision -&gt; hypothesis -&gt; measurement -&gt; result.</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Manager dashboards: design for decisions, not decoration','A practical guide to manager dashboards: design for decisions, not decoration, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(37,'http-https-config',2,'assets/img/covers/http-https-config.jpg','published',0,12,'2026-06-10 09:19:00','2026-06-10 09:19:00','2026-06-10 09:19:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(37,'fr','HTTP/HTTPS : configuration propre sans URLs codées en dur','Guide pratique sur base URL, proxy headers et redirections, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « HTTP/HTTPS : configuration propre sans URLs codées en dur » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est base URL, proxy headers et redirections. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour base URL, proxy headers et redirections, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT * FROM items WHERE team_id = ? AND updated_at &gt; ?&#x27;);
$stmt-&gt;execute([$teamId, $cursor]);</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur HTTP/HTTPS : configuration propre sans URLs codées en dur, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour base URL, proxy headers et redirections, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','HTTP/HTTPS : configuration propre sans URLs codées en dur','Guide pratique sur base URL, proxy headers et redirections, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(37,'ar','HTTP/HTTPS: إعداد صحيح دون روابط ثابتة','دليل عملي حول HTTP/HTTPS: إعداد صحيح دون روابط ثابتة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «HTTP/HTTPS: إعداد صحيح دون روابط ثابتة» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','HTTP/HTTPS: إعداد صحيح دون روابط ثابتة','دليل عملي حول HTTP/HTTPS: إعداد صحيح دون روابط ثابتة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(37,'en','HTTP/HTTPS configuration without hard-coded URLs','A practical guide to http/https configuration without hard-coded urls, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>HTTP/HTTPS configuration without hard-coded URLs is worth discussing when it is tied to a concrete constraint. The focus here is web. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>$stmt = $pdo-&gt;prepare(&#x27;SELECT id, status FROM jobs WHERE team_id = ? LIMIT 50&#x27;);</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','HTTP/HTTPS configuration without hard-coded URLs','A practical guide to http/https configuration without hard-coded urls, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(38,'web-security-headers',5,'assets/img/covers/web-security-headers.jpg','published',0,13,'2026-06-11 09:26:00','2026-06-11 09:26:00','2026-06-11 09:26:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(38,'fr','Headers de sécurité web à mettre en production','Guide pratique sur CSP, frame, referrer, MIME et permissions, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Headers de sécurité web à mettre en production » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est CSP, frame, referrer, MIME et permissions. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour CSP, frame, referrer, MIME et permissions, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>POST /api/v1/jobs HTTP/1.1
Idempotency-Key: device-42-job-981</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Headers de sécurité web à mettre en production, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour CSP, frame, referrer, MIME et permissions, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Headers de sécurité web à mettre en production','Guide pratique sur CSP, frame, referrer, MIME et permissions, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(38,'ar','ترويسات أمان الويب للإنتاج','دليل عملي حول ترويسات أمان الويب للإنتاج مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «ترويسات أمان الويب للإنتاج» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>Idempotency-Key: device-42-job-981</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','ترويسات أمان الويب للإنتاج','دليل عملي حول ترويسات أمان الويب للإنتاج مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(38,'en','Web security headers worth shipping','A practical guide to web security headers worth shipping, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Web security headers worth shipping is worth discussing when it is tied to a concrete constraint. The focus here is security. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>Idempotency-Key: device-42-job-981</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Web security headers worth shipping','A practical guide to web security headers worth shipping, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(39,'backup-restore-drill',5,'assets/img/covers/backup-restore-drill.jpg','published',0,14,'2026-06-12 09:33:00','2026-06-12 09:33:00','2026-06-12 09:33:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(39,'fr','Sauvegarde : la vraie fiabilité se teste à la restauration','Guide pratique sur RPO, RTO, rotation et vérification, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Sauvegarde : la vraie fiabilité se teste à la restauration » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est RPO, RTO, rotation et vérification. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour RPO, RTO, rotation et vérification, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>Décision → hypothèse → mesure → résultat → prochaine action.</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Sauvegarde : la vraie fiabilité se teste à la restauration, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour RPO, RTO, rotation et vérification, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Sauvegarde : la vraie fiabilité se teste à la restauration','Guide pratique sur RPO, RTO, rotation et vérification, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(39,'ar','النسخ الاحتياطي: الموثوقية تظهر عند الاستعادة','دليل عملي حول النسخ الاحتياطي: الموثوقية تظهر عند الاستعادة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «النسخ الاحتياطي: الموثوقية تظهر عند الاستعادة» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>قرار ← فرضية ← قياس ← نتيجة</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','النسخ الاحتياطي: الموثوقية تظهر عند الاستعادة','دليل عملي حول النسخ الاحتياطي: الموثوقية تظهر عند الاستعادة مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(39,'en','Backups: reliability is proven by restore tests','A practical guide to backups: reliability is proven by restore tests, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Backups: reliability is proven by restore tests is worth discussing when it is tied to a concrete constraint. The focus here is security. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>Decision -&gt; hypothesis -&gt; measurement -&gt; result.</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Backups: reliability is proven by restore tests','A practical guide to backups: reliability is proven by restore tests, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(40,'versioning-changelog',6,'assets/img/covers/versioning-changelog.jpg','published',0,7,'2026-06-13 09:40:00','2026-06-13 09:40:00','2026-06-13 09:40:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(40,'fr','Versionner une application pour que chaque livraison soit traçable','Guide pratique sur SemVer, changelog, migration et SHA-256, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Versionner une application pour que chaque livraison soit traçable » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est SemVer, changelog, migration et SHA-256. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour SemVer, changelog, migration et SHA-256, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>Décision → hypothèse → mesure → résultat → prochaine action.</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Versionner une application pour que chaque livraison soit traçable, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour SemVer, changelog, migration et SHA-256, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Versionner une application pour que chaque livraison soit traçable','Guide pratique sur SemVer, changelog, migration et SHA-256, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(40,'ar','إدارة إصدارات التطبيق لتكون كل نسخة قابلة للتتبع','دليل عملي حول إدارة إصدارات التطبيق لتكون كل نسخة قابلة للتتبع مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «إدارة إصدارات التطبيق لتكون كل نسخة قابلة للتتبع» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>قرار ← فرضية ← قياس ← نتيجة</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','إدارة إصدارات التطبيق لتكون كل نسخة قابلة للتتبع','دليل عملي حول إدارة إصدارات التطبيق لتكون كل نسخة قابلة للتتبع مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(40,'en','Versioning an application so every release is traceable','A practical guide to versioning an application so every release is traceable, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Versioning an application so every release is traceable is worth discussing when it is tied to a concrete constraint. The focus here is architecture. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>Decision -&gt; hypothesis -&gt; measurement -&gt; result.</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Versioning an application so every release is traceable','A practical guide to versioning an application so every release is traceable, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(41,'api-contract-testing',6,'assets/img/covers/api-contract-testing.jpg','published',0,8,'2026-06-14 09:47:00','2026-06-14 09:47:00','2026-06-14 09:47:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(41,'fr','Tester un contrat API avant de brancher l’application mobile','Guide pratique sur schemas, exemples, erreurs et compatibilité, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Tester un contrat API avant de brancher l’application mobile » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est schemas, exemples, erreurs et compatibilité. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour schemas, exemples, erreurs et compatibilité, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>{
  &quot;type&quot;: &quot;event&quot;,
  &quot;version&quot;: 3,
  &quot;idempotency_key&quot;: &quot;device-42:operation-981&quot;
}</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Tester un contrat API avant de brancher l’application mobile, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour schemas, exemples, erreurs et compatibilité, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Tester un contrat API avant de brancher l’application mobile','Guide pratique sur schemas, exemples, erreurs et compatibilité, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(41,'ar','اختبار عقد API قبل ربط تطبيق الهاتف','دليل عملي حول اختبار عقد API قبل ربط تطبيق الهاتف مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «اختبار عقد API قبل ربط تطبيق الهاتف» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>{&quot;version&quot;:3,&quot;idempotency_key&quot;:&quot;device-42:981&quot;}</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','اختبار عقد API قبل ربط تطبيق الهاتف','دليل عملي حول اختبار عقد API قبل ربط تطبيق الهاتف مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(41,'en','Testing an API contract before wiring the mobile app','A practical guide to testing an api contract before wiring the mobile app, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Testing an API contract before wiring the mobile app is worth discussing when it is tied to a concrete constraint. The focus here is architecture. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>{&quot;version&quot;:3,&quot;idempotency_key&quot;:&quot;device-42:981&quot;}</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Testing an API contract before wiring the mobile app','A practical guide to testing an api contract before wiring the mobile app, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO posts(id,slug,category_id,cover_image,status,featured,reading_minutes,published_at,created_at,updated_at) VALUES(42,'tech-writing-human',7,'assets/img/covers/tech-writing-human.jpg','published',0,9,'2026-06-15 09:54:00','2026-06-15 09:54:00','2026-06-15 09:54:00');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(42,'fr','Écrire un tutoriel technique utile : problème, preuve, décision','Guide pratique sur retour terrain, exemples, limites et vérification, avec architecture, cas limites, mesure et checklist de production.','<h2>1. Partir du problème réel</h2><p>Le sujet « Écrire un tutoriel technique utile : problème, preuve, décision » devient utile lorsqu\'on le rattache à une contrainte mesurable. Ici, l\'angle choisi est retour terrain, exemples, limites et vérification. Avant de modifier le code, je note le symptôme, le contexte, le volume de données, le comportement attendu et la manière de vérifier le résultat. Cette discipline évite les corrections qui déplacent simplement le problème ailleurs.</p><p>Dans un projet métier, la bonne solution n\'est pas nécessairement la plus sophistiquée. Elle doit surtout rester compréhensible au prochain incident. Je privilégie donc des composants courts, des états explicites, des erreurs traçables et une séparation nette entre interface, logique métier et accès aux données.</p><h2>2. Concevoir le flux avant l\'écran</h2><p>Je dessine d\'abord le chemin de la donnée : origine, validation, stockage, transformation, synchronisation et affichage. Pour retour terrain, exemples, limites et vérification, chaque étape doit pouvoir échouer sans laisser une donnée dans un état ambigu. C\'est aussi là que je décide où placer les identifiants stables, les horodatages, les tentatives et les journaux.</p><blockquote>Une interface rapide ne compense pas un flux de données imprécis. L\'utilisateur ressent immédiatement les doublons, les blocages et les résultats manquants.</blockquote><h2>3. Exemple minimal</h2><p>L\'extrait suivant ne représente pas une application complète; il montre plutôt la forme du contrat que je cherche : lisible, testable et sans effet caché.</p><pre><code>Décision → hypothèse → mesure → résultat → prochaine action.</code></pre><p>Le point important est de garder le code d\'infrastructure remplaçable. Une API, une base locale, un hébergement ou un SDK peuvent évoluer. Les règles métier doivent rester testables sans dépendre de l\'écran ou d\'un fournisseur précis.</p><h2>4. Gérer les cas difficiles</h2><p>Je teste ensuite les scénarios qui cassent les démonstrations parfaites : réseau lent, doublon, deux utilisateurs sur la même donnée, retour arrière, caractère arabe, écran étroit, liste très longue, redémarrage de l\'application et serveur temporairement indisponible. C\'est souvent dans ces cas que la qualité d\'architecture devient visible.</p><p>Pour éviter le comportement “ça marche chez moi”, chaque action importante produit un résultat exploitable : succès confirmé, erreur classée, nouvelle tentative planifiée ou conflit à résoudre. L\'absence de réponse n\'est jamais considérée comme un succès.</p><h2>5. Mesurer avant d\'optimiser</h2><p>Sur Écrire un tutoriel technique utile : problème, preuve, décision, j\'observe au minimum le temps de réponse, le nombre de requêtes, les erreurs, les éléments chargés et les opérations répétées. Une optimisation doit réduire un coût précis. Par exemple, limiter une carte à la zone visible ou ajouter un index adapté vaut mieux qu\'un cache global ajouté sans diagnostic.</p><h3>Checklist de vérification</h3><ul><li>Le résultat est-il exact avant d\'être rapide ?</li><li>Le flux supporte-t-il une nouvelle tentative ?</li><li>Les permissions sont-elles appliquées côté serveur ?</li><li>Le journal permet-il de comprendre une anomalie sans reproduire le poste utilisateur ?</li><li>Le mobile et la tablette conservent-ils la priorité au contenu utile ?</li></ul><h2>6. Ce que je garderais en production</h2><p>Je garde une solution lorsque son comportement est prévisible et documenté. Pour retour terrain, exemples, limites et vérification, cela signifie généralement un contrat d\'entrée strict, un stockage cohérent, des identifiants stables, une stratégie d\'erreur explicite et un test qui rejoue le scénario critique. Ensuite seulement j\'ajoute les optimisations visuelles.</p><p>La meilleure évolution suivante consiste à automatiser une vérification de non-régression. Le but n\'est pas d\'accumuler des couches techniques, mais de pouvoir changer une partie du système sans casser silencieusement les autres.</p>','Écrire un tutoriel technique utile : problème, preuve, décision','Guide pratique sur retour terrain, exemples, limites et vérification, avec architecture, cas limites, mesure et checklist de production.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(42,'ar','كتابة درس تقني مفيد: مشكلة ودليل وقرار','دليل عملي حول كتابة درس تقني مفيد: مشكلة ودليل وقرار مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.','<h2>1. ابدأ بالمشكلة الحقيقية</h2><p>قيمة موضوع «كتابة درس تقني مفيد: مشكلة ودليل وقرار» تظهر عندما نربطه بقيد يمكن قياسه. التركيز هنا هو هندسة عملية قابلة للقياس. قبل تعديل الكود نحدد العَرَض، والسلوك المطلوب، وحجم البيانات، وطريقة التحقق من النتيجة. بهذه الطريقة لا يتحول الإصلاح المحلي إلى مشكلة جديدة في جزء آخر من النظام.</p><p>في التطبيقات المهنية أفضل البنية الواضحة: حالات صريحة، مكونات صغيرة، أخطاء قابلة للتتبع، وفصل بين الواجهة وقواعد العمل والوصول إلى البيانات.</p><h2>2. صمّم مسار البيانات أولاً</h2><p>تتبّع البيانات من الإدخال إلى التحقق والحفظ والمزامنة ثم العرض. يجب أن تستطيع كل مرحلة الفشل دون ترك حالة غامضة. المعرفات الثابتة والتوقيتات وسجل المحاولات عناصر أساسية.</p><h2>3. مثال صغير</h2><pre><code>قرار ← فرضية ← قياس ← نتيجة</code></pre><p>الفكرة ليست في طول المثال، بل في عقد واضح يمكن اختباره. يجب أن تبقى البنية التحتية قابلة للاستبدال بينما تبقى قواعد العمل مستقلة عن الشاشة أو المزوّد.</p><h2>4. اختبر الظروف الصعبة</h2><p>جرّب اتصالاً بطيئاً، تكرار الطلب، تعديلين في نفس الوقت، نصاً عربياً، شاشة صغيرة، قائمة ضخمة، إعادة تشغيل التطبيق، وتعطّل الخادم مؤقتاً. هذه السيناريوهات تكشف جودة التصميم بسرعة.</p><h2>5. قِس قبل التحسين</h2><p>راقب زمن الاستجابة وعدد الاستعلامات والأخطاء والعناصر المعروضة والعمل المتكرر. حسّن تكلفة معروفة بدلاً من إضافة طبقات تقنية بدون تشخيص.</p><h3>قائمة تحقق</h3><ul><li>هل النتيجة صحيحة قبل أن تكون سريعة؟</li><li>هل إعادة المحاولة آمنة؟</li><li>هل الصلاحيات مطبقة في الخادم؟</li><li>هل السجل يشرح الأعطال؟</li><li>هل الواجهة تعطي الأولوية للمعلومة المهمة؟</li></ul><h2>6. قاعدة الإنتاج</h2><p>احتفظ بالحل عندما يصبح سلوكه متوقعاً وقابلاً للمراقبة وموثقاً. بعد ذلك أضف اختباراً يمنع رجوع المشكلة في الإصدارات القادمة.</p>','كتابة درس تقني مفيد: مشكلة ودليل وقرار','دليل عملي حول كتابة درس تقني مفيد: مشكلة ودليل وقرار مع تصميم واضح، حالات الفشل، القياس وقائمة تحقق للإنتاج.');
INSERT IGNORE INTO post_translations(post_id,locale,title,excerpt,content,meta_title,meta_description) VALUES(42,'en','Writing useful technical tutorials: problem, evidence, decision','A practical guide to writing useful technical tutorials: problem, evidence, decision, with architecture choices, failure cases, measurement and a production checklist.','<h2>1. Start with the real failure mode</h2><p>Writing useful technical tutorials: problem, evidence, decision is worth discussing when it is tied to a concrete constraint. The focus here is technology. I write down the symptom, expected behavior, data volume and verification method before changing code. This prevents a local fix from creating a harder problem elsewhere.</p><p>Business software benefits from boring reliability: explicit state, small components, traceable errors and a clear boundary between UI, domain rules and storage.</p><h2>2. Design the data path first</h2><p>Map the path from input to validation, persistence, synchronization and rendering. Each step should be able to fail without leaving ambiguous state. Stable identifiers and timestamps are more useful than assumptions about call order.</p><h2>3. Keep the contract small</h2><pre><code>Decision -&gt; hypothesis -&gt; measurement -&gt; result.</code></pre><p>The snippet is intentionally small. Infrastructure should be replaceable while domain rules remain testable without a screen or vendor SDK.</p><h2>4. Test hostile conditions</h2><p>Try slow networks, retries, duplicates, simultaneous edits, Arabic text, narrow screens, large lists, process restarts and temporary server failure. These cases expose architecture quality much faster than the happy path.</p><h2>5. Measure before optimizing</h2><p>Track response time, query count, errors, rendered items and repeated work. Optimize a known cost. A viewport query or a missing database index is often more valuable than adding an opaque cache.</p><h3>Production checklist</h3><ul><li>Correct before fast.</li><li>Retry-safe writes.</li><li>Authorization enforced server-side.</li><li>Logs that explain incidents.</li><li>UI density that prioritizes useful content.</li></ul><h2>6. The production rule</h2><p>Keep a solution when its behavior is predictable, observable and documented. Add one non-regression test for the critical scenario before moving on.</p>','Writing useful technical tutorials: problem, evidence, decision','A practical guide to writing useful technical tutorials: problem, evidence, decision, with architecture choices, failure cases, measurement and a production checklist.');
INSERT IGNORE INTO projects(id,slug,cover_image,tech_stack,status,featured,started_at,created_at,updated_at) VALUES(1,'prestataire-telecom','assets/img/projects/prestataire-telecom.jpg','Kotlin,Android,PHP,MySQL,REST,MapLibre','published',1,'2026-07-01','2026-08-08 10:00:00','2026-08-08 10:00:00');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(1,'fr','Prestataire Telecom','Application terrain et plateforme de gestion télécom, pensée pour la synchronisation et les équipes.','<h2>Pourquoi ce projet</h2><p>Application terrain et plateforme de gestion télécom, pensée pour la synchronisation et les équipes.</p><p>Le projet est présenté comme une étude de cas évolutive : contexte, contraintes, architecture, versions et décisions. L\'objectif est de montrer non seulement le résultat visuel, mais surtout la progression technique et les problèmes réellement résolus.</p><h2>Approche</h2><p>Chaque version conserve un historique clair. Les changements majeurs sont séparés des corrections, les migrations sont documentées et les points de mesure restent visibles.</p>');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(1,'ar','Prestataire Telecom','تطبيق ميداني ومنصة لإدارة أعمال الاتصالات مع المزامنة والفرق.','<h2>لماذا هذا المشروع</h2><p>تطبيق ميداني ومنصة لإدارة أعمال الاتصالات مع المزامنة والفرق.</p><p>يتم توثيق المشروع كدراسة حالة متطورة: السياق والقيود والهندسة والإصدارات والقرارات.</p>');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(1,'en','Prestataire Telecom','Field telecom operations app and management platform focused on sync and teams.','<h2>Why it exists</h2><p>Field telecom operations app and management platform focused on sync and teams.</p><p>The project is documented as an evolving case study: context, constraints, architecture, releases and decisions.</p>');
INSERT IGNORE INTO projects(id,slug,cover_image,tech_stack,status,featured,started_at,created_at,updated_at) VALUES(2,'nabd-news','assets/img/projects/nabd-news.jpg','Kotlin,Jetpack Compose,Room,WorkManager,REST','published',1,'2026-08-01','2026-08-08 10:00:00','2026-08-08 10:00:00');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(2,'fr','NABD News','Application Android d’actualités multilingue orientée rapidité, lecture intégrée et personnalisation.','<h2>Pourquoi ce projet</h2><p>Application Android d’actualités multilingue orientée rapidité, lecture intégrée et personnalisation.</p><p>Le projet est présenté comme une étude de cas évolutive : contexte, contraintes, architecture, versions et décisions. L\'objectif est de montrer non seulement le résultat visuel, mais surtout la progression technique et les problèmes réellement résolus.</p><h2>Approche</h2><p>Chaque version conserve un historique clair. Les changements majeurs sont séparés des corrections, les migrations sont documentées et les points de mesure restent visibles.</p>');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(2,'ar','NABD News','تطبيق أخبار أندرويد متعدد اللغات يركز على السرعة والقراءة داخل التطبيق.','<h2>لماذا هذا المشروع</h2><p>تطبيق أخبار أندرويد متعدد اللغات يركز على السرعة والقراءة داخل التطبيق.</p><p>يتم توثيق المشروع كدراسة حالة متطورة: السياق والقيود والهندسة والإصدارات والقرارات.</p>');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(2,'en','NABD News','Multilingual Android news app focused on speed, in-app reading and personalization.','<h2>Why it exists</h2><p>Multilingual Android news app focused on speed, in-app reading and personalization.</p><p>The project is documented as an evolving case study: context, constraints, architecture, releases and decisions.</p>');
INSERT IGNORE INTO projects(id,slug,cover_image,tech_stack,status,featured,started_at,created_at,updated_at) VALUES(3,'outlook-excel-robot','assets/img/projects/outlook-excel-robot.jpg','VBA,Excel,Outlook,Windows,Automation','published',1,'2025-01-01','2026-08-08 10:00:00','2026-08-08 10:00:00');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(3,'fr','Outlook → Excel Robot','Automatisation de traitement d’emails et de données avec orchestration de workers et traçabilité.','<h2>Pourquoi ce projet</h2><p>Automatisation de traitement d’emails et de données avec orchestration de workers et traçabilité.</p><p>Le projet est présenté comme une étude de cas évolutive : contexte, contraintes, architecture, versions et décisions. L\'objectif est de montrer non seulement le résultat visuel, mais surtout la progression technique et les problèmes réellement résolus.</p><h2>Approche</h2><p>Chaque version conserve un historique clair. Les changements majeurs sont séparés des corrections, les migrations sont documentées et les points de mesure restent visibles.</p>');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(3,'ar','Outlook → Excel Robot','أتمتة معالجة البريد والبيانات مع عمال وسجل تتبع.','<h2>لماذا هذا المشروع</h2><p>أتمتة معالجة البريد والبيانات مع عمال وسجل تتبع.</p><p>يتم توثيق المشروع كدراسة حالة متطورة: السياق والقيود والهندسة والإصدارات والقرارات.</p>');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(3,'en','Outlook → Excel Robot','Email and data-processing automation with worker orchestration and traceability.','<h2>Why it exists</h2><p>Email and data-processing automation with worker orchestration and traceability.</p><p>The project is documented as an evolving case study: context, constraints, architecture, releases and decisions.</p>');
INSERT IGNORE INTO projects(id,slug,cover_image,tech_stack,status,featured,started_at,created_at,updated_at) VALUES(4,'developer-blog','assets/img/projects/developer-blog.jpg','PHP,MySQL,JavaScript,CSS,SEO','published',1,'2026-08-08','2026-08-08 10:00:00','2026-08-08 10:00:00');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(4,'fr','FouadDev PortfolioBlog','Ce blog lui-même : portfolio trilingue, tutoriels, SEO technique et import éditorial contrôlé.','<h2>Pourquoi ce projet</h2><p>Ce blog lui-même : portfolio trilingue, tutoriels, SEO technique et import éditorial contrôlé.</p><p>Le projet est présenté comme une étude de cas évolutive : contexte, contraintes, architecture, versions et décisions. L\'objectif est de montrer non seulement le résultat visuel, mais surtout la progression technique et les problèmes réellement résolus.</p><h2>Approche</h2><p>Chaque version conserve un historique clair. Les changements majeurs sont séparés des corrections, les migrations sont documentées et les points de mesure restent visibles.</p>');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(4,'ar','FouadDev PortfolioBlog','هذه المدونة نفسها: معرض أعمال ثلاثي اللغات ودروس وSEO واستيراد تحريري مضبوط.','<h2>لماذا هذا المشروع</h2><p>هذه المدونة نفسها: معرض أعمال ثلاثي اللغات ودروس وSEO واستيراد تحريري مضبوط.</p><p>يتم توثيق المشروع كدراسة حالة متطورة: السياق والقيود والهندسة والإصدارات والقرارات.</p>');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(4,'en','FouadDev PortfolioBlog','This blog itself: trilingual portfolio, tutorials, technical SEO and controlled editorial imports.','<h2>Why it exists</h2><p>This blog itself: trilingual portfolio, tutorials, technical SEO and controlled editorial imports.</p><p>The project is documented as an evolving case study: context, constraints, architecture, releases and decisions.</p>');
INSERT IGNORE INTO projects(id,slug,cover_image,tech_stack,status,featured,started_at,created_at,updated_at) VALUES(5,'anomalie-reseau','assets/img/projects/anomalie-reseau.jpg','Android,Kotlin,Data,Field UX','published',0,'2026-07-01','2026-08-08 10:00:00','2026-08-08 10:00:00');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(5,'fr','Anomalie Réseau','Outils de suivi et de diagnostic réseau avec collecte structurée des anomalies.','<h2>Pourquoi ce projet</h2><p>Outils de suivi et de diagnostic réseau avec collecte structurée des anomalies.</p><p>Le projet est présenté comme une étude de cas évolutive : contexte, contraintes, architecture, versions et décisions. L\'objectif est de montrer non seulement le résultat visuel, mais surtout la progression technique et les problèmes réellement résolus.</p><h2>Approche</h2><p>Chaque version conserve un historique clair. Les changements majeurs sont séparés des corrections, les migrations sont documentées et les points de mesure restent visibles.</p>');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(5,'ar','Anomalie Réseau','أدوات لتتبع وتشخيص مشاكل الشبكة مع جمع منظم للمعطيات.','<h2>لماذا هذا المشروع</h2><p>أدوات لتتبع وتشخيص مشاكل الشبكة مع جمع منظم للمعطيات.</p><p>يتم توثيق المشروع كدراسة حالة متطورة: السياق والقيود والهندسة والإصدارات والقرارات.</p>');
INSERT IGNORE INTO project_translations(project_id,locale,name,tagline,description) VALUES(5,'en','Anomalie Réseau','Network monitoring and diagnostic tooling with structured anomaly collection.','<h2>Why it exists</h2><p>Network monitoring and diagnostic tooling with structured anomaly collection.</p><p>The project is documented as an evolving case study: context, constraints, architecture, releases and decisions.</p>');
INSERT IGNORE INTO project_versions(id,project_id,version,title,summary,changelog,released_at) VALUES(1,1,'13.7.0','Interface terrain consolidée','Menus Installations/PCO/Splitters, carte et recherche unifiée.','- Menus Installations/PCO/Splitters, carte et recherche unifiée.
- Tests de non-régression ciblés
- Documentation de livraison mise à jour','2026-07-20');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(1,'fr','Menus Installations/PCO/Splitters, carte et recherche unifiée.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(1,'en','Menus Installations/PCO/Splitters, carte et recherche unifiée.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(1,'ar','Menus Installations/PCO/Splitters, carte et recherche unifiée.');
INSERT IGNORE INTO project_versions(id,project_id,version,title,summary,changelog,released_at) VALUES(2,1,'14.4.0','Android 16','compileSdk/targetSdk 36, compatibilité Android 16 et stabilisation.','- compileSdk/targetSdk 36, compatibilité Android 16 et stabilisation.
- Tests de non-régression ciblés
- Documentation de livraison mise à jour','2026-08-03');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(2,'fr','compileSdk/targetSdk 36, compatibilité Android 16 et stabilisation.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(2,'en','compileSdk/targetSdk 36, compatibilité Android 16 et stabilisation.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(2,'ar','compileSdk/targetSdk 36, compatibilité Android 16 et stabilisation.');
INSERT IGNORE INTO project_versions(id,project_id,version,title,summary,changelog,released_at) VALUES(3,1,'14.6.0','Sync native probe','Vérification de communication native sans WebView.','- Vérification de communication native sans WebView.
- Tests de non-régression ciblés
- Documentation de livraison mise à jour','2026-08-05');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(3,'fr','Vérification de communication native sans WebView.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(3,'en','Vérification de communication native sans WebView.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(3,'ar','Vérification de communication native sans WebView.');
INSERT IGNORE INTO project_versions(id,project_id,version,title,summary,changelog,released_at) VALUES(4,1,'15.0.0','Architecture client-serveur','Rôles, synchronisation, modules web et backend extensible.','- Rôles, synchronisation, modules web et backend extensible.
- Tests de non-régression ciblés
- Documentation de livraison mise à jour','2026-08-08');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(4,'fr','Rôles, synchronisation, modules web et backend extensible.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(4,'en','Rôles, synchronisation, modules web et backend extensible.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(4,'ar','Rôles, synchronisation, modules web et backend extensible.');
INSERT IGNORE INTO project_versions(id,project_id,version,title,summary,changelog,released_at) VALUES(5,2,'1.2.1','Build stable','Wrapper Gradle stabilisé et dépendances rationalisées.','- Wrapper Gradle stabilisé et dépendances rationalisées.
- Tests de non-régression ciblés
- Documentation de livraison mise à jour','2026-08-03');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(5,'fr','Wrapper Gradle stabilisé et dépendances rationalisées.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(5,'en','Wrapper Gradle stabilisé et dépendances rationalisées.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(5,'ar','Wrapper Gradle stabilisé et dépendances rationalisées.');
INSERT IGNORE INTO project_versions(id,project_id,version,title,summary,changelog,released_at) VALUES(6,2,'1.3.0','Pipeline news','Travail sur ingestion, KSP et architecture de données.','- Travail sur ingestion, KSP et architecture de données.
- Tests de non-régression ciblés
- Documentation de livraison mise à jour','2026-08-04');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(6,'fr','Travail sur ingestion, KSP et architecture de données.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(6,'en','Travail sur ingestion, KSP et architecture de données.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(6,'ar','Travail sur ingestion, KSP et architecture de données.');
INSERT IGNORE INTO project_versions(id,project_id,version,title,summary,changelog,released_at) VALUES(7,3,'1.0.0','Robot initial','Traitement d’emails vers Excel et réponses automatisées.','- Traitement d’emails vers Excel et réponses automatisées.
- Tests de non-régression ciblés
- Documentation de livraison mise à jour','2025-04-01');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(7,'fr','Traitement d’emails vers Excel et réponses automatisées.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(7,'en','Traitement d’emails vers Excel et réponses automatisées.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(7,'ar','Traitement d’emails vers Excel et réponses automatisées.');
INSERT IGNORE INTO project_versions(id,project_id,version,title,summary,changelog,released_at) VALUES(8,3,'2.0.0','Master + Workers','Orchestration jobs/results/log/lock et anti-doublon.','- Orchestration jobs/results/log/lock et anti-doublon.
- Tests de non-régression ciblés
- Documentation de livraison mise à jour','2026-06-01');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(8,'fr','Orchestration jobs/results/log/lock et anti-doublon.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(8,'en','Orchestration jobs/results/log/lock et anti-doublon.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(8,'ar','Orchestration jobs/results/log/lock et anti-doublon.');
INSERT IGNORE INTO project_versions(id,project_id,version,title,summary,changelog,released_at) VALUES(9,4,'1.0.0','Portfolio trilingue','PHP MVC, FR/AR/EN, portfolio, articles, SEO et imports.','- PHP MVC, FR/AR/EN, portfolio, articles, SEO et imports.
- Tests de non-régression ciblés
- Documentation de livraison mise à jour','2026-08-08');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(9,'fr','PHP MVC, FR/AR/EN, portfolio, articles, SEO et imports.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(9,'en','PHP MVC, FR/AR/EN, portfolio, articles, SEO et imports.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(9,'ar','PHP MVC, FR/AR/EN, portfolio, articles, SEO et imports.');
INSERT IGNORE INTO project_versions(id,project_id,version,title,summary,changelog,released_at) VALUES(10,5,'5.0.1','Suivi anomalies','Structuration des anomalies et préparation de collecte terrain.','- Structuration des anomalies et préparation de collecte terrain.
- Tests de non-régression ciblés
- Documentation de livraison mise à jour','2026-07-29');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(10,'fr','Structuration des anomalies et préparation de collecte terrain.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(10,'en','Structuration des anomalies et préparation de collecte terrain.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(10,'ar','Structuration des anomalies et préparation de collecte terrain.');
INSERT IGNORE INTO sources(id,name,type,feed_url,default_locale,enabled,created_at) VALUES(1,'PHP News','rss','https://www.php.net/feed.atom','en',0,NOW());
INSERT IGNORE INTO settings(`key`,`value`) VALUES('content_license_mode','editorial_drafts_only');
INSERT IGNORE INTO project_versions(id,project_id,version,title,summary,changelog,released_at) VALUES(11,4,'1.0.1','Installateur hébergement mutualisé','Correction du déploiement racine ou /public, assistant MySQL et génération automatique du .env.','- Détection automatique domaine/HTTPS/sous-dossier
- Assistant MySQL complet
- Test des prérequis et connexion
- Import SQL et compte admin
- Génération et verrouillage automatique du .env
- Routeur compatible /public','2026-08-08');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(11,'fr','Correction du déploiement racine ou /public, assistant MySQL et génération automatique du .env.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(11,'en','Fixed root or /public deployment, MySQL setup wizard and automatic .env generation.');
INSERT IGNORE INTO project_version_translations(version_id,locale,summary) VALUES(11,'ar','إصلاح النشر من الجذر أو /public مع معالج MySQL وإنشاء ملف .env تلقائياً.');
