ابنِ مشروعًا حقيقيًا وانشره خلال يومين
إنشاء منصة عربية متجاوبة تعمل على الإنترنت وتضم صفحة عامة، تسجيل دخول، لوحة مستخدم، طلبات خدمات، رسائل مرتبطة بالطلبات، نموذج تواصل، قاعدة بيانات محمية، ونشر مباشر.
تقدمك في المعسكر
ضع علامة بعد كل خطوة. يُحفظ التقدم على نفس المتصفح.
مسار اليومين
لا تنتقل قبل تحقق المخرج الإلزامي.
نقطة التحقق
تثبيت رابط المستودع ونتيجة build
إنشاء Supabase
مشروع القاعدة ومفاتيح العميل
التسجيل والجلسات
Supabase SSR مع تحقق البريد والجوال عبر Authentica
البرومبتات الجاهزة
عدّل البيانات بين الأقواس ثم انسخ البرومبت إلى الأداة.
تحويل الفكرة إلى نسخة أولية قابلة للإنجاز
الأداة: ChatGPT / Gemini / Kimi / Qwen — المخرج: نطاق واضح، جمهور، صفحات، وظائف مؤجلة
أنت مستشار منتجات رقمية وخبير في بناء النسخ الأولية.
أريد تحويل الفكرة التالية إلى منصة ويب عملية يمكن بناؤها ونشرها خلال يومين تدريبيين، بإجمالي ست ساعات تطبيقية:
اسم الفكرة: [اكتب الاسم]
المجال: [اكتب المجال]
الفئة المستهدفة: [اكتب الفئة]
المشكلة: [اكتب المشكلة]
السوق: المملكة العربية السعودية
يجب أن تتضمن النسخة الأساسية:
- صفحة رئيسية عربية RTL.
- قائمة خدمات أو عناصر.
- تسجيل وإنشاء حساب.
- لوحة مستخدم.
- إنشاء طلب ومتابعة حالته.
- رسائل مرتبطة بالطلب.
- نموذج تواصل.
- قاعدة بيانات Supabase وسياسات RLS.
- نشر على GitHub ومنصة CranL السعودية.
قدّم:
1. وصف المشروع في فقرة.
2. المستخدم الرئيسي.
3. أهم 3 وظائف فقط.
4. الصفحات المطلوبة.
5. رحلة المستخدم.
6. الجداول والبيانات المطلوبة.
7. ما يجب تأجيله بعد المعسكر.
8. معيار واضح لقبول المشروع.
9. نصًا تسويقيًا قصيرًا للواجهة.
10. اسمًا عربيًا مناسبًا.
اضبط النطاق بحيث يكتمل خلال المعسكر ولا تقترح دفعًا إلكترونيًا أو تطبيق جوال أو لوحة إدارة مخصصة.
إنشاء وثيقة تنفيذ مختصرة
الأداة: ChatGPT / Kimi — المخرج: PRD قابل للبناء
حوّل نتيجة تحليل المشروع السابقة إلى وثيقة تنفيذ مختصرة لا تتجاوز 1200 كلمة.
استخدم الأقسام:
الهدف، المستخدمون، نطاق النسخة الأولى، الصفحات، وظائف كل صفحة، حالات الاستخدام، نموذج البيانات، قواعد الصلاحيات، حالات التحميل والخطأ والفراغ والنجاح، معايير القبول، وقائمة ما لن يتم بناؤه الآن.
اكتب المتطلبات بصيغة قابلة للتنفيذ بواسطة وكيل برمجي، وتجنب العبارات العامة دون معيار واضح.
إنشاء مشروع Next.js
الأداة: Codex / ZCode — المخرج: مشروع يعمل محليًا
اعمل داخل المجلد الحالي ونفّذ تهيئة مشروع جديد باستخدام أحدث إصدار مستقر متاح من Next.js.
المتطلبات:
- App Router وTypeScript وTailwind CSS وESLint ومجلد src.
- واجهة عربية RTL.
- تثبيت @supabase/supabase-js و@supabase/ssr وzod وreact-hook-form و@hookform/resolvers وlucide-react.
- إنشاء .env.example دون أسرار.
- تشغيل المشروع محليًا.
- تشغيل lint وbuild وإصلاح أي خطأ.
- لا تحذف ملفات خارج مجلد المشروع.
بناء الصفحات العامة
الأداة: Codex / ZCode — المخرج: واجهة عامة متجاوبة
ابنِ الواجهة العامة للمشروع وفق وثيقة المتطلبات.
المتطلبات:
- عربية RTL ومتوافقة مع 375px و768px و1440px.
- أزرق داكن مع لون تمييز برتقالي.
- مكونات قابلة لإعادة الاستخدام.
- شريط تنقل متجاوب.
- الصفحة الرئيسية، الخدمات، تفاصيل الخدمة، التواصل، والتذييل.
- حالات hover وfocus وlabels حقيقية.
- لا تستخدم Lorem Ipsum.
- استخدم بيانات تجريبية منظمة دون قاعدة بيانات في هذه المرحلة.
بعد التنفيذ شغّل lint وbuild وأصلح الأخطاء واعرض الملفات المعدلة.
واجهات التسجيل ولوحة المستخدم
الأداة: Codex / ZCode — المخرج: شاشات جاهزة للربط
أضف واجهات:
/register
/login
/forgot-password
/dashboard
/dashboard/requests
/dashboard/messages
/dashboard/profile
استخدم react-hook-form وzod، ورسائل تحقق عربية، وحالات loading/error/success، ومنع الضغط المتكرر، ولوحة متجاوبة للجوال. استخدم بيانات تجريبية ولا تنشئ لوحة أدمن مخصصة. شغّل lint وbuild وأصلح الأخطاء.
مراجعة الجوال والوصول
الأداة: Codex / ZCode — المخرج: واجهة اجتازت فحص الجوال
راجع المشروع كمختص UX/UI وإتاحة للواجهات العربية.
افحص 375px و768px و1440px، ومنع التمرير الأفقي، وصحة RTL، وأهداف اللمس، والتباين، وترتيب التركيز، وlabels وaria، وحالات التحميل والخطأ والفراغ والنجاح، وعدم قص النصوص. أصلح المشكلات مباشرة ثم شغّل lint وbuild.
إغلاق اليوم الأول ورفع النسخة
الأداة: Codex / Terminal / GitHub — المخرج: مستودع GitHub ونسخة سليمة
جهّز المشروع للحفظ في GitHub:
- راجع .gitignore وتأكد من تجاهل .env.local.
- أنشئ README عربيًا يشرح المشروع والتشغيل والمتغيرات.
- أزل الملفات المؤقتة.
- شغّل lint وbuild.
- أنشئ commit واضحًا.
- لا تضع أسرارًا في Git.
- أعطني أوامر ربط المستودع ورفع main.
مراجعة SQL وRLS
الأداة: ChatGPT / Codex — المخرج: SQL صالح وآمن
راجع مخطط SQL كخبير Supabase وPostgreSQL.
تحقق من المفاتيح والقيود والفهارس، وتفعيل RLS على كل جداول public، وأن المستخدم يرى بياناته فقط، وأن الخدمات النشطة عامة، وأن رسائل الطلب خاصة بصاحب الطلب، وأن نموذج التواصل لا يكشف رسائل الآخرين، وعدم استخدام service_role في المتصفح. صحح SQL كاملًا وقدمه ككتلة واحدة قابلة للتنفيذ.
إعداد الجلسات والتحقق عبر Authentica
الأداة: Codex / ZCode — المخرج: تسجيل ودخول وتحقق بريد وجوال
اربط مشروع Next.js الحالي بـ Supabase وAuthentica السعودية.
المتغيرات العامة:
NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY
متغيرات Authentica تكون على الخادم فقط، ولا تبدأ بـ NEXT_PUBLIC:
AUTHENTICA_API_KEY
AUTHENTICA_SENDER_ID
AUTHENTICA_BASE_URL
نفّذ:
1. عميل Supabase للمتصفح وعميل للخادم باستخدام @supabase/ssr.
2. تسجيل المستخدم بالبريد وكلمة المرور وإنشاء الجلسة.
3. إرسال رمز تحقق للبريد عبر Authentica.
4. إرسال رمز OTP إلى الجوال السعودي عبر Authentica.
5. طبّع أرقام الجوال إلى الصيغة +9665XXXXXXXX.
6. صفحة إدخال رمز التحقق مع مدة صلاحية وإعادة إرسال بعد وقت انتظار.
7. لا تخزن رمز OTP كنص صريح، ولا تسجله في console أو السجلات.
8. اجعل التحقق محدود المحاولات مع رسائل عربية عامة.
9. بعد نجاح التحقق، حدّث phone_verified_at وemail_verified_at في profiles.
10. لا تسمح بإنشاء طلب خدمة قبل اكتمال التحقق المطلوب.
11. أضف تسجيل الدخول والخروج ونسيت كلمة المرور.
12. احمِ مسارات /dashboard.
13. لا تستخدم service_role في المتصفح.
14. حدّث .env.example بأسماء المتغيرات فقط.
15. شغّل lint وbuild وأصلح جميع الأخطاء.
الموقع الرسمي لمزود التحقق:
https://authentica.sa/
ربط الخدمات والطلبات والملف الشخصي
الأداة: Codex / ZCode — المخرج: CRUD يعمل وفق RLS
اربط profiles وservices وservice_requests.
اقرأ الخدمات النشطة، وأنشئ أو حدّث الملف الشخصي، وأنشئ طلبًا للمستخدم المسجل، واعرض طلباته فقط، وصفحة تفاصيل طلب، ومنع الطلب الفارغ أو الخدمة غير النشطة، وحالات loading/error/empty/success. لا تثق في user_id من العميل؛ استخدم الجلسة. اختبر بحسابين ثم شغّل lint وbuild.
رسائل الطلب ونموذج التواصل
الأداة: Codex / ZCode — المخرج: رسائل خاصة ونموذج تواصل
اربط request_messages وcontact_messages.
يجب أن يرى المستخدم رسائل طلبه فقط، ويضيف رسالة نصية إلى طلب يملكه، ويمنع النص الفارغ أو الأطول من 2000 حرف. احفظ نموذج التواصل العام دون صفحة عامة للقراءة، وأضف رسائل نجاح ومنع الضغط المتكرر. لا تضف دردشة لحظية. اختبر محاولة الوصول لطلب مستخدم آخر.
إشعار بريد اختياري عبر Resend
الأداة: Codex / Resend — المخرج: إشعار اختياري آمن
أضف إرسال إشعار بريد اختياري عند إنشاء طلب عبر Resend.
التنفيذ على الخادم فقط. استخدم RESEND_API_KEY وRESEND_FROM_EMAIL وNOTIFICATION_TO_EMAIL دون NEXT_PUBLIC. لا يفشل الطلب إذا فشل البريد، ولا تكشف الخطأ للمستخدم، وتجاوز الإرسال إذا غابت المتغيرات. أضف قالبًا عربيًا بسيطًا وحدًا لمنع التكرار. شغّل lint وbuild.
مراجعة الأمن والخصوصية
الأداة: Codex / ZCode — المخرج: إغلاق الثغرات الأساسية
نفّذ مراجعة أمنية وأصلح المشكلات مباشرة:
الأسرار في Git، service_role في المتصفح، RLS، IDOR، التحقق من المدخلات، XSS، إعادة التوجيه، رسائل الخطأ، حماية المسارات، عدم الوثوق بـ user_id، حدود الطول، وروابط طلبات المستخدمين. قدّم PASS/FAIL بعد الإصلاح وشغّل lint وbuild.
اختبار رحلة المستخدم كاملة
الأداة: Codex / Browser — المخرج: رحلة E2E ناجحة
اختبر رحلة كاملة:
فتح الصفحة من الجوال، الخدمات، إنشاء حساب، الدخول، تعديل الملف، إنشاء طلب، فتح تفاصيله، إرسال رسالة، الخروج، منع لوحة التحكم، حساب ثانٍ لا يفتح طلب الأول، إرسال نموذج التواصل، والتحقق من السجلات في Supabase. أصلح كل عطل ثم شغّل lint وbuild واكتب النتائج.
SEO والأداء
الأداة: Codex / PageSpeed — المخرج: نسخة إنتاج نظيفة
جهّز المشروع للنشر:
metadata عربية، title وdescription، icon، تحسين الصور، إزالة بيانات الاختبار غير اللازمة، 404 وصفحة خطأ، عدم فهرسة dashboard، مراجعة الروابط والمتغيرات، README، فحص الجوال وRTL، ثم lint وbuild. لا تضف تحليلات أو ملفات تعريف ارتباط دون حاجة.
GitHub وCranL
الأداة: GitHub / CranL — المخرج: رابط إنتاج يعمل
جهّز إصدار النشر:
تأكد من نجاح lint وbuild، وعدم تتبع .env.local، ثم أنشئ commit نهائيًا وارفع main إلى GitHub. اربط المستودع بمشروع CranL السعودية، وفعّل النشر التلقائي عند كل push، وأضف متغيرات البيئة إلى CranL دون عرض قيمها. بعد النشر اختبر رابط الإنتاج، واضبط Supabase Site URL وRedirect URLs على رابط CranL المنشور، ثم أعد اختبار التسجيل والطلبات والرسائل وHTTPS من الرابط العام. لا تعتبر المهمة مكتملة قبل نجاح الرحلة.
فحص ما بعد النشر
الأداة: Codex / PageSpeed / Browser — المخرج: قرار GO أو NO-GO
افحص رابط الإنتاج:
HTTPS، الرئيسية، الجوال، التسجيل، الدخول والخروج، استعادة كلمة المرور، الخدمات، إنشاء الطلب، عزل المستخدمين، رسائل الطلب، التواصل، عدم ظهور أسرار أو أخطاء تقنية، PageSpeed، Console، وأن النشر على commit الصحيح.
أصدر GO عند نجاح الوظائف الأساسية، أو NO-GO مع المانع وطريقة الإصلاح.
عرض المشروع في 60 ثانية
الأداة: ChatGPT / Gemini / Kimi — المخرج: نص عرض قصير
اكتب عرضًا شفهيًا عربيًا مدته 60 ثانية لمشروعي، يتضمن المشكلة، الفئة المستهدفة، الحل، ما تم بناؤه، تجربة مباشرة واحدة، رابط المشروع، والخطوة القادمة. استخدم أسلوبًا سعوديًا رسميًا مبسطًا دون مبالغة.
دليل الأدوات
أدوات أساسية وبدائل مجانية أو محدودة، إضافة إلى مساحة CranL السعودية المعتمدة للنشر، دون شرح التسجيل.
Authentica السعودية للتحقق
المنصة المعتمدة في المسار التطبيقي لإرسال رموز OTP عبر الرسائل النصية والتحقق من البريد أثناء التسجيل.
Gemini
تحليل الفكرة وتحسين المحتوى
Google AI Studio
اختبار برومبتات Gemini ومفتاح API اختياري
Gemini Notebook
تلخيص المصادر والملفات
Google Colab
تجارب Python اختيارية
Google Apps Script
أتمتة Forms وSheets بعد المعسكر
Google Forms
حجز الاستشارة وتقييم المعسكر
PageSpeed Insights
اختبار رابط المشروع بعد النشر
Firebase Studio
مرجع لمن لديه مساحة سابقة
Kimi
تحليل طويل ومراجعة المشروع
Qwen Studio
تحليل وكتابة ومراجعة الكود
Z.ai
بناء واجهات وتنفيذ مهام
ZCode
تنفيذ البرومبتات داخل مجلد المشروع
DeepSeek Chat
تصحيح الأخطاء وشرح الكود
ChatGPT
التخطيط والبرومبتات وحل الأخطاء
Codex
بناء المشروع والفحص والإصلاح
Claude
نقد المواصفات وUX
GitHub
حفظ المشروع وربط النشر
Supabase
Postgres وAuth وRLS والطلبات والرسائل
CranL
نشر المشروع من GitHub، النشر التلقائي، HTTPS وSSL وإدارة متغيرات البيئة
Resend
إشعار بريد اختياري للطلبات
Cloudflare Pages
بديل للمواقع الثابتة
Authentica
التحقق عبر الرسائل النصية والبريد أثناء التسجيل وإنشاء الحساب.
قاعدة البيانات ومتغيرات البيئة
نفّذ SQL في Supabase ثم اربط المتغيرات.
supabase/schema.sql
-- مخطط معسكر: منصة خدمات ذكية
create extension if not exists pgcrypto;
create table if not exists public.profiles (
id uuid primary key references auth.users(id) on delete cascade,
full_name text not null default '',
phone text,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now()
);
create table if not exists public.services (
id uuid primary key default gen_random_uuid(),
title text not null,
slug text not null unique,
description text not null,
price_from numeric(10,2),
is_active boolean not null default true,
created_at timestamptz not null default now()
);
create table if not exists public.service_requests (
id uuid primary key default gen_random_uuid(),
user_id uuid not null references auth.users(id) on delete cascade,
service_id uuid not null references public.services(id),
subject text not null check (char_length(subject) between 3 and 150),
details text not null check (char_length(details) between 10 and 3000),
status text not null default 'new'
check (status in ('new','in_review','in_progress','completed','cancelled')),
created_at timestamptz not null default now(),
updated_at timestamptz not null default now()
);
create table if not exists public.request_messages (
id uuid primary key default gen_random_uuid(),
request_id uuid not null references public.service_requests(id) on delete cascade,
sender_id uuid not null references auth.users(id) on delete cascade,
body text not null check (char_length(body) between 1 and 2000),
created_at timestamptz not null default now()
);
create table if not exists public.contact_messages (
id uuid primary key default gen_random_uuid(),
user_id uuid references auth.users(id) on delete set null,
name text not null check (char_length(name) between 2 and 100),
email text,
phone text,
message text not null check (char_length(message) between 10 and 2000),
created_at timestamptz not null default now()
);
create index if not exists idx_service_requests_user_id on public.service_requests(user_id);
create index if not exists idx_request_messages_request_id on public.request_messages(request_id);
create index if not exists idx_services_active on public.services(is_active);
alter table public.profiles enable row level security;
alter table public.services enable row level security;
alter table public.service_requests enable row level security;
alter table public.request_messages enable row level security;
alter table public.contact_messages enable row level security;
drop policy if exists "profiles_select_own" on public.profiles;
create policy "profiles_select_own" on public.profiles
for select to authenticated using ((select auth.uid()) = id);
drop policy if exists "profiles_insert_own" on public.profiles;
create policy "profiles_insert_own" on public.profiles
for insert to authenticated with check ((select auth.uid()) = id);
drop policy if exists "profiles_update_own" on public.profiles;
create policy "profiles_update_own" on public.profiles
for update to authenticated
using ((select auth.uid()) = id)
with check ((select auth.uid()) = id);
drop policy if exists "services_public_read_active" on public.services;
create policy "services_public_read_active" on public.services
for select to anon, authenticated using (is_active = true);
drop policy if exists "requests_select_own" on public.service_requests;
create policy "requests_select_own" on public.service_requests
for select to authenticated using ((select auth.uid()) = user_id);
drop policy if exists "requests_insert_own" on public.service_requests;
create policy "requests_insert_own" on public.service_requests
for insert to authenticated with check ((select auth.uid()) = user_id);
drop policy if exists "requests_update_own" on public.service_requests;
create policy "requests_update_own" on public.service_requests
for update to authenticated
using ((select auth.uid()) = user_id)
with check ((select auth.uid()) = user_id);
drop policy if exists "messages_select_for_owned_request" on public.request_messages;
create policy "messages_select_for_owned_request" on public.request_messages
for select to authenticated
using (
exists (
select 1 from public.service_requests r
where r.id = request_id and r.user_id = (select auth.uid())
)
);
drop policy if exists "messages_insert_for_owned_request" on public.request_messages;
create policy "messages_insert_for_owned_request" on public.request_messages
for insert to authenticated
with check (
sender_id = (select auth.uid())
and exists (
select 1 from public.service_requests r
where r.id = request_id and r.user_id = (select auth.uid())
)
);
drop policy if exists "contact_public_insert" on public.contact_messages;
create policy "contact_public_insert" on public.contact_messages
for insert to anon, authenticated
with check (
char_length(name) between 2 and 100
and char_length(message) between 10 and 2000
and (user_id is null or user_id = (select auth.uid()))
);
drop policy if exists "contact_select_own" on public.contact_messages;
create policy "contact_select_own" on public.contact_messages
for select to authenticated using (user_id = (select auth.uid()));
insert into public.services (title, slug, description, price_from)
values
('استشارة أولية','consultation','جلسة لفهم الاحتياج وتحديد المسار المناسب.',199),
('تنفيذ الخدمة','implementation','تنفيذ عملي للخدمة وفق نطاق واضح.',499),
('باقة متابعة','support','دعم ومتابعة بعد التسليم.',299)
on conflict (slug) do nothing;
.env.example
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
# Optional email notification
RESEND_API_KEY=
RESEND_FROM_EMAIL=
NOTIFICATION_TO_EMAIL=
# Saudi verification provider — server only
AUTHENTICA_API_KEY=
AUTHENTICA_SENDER_ID=
AUTHENTICA_BASE_URL=https://authentica.sa/
أوامر التنفيذ
نفّذها في Terminal أو اطلب من الوكيل تنفيذها والتحقق منها.
إنشاء المشروع
npx create-next-app@latest smart-services --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"فتح المجلد
cd smart-servicesتثبيت الحزم
npm install @supabase/supabase-js @supabase/ssr zod react-hook-form @hookform/resolvers lucide-reactتشغيل محلي
npm run devفحص lint
npm run lintبناء الإنتاج
npm run buildتهيئة Git
git init
git add .
git commit -m "Build workshop MVP"رفع التحديث
git add .
git commit -m "Connect Supabase and prepare release"
git push origin mainخريطة الملفات النهائية
| الملف | الغرض |
|---|---|
src/app/layout.tsx | الهيكل العام وRTL والـ metadata |
src/app/page.tsx | الصفحة الرئيسية |
src/app/services/page.tsx | قائمة الخدمات |
src/app/services/[slug]/page.tsx | تفاصيل الخدمة |
src/app/contact/page.tsx | نموذج التواصل |
src/app/login/page.tsx | تسجيل الدخول |
src/app/register/page.tsx | إنشاء الحساب |
src/app/forgot-password/page.tsx | استعادة كلمة المرور |
src/app/dashboard/layout.tsx | تخطيط لوحة المستخدم |
src/app/dashboard/page.tsx | ملخص الحساب |
src/app/dashboard/requests/page.tsx | قائمة الطلبات |
src/app/dashboard/requests/[id]/page.tsx | تفاصيل الطلب والرسائل |
src/app/dashboard/profile/page.tsx | الملف الشخصي |
src/lib/supabase/client.ts | عميل المتصفح |
src/lib/supabase/server.ts | عميل الخادم |
src/middleware.ts | تحديث الجلسة وحماية المسارات |
supabase/schema.sql | الجداول والسياسات والبيانات |
.env.example | أسماء المتغيرات دون قيم |
README.md | التشغيل والنشر والنطاق |
بوابة الإطلاق
لا يحصل المشروع على GO إلا بعد اكتمال جميع البنود.
مصادر المعسكر
روابط رسمية للأدوات والتقنيات وحدود الخطط.