# Syncable Entity Builder And Validation

Contributing to the Twenty codebase itself (twentyhq/twenty server internals), not for...

- Repository: https://github.com/twentyhq/twenty (60258 stars)
- Category: Business
- License: see repository
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add twentyhq/twenty --skill syncable-entity-builder-and-validation -g -a claude-code -y`
Codex: `npx skills add twentyhq/twenty --skill syncable-entity-builder-and-validation -g -a codex -y`
Cursor: `npx skills add twentyhq/twenty --skill syncable-entity-builder-and-validation -g -a cursor -y`
Gemini CLI: `npx skills add twentyhq/twenty --skill syncable-entity-builder-and-validation -g -a gemini-cli -y`

## Description

Contributing to the Twenty codebase itself (twentyhq/twenty server internals), not for building apps on top of Twenty. Create validation logic and migration action builders for syncable entities in Twenty. Use when implementing business rule validation, uniqueness checks, foreign key validation, or building workspace migration actions for syncable entities. Validators never throw and never mutate.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Syncable Entity: Builder & Validation (Step 3/6)

**Purpose**: Implement business rule validation and create migration action builders.

**When to use**: After completing Steps 1-2 (Types, Cache, Transform). Required before implementing action handlers.

---

## Quick Start

This step creates:
1. Validator service (business logic validation)
2. Builder service (action creation)
3. Orchestrator wiring (**CRITICAL** - often forgotten!)

**Key principles**:
- Validators **never throw** - return error arrays
- Validators **never mutate** - pass optimistic entity maps
- Use indexed lookups (O(1)) not `Object.values().find()` (O(n))

---

## Step 1: Create Validator Service

**File**: `src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-my-entity-validator.service.ts`

```typescript
import { Injectable } from '@nestjs/common';
import { t, msg } from '@lingui/macro';
import { isDefined } from 'twenty-shared/utils';

import { type FlatMyEntity } from 'src/engine/metadata-modules/flat-my-entity/types/flat-my-entity.type';
import { type FlatMyEntityMaps } from 'src/engine/metadata-modules/flat-my-entity/types/flat-my-entity-maps.type';
import { WorkspaceMigrationValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/types/workspace-migration-validation-error.type';
import { MyEntityExceptionCode } from 'src/engine/metadata-modules/my-entity/exceptions/my-entity-exception-code.enum';

@Injectable()
export class FlatMyEntityValidatorService {
  validateMyEntityForCreate(
    flatMyEntity: FlatMyEntity,
    optimisticFlatMyEntityMaps: FlatMyEntityMaps,
  ): WorkspaceMigrationValidationError[] {
    const errors: WorkspaceMigrationValidationError[] = [];

The rest: https://github.com/twentyhq/twenty/blob/HEAD/.claude/skills/syncable-entity-builder-and-validation/SKILL.md
