Frontend: guards и UI
useSpaceAbility
Composable: apps/frontend/src/shared/composables/useSpaceAbility.ts.
vue
<script setup lang="ts">
import { computed } from 'vue';
import { useSpaceAbility } from '@/shared/composables/useSpaceAbility';
const props = defineProps<{ spaceId: string }>();
const { can, grants, isLoading, load } = useSpaceAbility(computed(() => props.spaceId));
</script>
<template>
<Button v-if="can('artifact.create')" label="Создать" />
</template>- Загружает
mySpaceAbilities(spaceId)при смене space. can('artifact.agentEdit')— проверка перед показом панели AI edit.
useSpaceAbilityPolicies
Для экрана редактирования policy matrix (owner): useSpaceAbilityPolicies.ts + SpaceAbilityPolicyMatrix.vue.
Registry app.spaceAbilityGuards
Итерируемый реестр для дополнительных guard-ов расширений (опционально):
ts
getExtensionRegistry('app.spaceAbilityGuards').register('my-ext', {
abilityId: 'my-ext.approve',
message: 'Нет права на approve',
});Хост может перебирать entries при рендере extension UI. Основной путь — can() в компоненте расширения.
Паттерны
| Задача | Подход |
|---|---|
| Скрыть кнопку | v-if="can('artifact.delete')" |
| Disable с tooltip | can + i18n сообщение |
| Route guard | beforeEnter + await load() + can |
| Extension slot | проверка в setup слота, не в хосте |
Не дублировать backend
Frontend guards — UX only. Сервер всегда проверяет abilities повторно; подмена GraphQL не обходит enforcement.