snapshot of https://github.com/twentyhq/twenty.git (main, 2026-09-17; blobs > 131072B omitted)
Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s

This commit is contained in:
upstream-mirror
2026-09-17 23:28:13 +05:00
commit e7da97194a
32688 changed files with 4208681 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
---
title: أفضل الممارسات
---
تحدد هذه الوثيقة أفضل الممارسات التي يجب اتباعها عند العمل في الواجهة الخلفية.
## اتبع نهجًا معياريًا
الواجهة الخلفية تتبع نهجًا معياريًا، وهو مبدأ أساسي عند العمل مع NestJS. تأكد من تقسيم الكود إلى وحدات قابلة لإعادة الاستخدام للحفاظ على كود مرتب ومنظم.
يجب أن تحتوي كل وحدة على ميزة أو وظيفة معينة وأن يكون لها نطاق محدد بوضوح. يتيح هذا النهج المعياري فصل الاهتمامات بوضوح ويزيل التعقيدات غير الضرورية.
## إتاحة الخدمات لاستخدامها في الوحدات
قم دائمًا بإنشاء خدمات ذات مسؤولية واضحة ووحيدة، مما يعزز من قابلية قراءة وصيانة الكود. قم بتسمية الخدمات بأسماء وصفية وبطريقة متسقة.
يجب أيضًا إتاحة الخدمات التي تريد استخدامها في وحدات أخرى. إتاحة الخدمات للوحدات الأخرى ممكنة عبر نظام حقن التبعيات القوي في NestJS، كما يعزز ذلك الاقتران الضعيف بين المكونات.
## تجنب استخدام نوع `أي`
عند إعلان متغير كـ `أي`، فإن مدقق الأنواع في TypeScript لا يقوم بأي عملية تدقيق للنوع، مما يجعله ممكنًا لتعيين أي نوع من القيم للمتغير. يستخدم TypeScript الاستدلال النوعي لتحديد نوع المتغير بناءً على القيمة. من خلال استخدام `أي`، لم يعد بإمكان TypeScript استنتاج النوع. هذا يجعل من الصعب ضبط أخطاء النوع أثناء التطوير، مما يؤدي إلى حدوث أخطاء في وقت التشغيل ويجعل الكود أقل قابلية للصيانة وأقل موثوقية ويصعب فهمه على الآخرين.
لهذا السبب يجب أن يكون لكل شيء نوع. لذا إن قمت بإنشاء كائن جديد يحتوي على الاسم الأول واسم العائلة، يجب عليك إنشاء واجهة أو نوع يحتوي على الاسم الأول واسم العائلة الذي يحدد شكل الكائن الذي تتعامل معه.

View File

@@ -0,0 +1,39 @@
---
title: كائنات مخصصة
---
الكائنات هي هياكل تسمح لك بتخزين البيانات (السجلات، السمات والقيم) الخاصة بالمؤسسة. توفر Twenty كلاً من الكائنات القياسية والمخصصة.
الكائنات القياسية هي كائنات مدمجة مع مجموعة من السمات المتاحة لجميع المستخدمين. تتضمن الأمثلة على الكائنات القياسية في Twenty الشركات والأشخاص. الكائنات القياسية تحتوي على حقول قياسية تتوفر أيضاً لجميع مستخدمي Twenty، مثل Company.displayName.
الكائنات المخصصة هي كائنات يمكنك إنشاؤها لتخزين المعلومات التي تخص مؤسستك. هذه الكائنات ليست مدمجة؛ يمكن لأعضاء مساحة العمل الخاصة بك إنشاء وتخصيص الكائنات المخصصة للاحتفاظ بالمعلومات التي لا تناسبها الكائنات القياسية.
## مخطط على مستوى عالي
<div style={{textAlign: 'center'}}>
<img src="/images/docs/server/custom-object-schema.png" alt="مخطط على مستوى عالي" />
</div>
<br />
## كيف يعمل
الكائنات المخصصة تأتي من جداول الميتاداتا التي تحدد شكل، اسم، ونوع الكائنات. كل هذه المعلومات موجودة في قاعدة بيانات المخطط البياني للبيانات الوصفية، والتي تتكون من جداول:
* **مصدر البيانات**: يشير إلى مكان وجود البيانات.
* **الكائن**: يصف الكائن ويرتبط بمصدر البيانات.
* **الحقل**: يحدد حقول الكائن ويرتبط بالكائن.
لإضافة كائن مخصص، سيقوم عضو مساحة العمل بالاستعلام عن واجهة برمجة التطبيقات /metadata. يقوم هذا بتحديث البيانات الوصفية وفقًا لذلك ويحسب مخطط GraphQL استنادًا إلى البيانات الوصفية، ويخزنها في ذاكرة GQL للاستخدام لاحقًا.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/server/add-custom-objects.jpeg" alt="استعلام واجهة برمجة التطبيقات /metadata لإضافة الكائنات المخصصة" />
</div>
<br />
لجلب البيانات، تتضمن العملية إجراء استعلامات من خلال نقطة النهاية /graphql وتمريرها من خلال محلل الاستعلام.
<div style={{textAlign: 'center'}}>
<img src="/images/docs/server/custom-object-schema.png" alt="استعلام نقطة النهاية /graphql لجلب البيانات" />
</div>

