Token导航 LogoToken导航TokenDH.com
研究检索只读github未标认证来源可访问许可证需确认审计通过

syncable-entity-cache-and-transform可同步实体缓存和转换

Agent Skill

syncable-entity-cache-and-transform 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

930

周安装

38

GitHub Stars

43,491

下载量

301
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:syncable-entity-cache-and-transform(可同步实体缓存和转换)
来源仓库:https://github.com/twentyhq/twenty
仓库路径:skills/syncable-entity-cache-and-transform
安装命令:
npx skills add https://github.com/twentyhq/twenty --skill syncable-entity-cache-and-transform
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/twentyhq/twenty --skill syncable-entity-cache-and-transform

简介

提供实体缓存管理与数据转换功能,支持中间结果暂存与格式适配。

  • 适用于需要临时存储或预处理数据的协作流程,如批量导入导出场景。
  • 通过 GitHub 仓库安装,使用 npx 命令添加技能并指定路径。
  • 需评估缓存策略对性能的影响,避免内存泄漏或过期数据残留问题。
  • 执行数据转换前应验证输入输出格式,防止字段丢失或类型错误。

SKILL.md

Syncable Entity: Cache & Transform (Step 2/6)

Purpose: Create cache layer and transformation utilities to convert between different entity representations.

When to use: After completing Step 1 (Types & Constants). Required before building validators and action handlers.


Quick Start

This step creates:

  1. Cache service for flat entity maps
  2. Entity-to-flat conversion utility
  3. Input transform utils (DTO → Universal Flat Entity)

Key principle: Input transform utils must output universal flat entities (with universalIdentifier and foreign keys mapped to universal identifiers).


Step 1: Create Cache Service

File: src/engine/metadata-modules/flat-my-entity/services/flat-my-entity-cache.service.ts

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { v4 } from 'uuid';

import { WorkspaceCache } from 'src/engine/twenty-orm/decorators/workspace-cache.decorator';
import { MyEntityEntity } from 'src/engine/metadata-modules/my-entity/entities/my-entity.entity';
import { type FlatMyEntityMaps } from 'src/engine/metadata-modules/flat-my-entity/types/flat-my-entity-maps.type';
import { fromMyEntityEntityToFlatMyEntity } from 'src/engine/metadata-modules/flat-my-entity/utils/from-my-entity-entity-to-flat-my-entity.util';

@Injectable()
export class FlatMyEntityCacheService {
  constructor(
    @InjectRepository(MyEntityEntity, 'metadata')
    private readonly myEntityRepository: Repository<MyEntityEntity>,
  ) {}

  @WorkspaceCache({ flatMapsKey: 'flatMyEntityMaps' })
  async getFlatMyEntityMaps(): Promise<FlatMyEntityMaps> {
    const myEntities = await this.myEntityRepository.find({
      withDeleted: true, // CRITICAL: Include soft-deleted entities
    });

    const flatMyEntities = myEntities.map((entity) =>
      fromMyEntityEntityToFlatMyEntity(entity),
    );

    return {
      byId: Object.fromEntries(flatMyEntities.map((e) => [e.id, e])),
      byName: Object.fromEntries(flatMyEntities.map((e) => [e.name, e])),
    };
  }
}

Critical rules:

  • Use @WorkspaceCache decorator with unique flatMapsKey
  • Always use withDeleted: true to include soft-deleted entities
  • Cache key pattern: flat{EntityName}Maps (camelCase)

Step 2: Entity-to-Flat Conversion

File: src/engine/metadata-modules/flat-my-entity/utils/from-my-entity-entity-to-flat-my-entity.util.ts

import { v4 } from 'uuid';
import { type MyEntityEntity } from 'src/engine/metadata-modules/my-entity/entities/my-entity.entity';
import { type FlatMyEntity } from 'src/engine/metadata-modules/flat-my-entity/types/flat-my-entity.type';

export const fromMyEntityEntityToFlatMyEntity = (
  entity: MyEntityEntity,
): FlatMyEntity => {
  return {
    id: entity.id,
    // Critical: generate a new UUID for universalIdentifier
    universalIdentifier: v4(),
    workspaceId: entity.workspaceId,
    applicationId: entity.applicationId,
    name: entity.name,
    label: entity.label,
    description: entity.description,
    isCustom: entity.isCustom,
    parentEntityId: entity.parentEntityId,
    settings: entity.settings,
    createdAt: entity.createdAt.toISOString(),
    updatedAt: entity.updatedAt.toISOString(),
    deletedAt: entity.deletedAt?.toISOString() ?? null,
  };
};

Critical: universalIdentifier must be a new UUID generated with v4() (not entity.id)


Step 3: Input Transform Utils (DTO → Universal Flat Entity)

File: src/engine/metadata-modules/flat-my-entity/utils/from-create-my-entity-input-to-universal-flat-my-entity.util.ts

import { v4 } from 'uuid';
import { sanitizeString } from 'twenty-shared/string';
import { type CreateMyEntityInput } from 'src/engine/metadata-modules/my-entity/dtos/create-my-entity.input';
import { type UniversalFlatMyEntity } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/universal-flat-my-entity.type';
import { resolveEntityRelationUniversalIdentifiers } from 'src/engine/metadata-modules/flat-entity/utils/resolve-entity-relation-universal-identifiers.util';
import { type AllFlatEntityMapsByMetadataName } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps-by-metadata-name.type';

