Skip to content

Контекст hook и wiring

EntityHookContext

typescript
interface EntityHookContext<TInput = unknown, TItem = unknown> {
  entity: EntityHookEntity;
  phase: EntityHookPhase;
  keystoneContext: KeystoneContext;
  session?: Session;
  spaceId?: string;
  input?: TInput;
  item?: TItem;
  ability?: SpaceAbilityChecker;  // если userId + spaceId
  fields: Record<string, string>; // EAV для entity
  extensionId: string;            // handler owner
  services: ExtensionBackendHostApis;
}

ability

Строится в runner при наличии userId и spaceId:

ts
hookCtx.ability?.assert('artifact.create');
hookCtx.ability?.can('my-ext.approve');

fields

Автоматически getEntityFieldValues для entity + id из input или item.

Wiring points (host)

EntryHooks
artifact-mutation.service.tscreate, move, tags, star
artifact-versioning.service.tssaveVersion
working-copy.service.tscommit → afterSaveVersion
Keystone Space, Artifact, SpaceMember, Templatethin adapter → runner

Полный список смотрите в entity-hooks/ и call sites runEntityHooks.

Регистрация

ts
import { defineExtension } from '@artiroute/extension-sdk/extension';

export default defineExtension((ctx) => {
  ctx.registerEntityHook(
    'artifact',
    'beforeCreate',
    async (hookCtx) => {
      // ...
    },
    100, // order: меньше = раньше
  );
});

Manifest:

js
{ registryId: 'backend.entityHooks', keys: ['artifact:beforeCreate'] }

Keys в manifest — документация surface; фактическая привязка по entity+phase в коде.

Ошибки

abortEntityHookAbortError → GraphQL error с code / message.

Тестирование

  1. pnpm build:extensions && pnpm install:extensions
  2. Создать artifact с именем __registry_test_abort__ в space с registry-test — ожидается abort
  3. Unit tests: apps/backend/src/modules/entity-hooks/ (если есть)

AI workspace для командных материалов и знаний