View File

@@ -0,0 +1,46 @@
---
title: أعلام الميزة
---
تُستخدم أعلام الميزات لإخفاء الميزات التجريبية. بالنسبة إلى Twenty، يتم ضبطها على مستوى مساحة العمل وليس على مستوى المستخدم.
## إضافة علم ميزة جديد
في ملف `FeatureFlagKey.ts` أضف علم الميزة:
```ts
type FeatureFlagKey =
| 'IS_FEATURENAME_ENABLED'
| ...;
```
أيضًا أضفه إلى التعداد في `feature-flag.entity.ts`:
```ts
enum FeatureFlagKeys {
IsFeatureNameEnabled = 'IS_FEATURENAME_ENABLED',
...
}
```
لتطبيق علم ميزة على ميزة **الخلفية** استخدم:
```ts
@Gate({
featureFlag: 'IS_FEATURENAME_ENABLED',
})
```
لتطبيق علم ميزة على ميزة **الواجهة الأمامية** استخدم:
```ts
const isFeatureNameEnabled = useIsFeatureEnabled('IS_FEATURENAME_ENABLED');
```
## تكوين أعلام الميزات للنشر
تغيير السجل المعني في جدول `core.featureFlag`:
| المُعرّف | المفتاح | معرف مساحة العمل | القيمة |
| -------- | ------------------------ | ---------------- | ------ |
| عشوائي | `IS_FEATURENAME_ENABLED` | معرف مساحة العمل | `صحيح` |

View File

