# Фреймворки и CMS

Версия источника: 4880e8b4372c96001c2e052be28b68a95d31252b
Синхронизировано: 2026-11-09T11:15:07.649Z
Источник: https://github.com/sergey-from-riders/vibecoding-base/tree/4880e8b4372c96001c2e052be28b68a95d31252b

## Оглавление

- [Laravel: Form Request и Policy](#frameworks-laravel-validation)
- [Laravel: транзакция и afterCommit](#frameworks-laravel-jobs)
- [Laravel: Eloquent и N+1](#frameworks-laravel-eloquent)
- [1С-Битрикс: /local и расширения](#frameworks-bitrix-local)
- [1С-Битрикс: D7-транзакции](#frameworks-bitrix-transactions)
- [1С-Битрикс: ключ кеша и инвалидация](#frameworks-bitrix-cache)
- [Bitrix24: серверный вебхук](#frameworks-bitrix24-webhook)
- [Bitrix24: лимиты и повтор запросов](#frameworks-bitrix24-limits)
- [Django: atomic и on_commit](#frameworks-django-atomic)
- [FastAPI: async и блокирующий I/O](#frameworks-fastapi-io)
- [NestJS: ValidationPipe и DTO](#frameworks-nestjs-validation)
- [Vue: computed и производное состояние](#frameworks-vue-computed)
- [Nuxt: useAsyncData и SSR](#frameworks-nuxt-ssr-data)
- [SvelteKit: server-only modules](#frameworks-sveltekit-server)
- [WordPress: capabilities и nonce](#frameworks-wordpress-permissions)

<a id="frameworks-laravel-validation"></a>

# Laravel: Form Request и Policy

## Коротко

Валидируйте вход и отдельно проверяйте право на объект. В модель передавайте только разрешённые поля.

## Плохо

```php
$order->update($request->all());
```

## Хорошо

```php
// Контроллер: UpdateOrderRequest проверяет title
Gate::authorize('update', $order);
$order->update($request->safe()->only(['title']));
```

## Почему

Проверка формата не даёт права редактировать чужой заказ. Поля вроде owner_id нельзя принимать из произвольного тела запроса.

## Когда применять

Laravel 12.x, Form Request и зарегистрированная Policy; в модели настроен `$fillable`. Входящий DTO не заменяет объектную авторизацию.

## Человек

Определяет права ролей и редактируемые поля заказа.

## Агент

Создаёт Form Request, Policy и тесты запрещённых полей/чужих объектов.

## Пример применения

В кабинете клиент меняет название своего заказа. `UpdateOrderRequest` проверяет строку title, Policy сопоставляет владельца с текущим пользователем, контроллер записывает только title.

## Как проверить

- Чужой заказ даёт отказ.
- Лишние owner_id и is_paid не меняют запись.

## Источники

- [Validation](https://laravel.com/docs/12.x/validation)
- [Authorization](https://laravel.com/docs/12.x/authorization)

Уровень: Рекомендуется. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/laravel-validation.md)

---

<a id="frameworks-laravel-jobs"></a>

# Laravel: транзакция и afterCommit

## Коротко

Задание, которое читает новую запись, отправляйте после фиксации транзакции.

## Плохо

```php
DB::transaction(function () use ($data) {
  $order = Order::create($data);
  SendReceipt::dispatch($order->id);
});
```

## Хорошо

```php
DB::transaction(function () use ($data) {
  $order = Order::create($data);
  SendReceipt::dispatch($order->id)->afterCommit();
});
```

## Почему

Worker может начать работу до commit. При rollback уведомление о несуществующем заказе не должно отправиться.

## Когда применять

Laravel 12.x и асинхронная очередь. Плохой пример предполагает `after_commit=false` в конфигурации соединения. При `after_commit=true` Laravel уже откладывает отправку до commit; явный `afterCommit()` тогда не обязателен. `afterCommit()` не гарантирует доставку при падении процесса между commit и отправкой; для такой гарантии нужен outbox. Обработчик всё равно должен переносить повторы.

## Человек

Определяет необходимую гарантию доставки и срок уведомления.

## Агент

Настраивает afterCommit, идемпотентность и проверку rollback; для надёжной доставки реализует outbox.

## Пример применения

После создания заказа квитанция ставится в очередь. Её ключ уникальности — идентификатор заказа и тип уведомления; временная ошибка почты допускает повтор.

## Как проверить

- Rollback не создаёт отправку.
- Повтор задания не отправляет вторую квитанцию.

## Источники

- [Queues](https://laravel.com/docs/12.x/queues)
- [Database: Getting Started](https://laravel.com/docs/12.x/database#database-transactions)

Уровень: Рекомендуется. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/laravel-jobs.md)

---

<a id="frameworks-laravel-eloquent"></a>

# Laravel: Eloquent и N+1

## Коротко

Загружайте нужные связи списком и ограничивайте размер выдачи.

## Плохо

```php
foreach (Order::all() as $order) {
  echo $order->customer->name;
}
```

## Хорошо

```php
$orders = Order::with('customer')->paginate(30);
foreach ($orders as $order) {
  echo e($order->customer->name);
}
```

## Почему

Ленивая загрузка связи внутри цикла может добавлять запрос на каждую запись.

## Когда применять

Laravel 12.x; связь customer объявлена и обязательна. Фильтр доступа к заказам добавляется до paginate. Не загружайте все связи без необходимости.

## Человек

Выбирает нужные колонки и размер страницы.

## Агент

Добавляет eager loading, измеряет SQL-запросы на нескольких размерах выборки.

## Пример применения

Экран менеджера показывает 30 заказов и имена клиентов. Основная выборка и выборка клиентов выполняются отдельно, без 30 дополнительных запросов.

## Как проверить

- Количество SQL-запросов не растёт линейно с количеством строк.
- Пагинация и фильтр доступа проверены.

## Источники

- [Eloquent: Relationships](https://laravel.com/docs/12.x/eloquent-relationships#eager-loading)
- [Database: Pagination](https://laravel.com/docs/12.x/pagination)

Уровень: Рекомендуется. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/laravel-eloquent.md)

---

<a id="frameworks-bitrix-local"></a>

# 1С-Битрикс: /local и расширения

## Коротко

Собственный код размещайте в /local, используя расширения и шаблоны компонентов.

## Плохо

```text
/bitrix/components/bitrix/news.list/templates/.default/template.php
/bitrix/modules/main/lib/application.php
```

## Хорошо

```text
/local/components/project/events.list/
/local/templates/site/components/bitrix/news.list/events/
```

## Почему

Обновление продукта перезаписывает ядро. Собственный компонент или переопределённый шаблон имеет ясную границу изменений.

## Когда применять

Bitrix Framework с поддержкой /local (D7). Не копируйте ядро целиком. На унаследованном проекте сначала найдите существующие изменения и спланируйте их перенос.

## Человек

Определяет нужное поведение и согласует перенос старых доработок.

## Агент

Находит точку расширения, переносит только необходимое и проверяет компонент на стенде.

## Пример применения

Нужно изменить карточку мероприятия в news.list. Агент создаёт шаблон events в /local/templates/site/components/bitrix/news.list/ и выбирает его в вызове компонента.

## Как проверить

- Diff не меняет системное ядро.
- После обновления тестового стенда компонент работает.

## Источники

- [Урок 1. Разворачиваем стенд и знакомимся с проектом](https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=43&LESSON_ID=33874&LESSON_PATH=33872.33874)

Уровень: Рекомендуется. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/bitrix-local.md)

---

<a id="frameworks-bitrix-transactions"></a>

# 1С-Битрикс: D7-транзакции

## Коротко

Связанные изменения БД фиксируйте одной транзакцией и проверяйте Result каждого вызова.

## Плохо

```php
$first->save();
$second->save(); // ошибка игнорируется
```

## Хорошо

```php
$db = \Bitrix\Main\Application::getConnection();
$db->startTransaction();
try {
  foreach ([$first, $second] as $entity) {
    $result = $entity->save();
    if (!$result->isSuccess()) {
      throw new \RuntimeException('Save failed');
    }
  }
  $db->commitTransaction();
} catch (\Throwable $e) {
  $db->rollbackTransaction();
  throw $e;
}
```

## Почему

Ошибка второго сохранения не должна оставлять первое изменение отдельно от общего результата.

## Когда применять

D7, API сущностей с save(): Result, одна транзакционная БД/соединение. Внешние вызовы и файлы не откатываются вместе с БД. Для конкретного модуля проверьте транзакционное поведение его событий.

## Человек

Определяет атомарную бизнес-операцию и побочные действия.

## Агент

Проверяет API модуля, добавляет транзакцию и воспроизводит частичный отказ.

## Пример применения

При обновлении двух связанных сущностей тест принудительно отклоняет вторую запись. После выполнения первая остаётся без изменений.

## Как проверить

- Ошибка второго сохранения откатывает первое.
- Ошибки Result не игнорируются.

## Источники

- [Connection::startTransaction](https://dev.1c-bitrix.ru/api_d7/bitrix/main/db/connection/starttransaction.php)
- [Result::isSuccess](https://dev.1c-bitrix.ru/api_d7/bitrix/main/result/issuccess.php)

Уровень: Рекомендуется. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/bitrix-transactions.md)

---

<a id="frameworks-bitrix-cache"></a>

# 1С-Битрикс: ключ кеша и инвалидация

## Коротко

Ключ кеша должен различать варианты данных, а изменение источника — очищать соответствующий кеш.

## Плохо

```php
$cacheId = 'orders'; // общий для всех пользователей
```

## Хорошо

```php
$cacheId = hash('sha256', json_encode([
  'v' => 1, 'user' => $userId,
  'filter' => $normalizedFilter,
  'permissions' => $permissionVersion,
], JSON_THROW_ON_ERROR));
```

## Почему

Общий ключ персональной выдачи может показать чужие данные. TTL ограничивает возраст, но не заменяет проверку прав.

## Когда применять

D7 Cache, PHP 7.3+ для JSON_THROW_ON_ERROR; в примере значения userId и permissionVersion получены на сервере после авторизации. При смене прав нужна инвалидация или смена версии. Публичные каталоги могут использовать общий кеш.

## Человек

Определяет приватность, допустимый TTL и события обновления.

## Агент

Формирует нормализованный ключ, настраивает Cache API и проверяет очистку после записи.

## Пример применения

Личный кабинет кеширует список заказов на 30 секунд. Сохранение заказа очищает кеш владельца; отзыв прав меняет permissionVersion. Выбор Redis как движка не меняет эти правила.

## Как проверить

- Два пользователя не получают общую персональную выдачу.
- Изменение данных и прав обновляет результат.

## Источники

- [Главный модуль:Cache](https://dev.1c-bitrix.ru/api_d7/bitrix/main/data/cache/index.php)

Уровень: Рекомендуется. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/bitrix-cache.md)

---

<a id="frameworks-bitrix24-webhook"></a>

# Bitrix24: серверный вебхук

## Коротко

URL входящего вебхука содержит секрет доступа. Вызывайте Bitrix24 со своего сервера.

## Плохо

```text
Браузер → https://portal.bitrix24.ru/rest/1/SECRET/crm.lead.add
```

## Хорошо

```text
Браузер → POST /api/leads
Сервер → Bitrix24 REST API
Секрет → серверная конфигурация
```

## Почему

Секрет из клиентского JavaScript доступен посетителю. Ограничения формы не ограничивают прямой вызов API.

## Когда применять

Bitrix24 REST, локальная интеграция через входящий вебхук. Для устанавливаемого приложения используйте подходящий OAuth-поток. Не публикуйте URL в логах и примерах.

## Человек

Выбирает портал, владельца интеграции и минимальные права вебхука.

## Агент

Хранит секрет на сервере, валидирует заявку и проверяет отказ Bitrix24.

## Пример применения

Форма заявки отправляет только имя и контакт в свой backend. Backend создаёт лид и сохраняет соответствие локального request_id и CRM ID для защиты от дублей.

## Как проверить

- В клиентской сборке и логах нет секрета.
- Свой API проверяет ввод, лимиты и право операции.

## Источники

- [Входящие и исходящие вебхуки](https://apidocs.bitrix24.ru/local-integrations/local-webhooks.html)

Уровень: Обязательно. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/bitrix24-webhook.md)

---

<a id="frameworks-bitrix24-limits"></a>

# Bitrix24: лимиты и повтор запросов

## Коротко

Ограничивайте поток запросов к порталу и обрабатывайте коды ошибок Bitrix24.

## Плохо

```text
1000 заявок → 1000 одновременных crm.lead.add
Любая ошибка → немедленный повтор
```

## Хорошо

```text
Очередь на портал → ограниченный поток
QUERY_LIMIT_EXCEEDED → задержка с jitter
Неясный результат создания → сверка перед повтором
```

## Почему

Лимит зависит от тарифа и нагрузки. Немедленные повторы усиливают блокировку, а повтор создания может создать дубль.

## Когда применять

Облачный Bitrix24 REST. Учитывайте фактические ошибки, время выполнения и текущие лимиты документации; не фиксируйте одну скорость для всех тарифов. В коробочной версии ограничения настраиваются иначе.

## Человек

Определяет приоритеты синхронизации и допустимую задержку.

## Агент

Добавляет очередь по порталам, ограниченный backoff, метрики и обработку исчерпания повторов.

## Пример применения

Импорт 5000 контактов обрабатывается очередью. После QUERY_LIMIT_EXCEEDED скорость уменьшается; прогресс сохраняется, чтобы перезапуск продолжил импорт.

## Как проверить

- Лимит одного портала не останавливает другой.
- При неизвестном результате записи выполняется сверка.

## Источники

- [Лимиты REST API](https://apidocs.bitrix24.ru/limits.html)
- [Как выполнить пакет запросов batch](https://apidocs.bitrix24.ru/settings/how-to-call-rest-api/batch.html)

Уровень: Рекомендуется. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/bitrix24-limits.md)

---

<a id="frameworks-django-atomic"></a>

# Django: atomic и on_commit

## Коротко

Сохранение связанных объектов выполняйте атомарно; зависимое внешнее действие запускайте после commit.

## Плохо

```python
order = Order.objects.create(**data)
notify(order.pk)
Item.objects.create(order=order, **item)
```

## Хорошо

```python
with transaction.atomic():
    order = Order.objects.create(**data)
    Item.objects.create(order=order, **item)
    transaction.on_commit(lambda: notify(order.pk))
```

## Почему

При ошибке создания позиции заказ не должен остаться частично сохранённым.

## Когда применять

Django 5.2 и транзакционная БД. Импорт: `from django.db import transaction`. Callback on_commit не является гарантированной очередью; для доставки после аварии нужен outbox.

## Человек

Определяет атомарность заказа и гарантию доставки уведомлений.

## Агент

Добавляет atomic, on_commit и проверку rollback; отделяет быстрый callback от фоновой обработки.

## Пример применения

Заказ и его позиции сохраняются вместе. В on_commit ставится задача уведомления; если уведомление нельзя потерять при аварии, намерение записывается в outbox внутри atomic.

## Как проверить

- Ошибка позиции откатывает заказ.
- После rollback callback не запускается.

## Источники

- [Database transactions](https://docs.djangoproject.com/en/5.2/topics/db/transactions/)

Уровень: Рекомендуется. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/django-atomic.md)

---

<a id="frameworks-fastapi-io"></a>

# FastAPI: async и блокирующий I/O

## Коротко

В async-обработчике используйте неблокирующий клиент. Обычный def-обработчик подходит для синхронной библиотеки.

## Плохо

```python
@app.get("/report")
async def report():
    return blocking_sdk.fetch_report()
```

## Хорошо

```python
@app.get("/report")
def report():
    return blocking_sdk.fetch_report()
```

## Почему

Синхронный вызов внутри async def блокирует цикл событий. Обычные def-обработчики FastAPI выполняет в пуле потоков.

## Когда применять

FastAPI, ASGI. Пример использует синхронный SDK. Для async-клиента выбирайте async def + await. Выделение потока не отменяет тайм-ауты; CPU-тяжёлые задачи требуют отдельного рассмотрения.

## Человек

Задаёт время ответа и предел нагрузки на внешний сервис.

## Агент

Проверяет тип SDK, выбирает обработчик и проводит тест параллельных запросов.

## Пример применения

Внешний SDK отчётов поддерживает только синхронный вызов. Endpoint реализован через def, SDK имеет ограничение времени; тяжёлая генерация вынесена в очередь.

## Как проверить

- Медленный SDK не блокирует все остальные запросы.
- Настроены тайм-аут и предел параллелизма.

## Источники

- [Concurrency and async / await - FastAPI](https://fastapi.tiangolo.com/async/)

Уровень: Рекомендуется. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/fastapi-io.md)

---

<a id="frameworks-nestjs-validation"></a>

# NestJS: ValidationPipe и DTO

## Коротко

Runtime-валидация требует классов DTO с правилами. TypeScript-интерфейс не проверяет входящий JSON.

## Плохо

```typescript
interface CreateOrder { title: string }
// Тип исчезает после компиляции.
```

## Хорошо

```typescript
class CreateOrderDto {
  @IsString()
  @MaxLength(200)
  title!: string;
}
app.useGlobalPipes(new ValidationPipe({
  whitelist: true, forbidNonWhitelisted: true
}));
```

## Почему

Клиент может отправить поля и типы, которых нет в TypeScript-описании.

## Когда применять

NestJS с class-validator/class-transformer, декораторами и DTO-классом в @Body(). Импорты IsString/MaxLength — class-validator, ValidationPipe — @nestjs/common. Guard/Policy для доступа настраивается отдельно.

## Человек

Определяет допустимые поля и контракт ошибки.

## Агент

Настраивает ValidationPipe, DTO и запросы с некорректным JSON.

## Пример применения

POST /orders принимает title длиной до 200 символов. Поле isPaid, присланное клиентом, отклоняется; оплату меняет только серверный процесс.

## Как проверить

- Число вместо title и лишнее поле получают 400.
- Авторизация проверяется отдельно от DTO.

## Источники

- [Documentation](https://docs.nestjs.com/techniques/validation)
- [Guards](https://docs.nestjs.com/guards)

Уровень: Рекомендуется. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/nestjs-validation.md)

---

<a id="frameworks-vue-computed"></a>

# Vue: computed и производное состояние

## Коротко

Значение, выводимое из реактивных данных, вычисляйте через computed без побочных эффектов.

## Плохо

```typescript
const total = ref(0);
watch(items, () => { total.value = sum(items.value); });
```

## Хорошо

```typescript
import { computed } from 'vue';
const total = computed(() => sum(items.value));
```

## Почему

Отдельное изменяемое total может отстать от исходных данных. computed описывает зависимость напрямую.

## Когда применять

Vue 3 Composition API. items — ref, sum — чистая функция. Watch остаётся подходящим инструментом для побочных действий; денежная арифметика требует точного представления.

## Человек

Определяет формулу итоговой суммы и округление.

## Агент

Выносит чистое вычисление в computed и проверяет изменение элементов.

## Пример применения

Корзина хранит позиции и количество. Итог вычисляется из них; сервер повторно рассчитывает стоимость перед оплатой.

## Как проверить

- Изменение количества обновляет итог.
- Вычисление не изменяет исходные данные.

## Источники

- [Computed Properties](https://vuejs.org/guide/essentials/computed.html)

Уровень: Рекомендуется. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/vue-computed.md)

---

<a id="frameworks-nuxt-ssr-data"></a>

# Nuxt: useAsyncData и SSR

## Коротко

Для данных страницы используйте SSR-aware composable с устойчивым ключом.

## Плохо

```typescript
// setup: запрос повторяется при гидратации
const products = await $fetch("/api/products");
```

## Хорошо

```typescript
const { data: products, status, error } =
  await useAsyncData("products", () => $fetch("/api/products"));
```

## Почему

useAsyncData передаёт серверный результат клиенту и согласует состояния запроса.

## Когда применять

Nuxt 4. Ключ должен учитывать параметры выдачи; один ключ с разными обработчиками недопустим. Для персональных данных отдельно проверяйте cookie, авторизацию и область кеша.

## Человек

Определяет публичность списка и требования к обновлению.

## Агент

Настраивает ключ, обработку status/error и проверяет SSR/гидратацию.

## Пример применения

Публичный каталог загружается через useAsyncData. При добавлении фильтра категории ключ включает её идентификатор; карточки показывают загрузку и ошибку.

## Как проверить

- При гидратации нет лишнего запроса того же результата.
- Смена фильтра меняет ключ или явно обновляет данные.

## Источники

- [useAsyncData · Nuxt Composables v4](https://nuxt.com/docs/4.x/api/composables/use-async-data)
- [Data Fetching · Get Started with Nuxt v4](https://nuxt.com/docs/4.x/getting-started/data-fetching)

Уровень: Рекомендуется. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/nuxt-ssr-data.md)

---

<a id="frameworks-sveltekit-server"></a>

# SvelteKit: server-only modules

## Коротко

Секреты и доступ к БД держите в серверных модулях; клиенту возвращайте только разрешённые поля.

## Плохо

```typescript
// +page.ts: универсальный load
import { db } from "$lib/db";
```

## Хорошо

```typescript
// +page.server.ts: только сервер
import { db } from "$lib/server/db";
export async function load() {
  return { products: await db.product.findMany({
    select: { id: true, title: true },
    orderBy: { id: "asc" }, take: 50
  }) };
}
```

## Почему

Универсальный код может попасть в клиентскую сборку. Серверная загрузка тоже передаёт возвращённые данные браузеру.

## Когда применять

SvelteKit 2; db — пример ORM-клиента проекта. В приватной выдаче добавьте проверку сессии и ограничение владельца. $lib/server и private env нельзя импортировать в клиентский код.

## Человек

Определяет, какие данные публичны.

## Агент

Размещает модуль на сервере, проверяет состав ответа и сборку.

## Пример применения

Каталог возвращает только id и title. Закупочная цена хранится в БД, но не включается в select и данные страницы.

## Как проверить

- Секреты отсутствуют в клиентской сборке.
- Ответ load не содержит закрытых полей.

## Источники

- [Server-only modules • SvelteKit Docs](https://svelte.dev/docs/kit/server-only-modules)
- [Loading data • SvelteKit Docs](https://svelte.dev/docs/kit/load)

Уровень: Рекомендуется. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/sveltekit-server.md)

---

<a id="frameworks-wordpress-permissions"></a>

# WordPress: capabilities и nonce

## Коротко

Проверяйте право на действие и CSRF-защиту отдельно. Nonce не заменяет авторизацию.

## Плохо

```php
check_admin_referer('save_post');
wp_update_post($data);
```

## Хорошо

```php
if (!current_user_can('edit_post', $post_id)) {
  wp_die('Forbidden', '', ['response' => 403]);
}
check_admin_referer('save_post_' . $post_id);
$result = wp_update_post(wp_slash([
  'ID' => $post_id,
  'post_title' => $validated_title,
]), true);
if (is_wp_error($result)) {
  wp_die('Save failed', '', ['response' => 500]);
}
```

## Почему

Знание nonce не даёт права изменять произвольную запись. Проверка capability учитывает объект и текущего пользователя.

## Когда применять

WordPress, обработчик формы в админке. Форма создаёт соответствующий wp_nonce_field; `$post_id` — проверенный ID из маршрута, `$validated_title` — валидированная строка без служебных слешей. В запись передаётся тот же ID, на который проверено право; wp_slash подготавливает массив для API WordPress. Для REST используйте permission_callback и механизм аутентификации REST.

## Человек

Определяет права редакторов и разрешённые поля.

## Агент

Добавляет capability, nonce, валидацию и проверяет запрещённое редактирование.

## Пример применения

Редактор сохраняет карточку товара: сервер проверяет его право на конкретную запись, nonce этой формы и список разрешённых полей.

## Как проверить

- Пользователь без edit_post получает отказ.
- Неверный nonce отклоняется.

## Источники

- [Checking User Capabilities – Plugin Handbook](https://developer.wordpress.org/plugins/security/checking-user-capabilities/)
- [Nonces – Common APIs Handbook](https://developer.wordpress.org/apis/security/nonces/)
- [wp_update_post() – Function](https://developer.wordpress.org/reference/functions/wp_update_post/)

Уровень: Обязательно. Проверено: 2026-11-09. Изменено: 2026-11-09.

[Исходный файл](https://github.com/sergey-from-riders/vibecoding-base/blob/4880e8b4372c96001c2e052be28b68a95d31252b/registry/standards/frameworks/platforms/rules/wordpress-permissions.md)
