مقدمة — الرهبة من المصطلحات
أول مرة تقرأ فيها كلمة JWT أو UUID أو migration في توثيق ما، تشعر أن هناك عالماً سرياً يعرفه الجميع إلا أنت.
هذا الشعور طبيعي تماماً — ومؤقت.
المصطلحات التقنية تبدو مرعبة من الخارج لأنها كلمات إنجليزية غريبة أو اختصارات بلا سياق. لكن بمجرد أن تفهم ما تعنيه، تكتشف أن الفكرة خلفها بسيطة جداً — وكثيراً ما تكون فكرة تعرفها من حياتك اليومية لكنها تلبس "ملابس تقنية".
هذا الدرس لا يُعلّمك البرمجة — يُعلّمك اللغة. حين تعرف اللغة، تستطيع قراءة التوثيقات، فهم الأخطاء، والتواصل مع الذكاء الاصطناعي بدقة أكبر.
١. JWT — تصريح الدخول الرقمي
JWT (اختصار لـ JSON Web Token، يُنطق: "جوت") هو وثيقة هوية رقمية صغيرة يحملها المستخدم بعد تسجيل الدخول.
تخيّل المشهد:
أنت تدخل مبنى → الحارس يتحقق من هويتك → يعطيك بطاقة دخول
في اليوم التالي → تُري البطاقة فقط → لا تحتاج إثبات هوية من جديد
هكذا يعمل JWT تماماً:
المستخدم يُدخل بريده وكلمته → السيرفر يتحقق → يُعطيه JWT
في كل طلب تالٍ → يُرسل المستخدم الـ JWT معه → السيرفر يُصدّق عليه
شكل الـ JWT في الواقع:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIn0.SflKxwRJSMeKKF2QT4fwpMeJf36
↑ ↑ ↑
Header Payload Signature
(نوع التشفير) (البيانات) (التوقيع للتحقق)
لماذا يُستخدم JWT بدلاً من الـ Sessions التقليدية؟
| JWT | Session التقليدية | |
|---|---|---|
| الحفظ | عند المستخدم (المتصفح/التطبيق) | في قاعدة بيانات السيرفر |
| التوسع | سهل — أي سيرفر يقرأه | صعب — كل السيرفرات تحتاج نفس الـ DB |
| الأداء | لا يحتاج استعلام DB | يحتاج استعلام في كل طلب |
الـ JWT مُشفَّر لكنه ليس سرياً — يمكن لأي شخص قراءة محتواه (قِسم الـ Payload) لكن لا يستطيع تعديله بدون اكتشافه. لذا لا تضع كلمات مرور أو بيانات حساسة داخله.
٢. exp / aud / sub — ما بداخل الـ Token
هذه مفاتيح (Claims) موجودة داخل Payload الـ JWT. كل واحدة تحمل معنى محدداً:
{
"sub": "user_abc123",
"aud": "my-mobile-app",
"exp": 1748952000,
"iat": 1748865600,
"email": "abdullah@example.com",
"role": "admin"
}
| المفتاح | الاسم الكامل | المعنى | مثال |
|---|---|---|---|
sub | Subject | هوية من يحمل هذا الـ Token | معرّف المستخدم |
exp | Expiration | متى ينتهي صلاحية الـ Token | timestamp رقمي |
iat | Issued At | متى صدر الـ Token | timestamp رقمي |
aud | Audience | لمن هذا الـ Token — أي تطبيق يقبله | "mobile-app" أو "web" |
iss | Issuer | من أصدر الـ Token | "auth.myapp.com" |
الـ exp مخزّن كـ Unix Timestamp (عدد الثواني منذ ١ يناير ١٩٧٠). يمكنك تحويله على موقع unixtimestamp.com لترى التاريخ الحقيقي.
٣. uid و UUID — هوية كل شيء
uid (User ID)
ببساطة: رقم تعريف المستخدم. كل مستخدم في قاعدة بياناتك له uid فريد لا يتكرر.
عبدالله → uid: 1
محمد → uid: 2
سارة → uid: 3
UUID (Universally Unique Identifier)
نوع خاص من المعرّفات — مضمون أنه فريد في العالم كله.
نموذج UUID:
550e8400-e29b-41d4-a716-446655440000
لماذا UUID بدلاً من أرقام عادية (1, 2, 3)؟
الأرقام التسلسلية:
المستخدم يرى: /users/1, /users/2, /users/3
→ يمكنه تخمين: /users/4 وصولاً لبيانات شخص آخر!
UUID:
المستخدم يرى: /users/550e8400-e29b-41d4-a716-446655440000
→ مستحيل تخمين UUID آخر
متى تستخدم UUID؟
- في أي جدول تريد أمانه أو ستوصله بـ API للعالم الخارجي
- عند دمج بيانات من قواعد بيانات متعددة (لا تصادم في الأرقام)
- مع Supabase — يُولّد UUID تلقائياً لكل سجل جديد
٤. API — الجسر بين التطبيقات
API (Application Programming Interface) هو واجهة تتيح لتطبيقين التحدث مع بعضهما.
المثال الأبسط:
أنت في مطعم (التطبيق)
القائمة هي الـ API (ما يمكنك طلبه)
المطبخ هو السيرفر (من ينفّذ الطلب)
الجرسون هو HTTP (وسيلة النقل)
في الكود:
// طلب بيانات المستخدم من API
const response = await fetch('https://api.myapp.com/users/123');
const user = await response.json();
// user = { id: 123, name: "عبدالله", email: "..." }
أنواع طلبات API:
| النوع | الاستخدام | مثال |
|---|---|---|
GET | جلب بيانات | اجلب بيانات مستخدم |
POST | إرسال/إنشاء بيانات | أنشئ مستخدماً جديداً |
PUT/PATCH | تعديل بيانات | حدّث الاسم |
DELETE | حذف بيانات | احذف الحساب |
كل خدمة تقريباً لها API: Supabase، Google Maps، طقس، دفع... أي شيء تراه في تطبيق يجلب بيانات من خارجه = يستخدم API.
٥. SQL وPostgreSQL — لغة قواعد البيانات
SQL
SQL (Structured Query Language، يُنطق: "سيكوِل" أو "إس-كيو-إل") هي لغة التحدث مع قواعد البيانات. كل سؤال تسأله لقاعدة البيانات مكتوب بـ SQL.
-- اجلب كل المستخدمين
SELECT * FROM users;
-- اجلب مستخدمين أعمارهم فوق ١٨
SELECT name, email FROM users WHERE age > 18;
-- أضف مستخدماً جديداً
INSERT INTO users (name, email) VALUES ('عبدالله', 'a@example.com');
-- حدّث البريد الإلكتروني
UPDATE users SET email = 'new@example.com' WHERE id = 1;
-- احذف مستخدماً
DELETE FROM users WHERE id = 5;
PostgreSQL (يُنطق: "بوست-جرِس-كيو-إل")
PostgreSQL هو نظام قواعد بيانات كامل يستخدم SQL. مثل العلاقة بين:
SQL = اللغة (الإنجليزية)
PostgreSQL = النظام الذي يفهم هذه اللغة (محرك القواعد)
أنظمة أخرى تستخدم SQL أيضاً: MySQL، SQLite، Microsoft SQL Server — لكن PostgreSQL أصبح المعيار الذهبي في المشاريع الحديثة، وهو ما تعتمد عليه Supabase.
٦. Dependencies — مكتبات مشروعك
Dependencies (تبعيات، مفردها: dependency) هي المكتبات الخارجية التي يعتمد عليها مشروعك.
{
"dependencies": {
"react": "^18.2.0",
"axios": "^1.6.0",
"supabase": "^2.0.0"
},
"devDependencies": {
"eslint": "^8.0.0",
"typescript": "^5.0.0"
}
}
الفرق بين النوعين:
| dependencies | devDependencies | |
|---|---|---|
| متى تُستخدم؟ | في التطبيق الفعلي | أثناء التطوير فقط |
| هل تُضاف عند النشر؟ | ✅ نعم | ❌ لا |
| مثال | React، Axios | ESLint، TypeScript |
مجلد node_modules هو مكان تخزين كل الـ dependencies — قد يصل لـ ٥٠٠MB. لذا لا ترفعه على GitHub أبداً، وأضفه لـ .gitignore.
٧. Migration — تطوير قاعدة البيانات بأمان
Migration هو ملف تعديل يُطبَّق على قاعدة البيانات بشكل تدريجي ومنظّم.
المشكلة بدون Migrations:
الأسبوع ١: أنشأت جدول users
الأسبوع ٣: أردت إضافة عمود phone_number
→ تعدّل قاعدة البيانات مباشرة
→ زميلك على جهاز آخر لا يعلم بالتغيير
→ مشاكل ومزامنة يدوية مؤلمة
الحل مع Migrations:
كل تغيير = ملف migration جديد مرقّم
001_create_users.sql ← إنشاء جدول users
002_add_phone_to_users.sql ← إضافة عمود phone
003_create_posts.sql ← إنشاء جدول posts
أي شخص يسحب المشروع يُشغّل: migrate
→ قاعدة بياناته تصبح مطابقة تماماً
مثال migration في Supabase:
ALTER TABLE users
ADD COLUMN phone_number TEXT;
فكّر في الـ Migrations كـ git commits لقاعدة البيانات — تاريخ كامل لكل تغيير، ويمكن التراجع عنه.
٨. Metadata — البيانات عن البيانات
Metadata هي معلومات تصف بيانات أخرى — لا تحتوي المحتوى الفعلي، بل تصف خصائصه.
أمثلة من الحياة اليومية:
صورة فوتوغرافية:
المحتوى = الصورة نفسها (البيانات)
Metadata = التاريخ، الكاميرا، الموقع، الحجم، الدقة
مقطع صوتي:
المحتوى = الصوت
Metadata = الفنان، الألبوم، السنة، المدة، الصنف
ملف في قاعدة البيانات:
المحتوى = النص المكتوب
Metadata = تاريخ الإنشاء، من كتبه، آخر تعديل، عدد الكلمات
في قواعد البيانات:
id → معرّف المقال
content → محتوى المقال (البيانات)
created_at → متى أُنشئ ┐
updated_at → متى عُدِّل ├── Metadata
author_id → من كتبه │
word_count → عدد الكلمات ┘
٩. UI / UX — التصميم ووظيفته
هذان المصطلحان يتداخلان كثيراً لكنهما مختلفان جوهرياً:
UX (User Experience — تجربة المستخدم)
كيف يشعر المستخدم أثناء استخدام التطبيق.
تسأل UX:
- هل المستخدم يجد ما يريده بسهولة؟
- هل تسلسل الخطوات منطقي؟
- هل يعرف دائماً أين هو في التطبيق؟
- هل يحقق هدفه بدون إحباط؟
UX لا علاقة له بالألوان أو الجمال — يهتم بـ المنطق والتدفق والسهولة.
UI (User Interface — واجهة المستخدم)
كيف يبدو التطبيق بصرياً.
تسأل UI:
- ما الألوان المستخدمة؟
- ما حجم الأزرار وشكلها؟
- ما الخطوط؟
- أين يقع كل عنصر على الشاشة؟
المثال الكلاسيكي:
موقع قبيح لكن سهل الاستخدام = UX جيد + UI سيئ
موقع جميل لكن محيّر = UI جيد + UX سيئ
الهدف: الاثنان معاً ✅
١٠. Wrangler — أداة Cloudflare للـ CLI
Wrangler هو أداة سطر الأوامر (CLI) الرسمية لـ Cloudflare. تستخدمها للتعامل مع خدمات Cloudflare من التيرمنال:
# تثبيت Wrangler
npm install -g wrangler
# تسجيل الدخول
wrangler login
# نشر Worker على Cloudflare
wrangler deploy
# تشغيل محلي للاختبار
wrangler dev
# رفع ملف لـ R2
wrangler r2 object put my-bucket/file.pdf --file ./file.pdf
ما هي Cloudflare Workers؟ كود JavaScript يعمل على حافة الشبكة (Edge) في ٣٠٠+ موقع حول العالم — أسرع بكثير من السيرفرات التقليدية.
١١. R2 و S3 — تخزين الملفات السحابي
S3 (Amazon Simple Storage Service)
S3 هو خدمة تخزين الملفات من Amazon AWS. أصبح الاسم معياراً — أي خدمة "متوافقة مع S3" تعني أنها تعمل بنفس الطريقة.
- صور ومقاطع فيديو
- ملفات PDF والمرفقات
- نسخ احتياطية
- أي ملف لا تريد تخزينه في قاعدة البيانات
R2 (Cloudflare R2)
R2 هو بديل Cloudflare لـ S3 — نفس الفكرة لكن بدون رسوم على النقل الصادر (Egress). هذا فارق ضخم:
S3:
رفع ملف = مجاني
تحميله من المستخدمين = رسوم على كل GB صادر 💸
R2:
رفع ملف = مجاني
تحميله من المستخدمين = مجاني تماماً ✅
إذا تطبيقك سيخزن صوراً يراها مستخدمون كثيرون (مثل صور الملفات الشخصية)، R2 يوفّر عليك تكاليف كبيرة مقارنةً بـ S3.
١٢. Linear — إدارة المشاريع للمطورين
Linear هو تطبيق إدارة مهام مصمم خصيصاً للمطورين والفرق التقنية. يُستخدم لتتبع المهام، الأخطاء (Bugs)، والميزات الجديدة.
المشروع يُقسّم إلى:
Issues ← مهام أو أخطاء محددة
Cycles ← دورات عمل (مثل Sprint في Agile)
Projects ← مجموعة Issues مترابطة
Teams ← فرق العمل المختلفة
لماذا Linear وليس Jira أو Trello؟
- أسرع بكثير — تصميم keyboard-first
- مدمج مع GitHub، GitLab، Slack
- يربط كل Issue بـ commit أو PR تلقائياً
- شائع جداً في الشركات الناشئة التقنية
١٣. مصطلحات إضافية لا غنى عنها
Environment Variables (.env)
متغيرات البيئة — مكان تخزين الإعدادات السرية خارج الكود:
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_KEY=eyJhbGciOiJIUzI1...
API_SECRET=super-secret-key-123
لا ترفع ملف .env على GitHub أبداً — أضفه لـ .gitignore.
CORS (Cross-Origin Resource Sharing)
آلية أمان في المتصفح تمنع موقعاً من استدعاء API موقع آخر بدون إذن صريح. إذا رأيت هذا الخطأ:
Access to fetch blocked by CORS policy
الحل يكون في السيرفر — لا في كودك.
REST vs GraphQL
طريقتان لتصميم الـ API:
REST:
/users ← جميع المستخدمين
/users/123 ← مستخدم محدد
/users/123/posts ← منشوراته
GraphQL:
طلب واحد يُحدد فيه ما تريده بالضبط:
{ user(id: 123) { name, posts { title } } }
Payload
المحتوى الفعلي لأي رسالة أو طلب. في طلب API:
{
"name": "عبدالله",
"email": "a@example.com",
"role": "admin"
}
Webhook
عكس الـ API — بدلاً من أن أنت تسأل السيرفر، السيرفر يُرسل لك تلقائياً عند حدث ما:
API عادي: أنت تسأل كل دقيقة "هل وصل دفع جديد؟"
Webhook: Stripe يرسل لك مباشرةً حين يصل الدفع
Token vs Session
Session: السيرفر يحفظ "أنت مسجّل دخول" في قاعدة بياناته
Token (JWT): أنت تحمل "بطاقة تثبت أنك مسجّل" بدون حفظ في السيرفر
Caching
تخزين نتائج طلبات مؤقتاً لتجنب إعادة حسابها:
بدون Cache: كل طلب → استعلام DB → نتيجة (بطيء)
مع Cache: أول طلب → استعلام DB → حفظ النتيجة → التالي من Cache (سريع جداً)
Async / Await
طريقة للتعامل مع العمليات التي تأخذ وقتاً (طلبات API، قراءة ملفات):
// بدون async: الكود لا ينتظر النتيجة
const data = fetch('/api/users'); // data = Promise، ليس البيانات!
// مع async/await: الكود ينتظر حتى تأتي النتيجة
const data = await fetch('/api/users'); // data = البيانات الفعلية ✅
Middleware
كود يعمل بين الطلب والرد — يُنفَّذ قبل أن يصل الطلب لوجهته النهائية:
طلب قادم → [Middleware: تحقق من JWT] → [Middleware: سجّل الطلب] → Handler
١٤. مرجع سريع — القاموس الكامل
JWT ← وثيقة هوية رقمية بعد تسجيل الدخول
exp ← وقت انتهاء صلاحية الـ Token
aud ← لمن هذا الـ Token (أي تطبيق)
sub ← هوية حامل الـ Token
uid ← معرّف المستخدم
UUID ← معرّف فريد عالمياً (آمن لا يُخمَّن)
API ← واجهة تتيح التواصل بين تطبيقين
SQL ← لغة الاستعلام عن قواعد البيانات
PostgreSQL ← نظام قاعدة بيانات يستخدم SQL
Dependencies ← مكتبات خارجية يعتمد عليها مشروعك
Migration ← ملف تعديل منظّم لقاعدة البيانات
Metadata ← بيانات تصف بيانات أخرى
UX ← تجربة المستخدم (كيف يشعر)
UI ← واجهة المستخدم (كيف تبدو)
Wrangler ← CLI رسمي لـ Cloudflare
R2 ← تخزين ملفات من Cloudflare (بدون رسوم نقل)
S3 ← تخزين ملفات من Amazon (المعيار الأشهر)
Linear ← إدارة مهام للفرق التقنية
.env ← ملف المتغيرات السرية
CORS ← قيد أمان في المتصفح على طلبات API
REST ← نمط تصميم API بمسارات URL
Payload ← المحتوى الفعلي للطلب أو الرسالة
Webhook ← إشعار تلقائي من السيرفر عند حدث
Caching ← حفظ النتائج مؤقتاً لتسريع الأداء
Async/Await ← انتظار عملية قبل المتابعة
Middleware ← كود يعمل بين الطلب ووجهته
تمرين عملي
بعد قراءة الدرس، اذهب لأي مشروع مفتوح المصدر على GitHub وافتح ملف package.json:
- حدّد الـ dependencies — ما المكتبات التي يستخدمها؟
- ابحث عن مجلد
migrations/— كيف طوّروا قاعدة بياناتهم؟ - ابحث عن كلمة JWT أو token في الكود — أين تظهر؟
- ابحث عن ملف
.env.example— ما المتغيرات التي يحتاجها المشروع؟ - افتح أي خطأ في الـ Issues وحاول فهمه باستخدام مصطلحات هذا الدرس.