@@ -0,0 +1,125 @@
---
title: هيكلية المجلدات
info: نظرة تفصيلية داخل هيكلية مجلدات الخادم
---
الهيكلية الدليلية للمكونات الخلفية كالتالي:
```
server
└───ability
└───constants
└───core
└───database
└───decorators
└───filters
└───guards
└───health
└───integrations
└───metadata
└───workspace
└───utils
```
## قدرات
تعريف الأذونات وتتضمن معالجات لكل كيان.
## زخارف
تعريف الزخارف المخصصة في NestJS لإضافة وظائف جديدة.
شاهد [زخارف مخصصة](https://docs.nestjs.com/custom-decorators) لمزيد من التفاصيل.
## الفلاتر
تتضمن فلاتر استثناء لمعالجة الحالات الطارئة التي قد تحدث في نقاط GraphQL النهائية.
## حمايات
شاهد [الحمايات](https://docs.nestjs.com/guards) لمزيد من التفاصيل.
## الصحة
تتضمن واجهة برمجية متاحة للجميع (healthz) تعيد جيسون لتأكيد ما إذا كانت قاعدة البيانات تعمل كما هو متوقع.
## البيانات الوصفية
تعريف الأشياء المخصصة وتوفر واجهة برمجية GraphQL (graphql/metadata).
## مساحة العمل
توليد وتقديم مخطط GraphQL مخصص بناءً على البيانات الوصفية.
### هيكلية دليل مساحة العمل
```
workspace
└───workspace-schema-builder
└───factories
└───graphql-types
└───database
└───interfaces
└───object-definitions
└───services
└───storage
└───utils
└───workspace-resolver-builder
└───factories
└───interfaces
└───workspace-query-builder
└───factories
└───interfaces
└───workspace-query-runner
└───interfaces
└───utils
└───workspace-datasource
└───workspace-manager
└───workspace-migration-runner
└───utils
└───workspace.module.ts
└───workspace.factory.spec.ts
└───workspace.factory.ts
```
يحتوي الجذر في دليل مساحة العمل على `workspace.factory.ts`، ملف يحتوي على وظيفة `createGraphQLSchema`. تولّد هذه الوظيفة مخططًا خاصًا بمساحة العمل باستخدام البيانات الوصفية لتخصيص المخطط لمساحات العمل الفردية. من خلال فصل بناء المخطط والمستعرض، نستخدم وظيفة `makeExecutableSchema`، التي تجمع بين هذه العناصر المنفصلة.
تعتمد هذه الاستراتيجية على التنظيم ولا تساعد فقط في التنظيم، لكنها أيضًا تحسن الأداء، مثل تخزين تعريفات النوع المولدة مؤقتًا لتعزيز الأداء والتوسع.
### منشئ مخطط مساحة العمل
يولد مخطط GraphQL، ويتضمن:
#### مصانع:
مصانع متخصصة لتوليد الإنشاءات المتعلقة بـ GraphQL.
* المصنع النوعي يترجم بيانات الحقول الوصفية إلى أنواع GraphQL باستخدام `TypeMapperService`.
* ينشئ type-definition.factory كائنات إدخال أو إخراج لـ GraphQL مشتقة من `objectMetadata`.
#### أنواع GraphQL
يتضمن تعدادات، إدخالات، كائنات، وأشكال بسيطة، ويعمل كنقاط بناء للمخطط.
#### واجهات وتعريفات الكائنات
تحتوي على مخططات للكيانات GraphQL، وتشتمل على أنواع معرفة مسبقًا ومخصصة مثل `MONEY` أو `URL`.
#### خدمات
تحتوي على الخدمة المسؤولة عن ربط FieldMetadataType بنوع GraphQL المناسب أو أدوات التعديل الاستعلامية.
#### التخزين
يتضمن فئة `TypeDefinitionsStorage` التي تحتوي على تعريفات نوع قابلة لإعادة الاستخدام، مما يمنع تكرار أنواع GraphQL.
### منشئ محلل مساحة العمل
إنشاء وظائف المعالجات للاستعلام وتعديل مخطط GraphQL.
كل مصنع في هذا الدليل مسؤول عن إنتاج نوع محلل مميز، مثل `FindManyResolverFactory`، المصمم للتطبيق المتكيف عبر جداول مختلفة.
### مشغل استعلامات مساحة العمل
يشغل الاستعلامات المولدة على قاعدة البيانات ويحلل النتيجة.

View File

@@ -0,0 +1,41 @@
---
title: قائمة انتظار الرسائل
---
تسهل القوائم العمليات غير المتزامنة. يمكن استخدامها لأداء مهام الخلفية مثل إرسال بريد ترحيبي عند التسجيل.
سيكون لكل حالة استخدام فئة قائمة خاصة بها ممتدة من `MessageQueueServiceBase`.
حاليًا، ندعم `bull-mq`[bull-mq](https://bullmq.io/) فقط كبرنامج تشغيل القائمة.
## خطوات إنشاء واستخدام قائمة جديدة
1. أضف اسم قائمة لقائمة جديدة تحت التعداد `MESSAGE_QUEUES`.
2. وفّر تنفيذ المصنع لقائمة الانتظار مع استخدام اسم قائمة الانتظار بوصفه رمز التبعية.
3. قم بإدراج القائمة التي أنشأتها في الوحدة/الخدمة المطلوبة مع اسم القائمة كرمز تبعية.
4. أضِف صنف عامل مع حقن قائم على الرمز تمامًا مثل المنتِج.
### نموذج للاستخدام
```ts
class Resolver {
constructor(@Inject(MESSAGE_QUEUES.custom) private queue: MessageQueueService) {}
async onSomeAction() {
//business logic
await this.queue.add(someData);
}
}
//async worker
class CustomWorker {
constructor(@Inject(MESSAGE_QUEUES.custom) private queue: MessageQueueService) {
this.initWorker();
}
async initWorker() {
await this.queue.work(async ({ id, data }) => {
//worker logic
});
}
}
```

View File

@@ -0,0 +1,87 @@
---
title: الأوامر الخلفية
icon: terminal
---
## الأوامر المفيدة
يجب تنفيذ هذه الأوامر من مجلد packages/twenty-server.
من أي مجلد آخر يمكنك تشغيل `npx nx {command} twenty-server` (أو `npx nx run twenty-server:{command}`).
### إعداد المرة الأولى
```
npx nx database:reset twenty-server # setup the database with dev seeds
```
### بدء الخادم
```
npx nx run twenty-server:start
```
### Lint
```
npx nx run twenty-server:lint # pass --fix to fix lint errors
```
### تجربة
```
npx nx run twenty-server:test:unit # run unit tests
npx nx run twenty-server:test:integration # run integration tests
```
ملاحظة: يمكنك تشغيل `npx nx run twenty-server:test:integration:with-db-reset` في حالة احتياجك لإعادة تعيين قاعدة البيانات قبل تشغيل اختبارات التكامل.
### إعادة تعيين قاعدة البيانات
إذا أردت إعادة تعيين قاعدة البيانات وزرع بعض البيانات فيها، يمكنك تشغيل الأمر التالي:
```bash
npx nx run twenty-server:database:reset
```
### عمليات الترحيل
#### للكائنات داخل مخططات Core/Metadata (TypeORM)
```bash
npx nx run twenty-server:database:migrate:generate
```
## "التقنية المستخدمة"
تستخدم Twenty بشكل أساسي NestJS للواجهة الخلفية.
Prisma كان أول ORM استخدمناه. ولكن للسماح للمستخدمين بإنشاء الحقول والعناصر المخصصة، كان من المنطقي استخدام مستوى أقل حيث نحتاج إلى تحكم دقيق. الآن يستخدم المشروع TypeORM.
إليك شكل العناصر التقنية الآن.
**النواة**
* [NestJS](https://nestjs.com/)
* [TypeORM](https://typeorm.io/)
* [GraphQL Yoga](https://the-guild.dev/graphql/yoga-server)
**قاعدة البيانات**
* [Postgres](https://www.postgresql.org/)
**التكاملات مع جهات خارجية**
* [Sentry](https://sentry.io/welcome/) لتتبع الأخطاء
**الاختبار**
* [Jest](https://jestjs.io/)
**الأدوات**
* [Yarn](https://yarnpkg.com/)
* [Oxlint](https://oxc.rs/docs/guide/usage/linter.html)
**التطوير**
* [AWS EKS](https://aws.amazon.com/eks/)

View File

@@ -0,0 +1,85 @@
---
title: تطبيق Zapier
---
قم بمزامنة Twenty مع أكثر من 3000 تطبيق باستخدام [Zapier](https://zapier.com/) بسهولة. قم بأتمتة المهام، وزيادة الإنتاجية، وتعزيز علاقاتك مع العملاء!
## حول Zapier
Zapier هي أداة تتيح لك أتمتة سير العمل من خلال ربط التطبيقات التي يستخدمها فريقك يوميًا. المفهوم الأساسي ل Zapier هو سير العمل الآلي، المسمى Zaps، والذي يتضمن محفزات وإجراءات.
يمكنك معرفة المزيد حول كيفية عمل Zapier [هنا](https://zapier.com/how-it-works).
## إعداد
### الخطوة 1: تثبيت حزم Zapier
```bash
cd packages/twenty-zapier
yarn
```
### الخطوة 2: تسجيل الدخول باستخدام CLI
استخدم بيانات اعتماد Zapier الخاصة بك لتسجيل الدخول باستخدام CLI:
```bash
zapier login
```
### الخطوة 3: تعيين متغيرات البيئة
من مجلد `packages/twenty-zapier`، قم بتشغيل:
```bash
cp .env.example .env
```
شغل التطبيق محليًا، اذهب إلى [http://localhost:3000/settings/api-webhooks](http://localhost:3000/settings/api-webhooks)، وولد مفتاح API.
استبدل قيمة **YOUR_API_KEY** في ملف `.env` بمفتاح API الذي قمت بتوليده للتو.
## التطوير
<Warning>
تأكد من تشغيل `yarn build` قبل أي أمر `zapier`.
</Warning>
### تجربة
```bash
yarn test
```
### Lint
```bash
yarn format
```
### راقب وقم بالتحويل عند تحرير الكود
```bash
yarn watch
```
### تحقق من صحة تطبيق Zapier الخاص بك
```bash
yarn validate
```
### قم بنشر تطبيق Zapier الخاص بك
```bash
yarn deploy
```
### اعرض جميع أوامر Zapier CLI
```bash
zapier
```