export const fromCreateMyEntityInputToUniversalFlatMyEntity = ({
  input,
  workspaceId,
  flatEntityMaps,
}: {
  input: CreateMyEntityInput;
  workspaceId: string;
  flatEntityMaps?: AllFlatEntityMapsByMetadataName;
}): UniversalFlatMyEntity => {
  const id = v4();
  const universalIdentifier = v4();

  // 1. Extract foreign key IDs BEFORE sanitization
  const parentEntityId = input.parentEntityId ?? null;

  // 2. Sanitize string properties
  const name = sanitizeString(input.name);
  const label = sanitizeString(input.label);
  const description = input.description ? sanitizeString(input.description) : null;

  // 3. Build base flat entity
  const baseFlatEntity = {
    id,
    universalIdentifier,
    workspaceId,
    applicationId: null,
    name,
    label,
    description,
    isCustom: true,
    parentEntityId,
    settings: input.settings ?? null,
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
    deletedAt: null,
  };

  // 4. Resolve foreign keys to universal identifiers (if flatEntityMaps provided)
  if (flatEntityMaps) {
    return resolveEntityRelationUniversalIdentifiers({
      metadataName: 'myEntity',
      flatEntity: baseFlatEntity,
      flatEntityMaps,
    });
  }

  // 5. Return with null universal foreign keys if no maps
  return {
    ...baseFlatEntity,
    parentEntityUniversalIdentifier: null,
  };
};

Key steps:

  1. Generate IDs (id and universalIdentifier with v4())
  2. Extract foreign keys before sanitization
  3. Sanitize all string properties
  4. Build base flat entity
  5. Resolve foreign keys → universal identifiers

Step 4: Create Flat Entity Module

File: src/engine/metadata-modules/flat-my-entity/flat-my-entity.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

import { MyEntityEntity } from 'src/engine/metadata-modules/my-entity/entities/my-entity.entity';
import { FlatMyEntityCacheService } from 'src/engine/metadata-modules/flat-my-entity/services/flat-my-entity-cache.service';

@Module({
  imports: [TypeOrmModule.forFeature([MyEntityEntity], 'metadata')],
  providers: [FlatMyEntityCacheService],
  exports: [FlatMyEntityCacheService],
})
export class FlatMyEntityModule {}

Rules:

  • Import entity with 'metadata' datasource
  • Export cache service for use in other modules

Common Patterns

Pattern: Foreign Key Resolution

// Extract foreign keys BEFORE sanitization
const parentEntityId = input.parentEntityId ?? null;

// After building base entity, resolve to universal identifiers
const universalFlatEntity = resolveEntityRelationUniversalIdentifiers({
  metadataName: 'myEntity',
  flatEntity: baseFlatEntity,
  flatEntityMaps,
});

Pattern: JSONB with SerializedRelation

// For JSONB properties containing foreign keys
const settings = input.settings
  ? {
      ...input.settings,
      fieldMetadataId: input.settings.fieldMetadataId,
    }
  : null;

// After resolution, JSONB foreign keys become universal identifiers
return resolveEntityRelationUniversalIdentifiers({
  metadataName: 'myEntity',
  flatEntity: { ...baseFlatEntity, settings },
  flatEntityMaps,
});

Pattern: Update Transform

// from-update-my-entity-input-to-universal-flat-my-entity-updates.util.ts
export const fromUpdateMyEntityInputToUniversalFlatMyEntityUpdates = ({
  input,
  flatEntityMaps,
}: {
  input: UpdateMyEntityInput;
  flatEntityMaps?: AllFlatEntityMapsByMetadataName;
}): Partial<UniversalFlatMyEntity> => {
  const updates: Partial<UniversalFlatMyEntity> = {};

  if (input.name !== undefined) {
    updates.name = sanitizeString(input.name);
  }

  if (input.parentEntityId !== undefined) {
    updates.parentEntityId = input.parentEntityId;
  }

  updates.updatedAt = new Date().toISOString();

  // Resolve foreign keys if maps provided
  if (flatEntityMaps) {
    return resolveEntityRelationUniversalIdentifiers({
      metadataName: 'myEntity',
      flatEntity: updates as any,
      flatEntityMaps,
    });
  }

  return updates;
};

Checklist

Before moving to Step 3:

  • Cache service created with @WorkspaceCache decorator
  • Cache uses withDeleted: true
  • Cache key follows flat{EntityName}Maps pattern
  • Entity-to-flat conversion implemented
  • universalIdentifier set correctly (generated with v4())
  • Create input transform implemented
  • Update input transform implemented (if needed)
  • Foreign keys extracted before sanitization
  • String properties sanitized
  • Foreign keys resolved to universal identifiers
  • Flat entity module created and exports cache service

Next Step

Once cache and transform utilities are complete, proceed to: Syncable Entity: Builder & Validation (Step 3/6)

For complete workflow, see @creating-syncable-entity rule.

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

37.71%
按下载量换算114

Claude

32.22%
按下载量换算97

Cursor

18.33%
按下载量换算55

Gemini CLI

8.96%
按下载量换算27

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills