Спасибо за идею — добавил CR-05 с правом cart.items.add и отдельный тест. Гипотеза подтвердилась частично: в cargo проверка прав действительно проходит через запрещённую связь entity → feature, но новых нарушений не появилось — использовалась уже существующая плохая граница. Добавил в статью результаты и сравнение графов до/после изменения.
Спасибо, хороший вопрос — Вы как раз попали в одно из ограничений текущего стенда.
В этой версии авторизация не выделена в отдельную категорию и системно не разложена по всем шести вариантам. Кейс с утекшими проверками прав во вступлении был исходной мотивацией, но в измерительную часть вошли другие изменения: переиспользование карточки, удаление промокодов, кэширование каталога и правило доставки. Размещение сквозных политик стенд увы не сравнивает.
Концептуально я бы рассматривал policies/ не как седьмой вариант архитектуры, а как ортогональную границу. При этом полезно разделить получение текущей роли, само правило вида canChangeLimit(user, card) и его применение в UI. В Clean такое правило может находиться в domain/application, в modular — рядом с модулем-владельцем, а в FSD — рядом с owning-слайсом с композицией выше. Отдельный общий policies/ тоже выглядит рабочим решением, если он содержит узкие правила, а не превращается со временем во второй shared.
Ваш эксперимент с корзиной звучит интересно. Отдельный change request на права доступа — например, добавление новой роли или изменение политики без размазывания проверок по UI — был бы хорошим дополнением к стенду. Спасибо за идею, возьму её в список следующих сценариев.
Спасибо за дополнение! Да, такой вариант в официальной документации React действительно есть, и для полноты его стоило упомянуть. Обновил пункт 4, согласно комментарию и документации.
При частичной корректировке состояния React допускает условный setState непосредственно во время рендера. В таком случае текущий результат рендера отбрасывается, и React сразу повторяет рендер до обновления DOM, поэтому дочерние компоненты не успевают отрисоваться с устаревшим значением.
При этом я бы уточнил два момента. Речь здесь всё-таки не про useEffect с пустым массивом, а про эффект с зависимостью от изменившегося prop, например [items]. И сам React рассматривает обновление состояния во время рендера скорее как запасной вариант: сначала рекомендует проверить, нельзя ли сбросить состояние через key или вообще не хранить корректируемый объект в состоянии.
В статье я показал именно последний вариант: хранить selectedId, а актуальный selection вычислять из нового списка. Но согласен, что условный setState во время рендера стоит добавить в чек-лист как отдельный допустимый вариант для случаев, когда состояние нельзя просто вычислить. Обновил и чек-лист.
Спасибо большое! Очень приятно, что статья не просто попала в закладки, но ещё и стала поводом для омаж-материала.
Прочитал статью — получилось действительно интересно. Я сам с $mol в боевых проектах не работал, поэтому было особенно любопытно посмотреть на похожую тему через другую призму и сравнить подходы со своей статьёй. Как раз такие материалы хорошо расширяют взгляд: видно, что одну и ту же задачу можно разложить и решить совсем по-разному.
Спасибо, что поделились. Буду рад продолжению и новым материалам — тема точно заслуживает обсуждения.
Для данных с внешней границы schema-валидация действительно более надёжный путь: zod/yup позволяют один раз разобрать ответ на входе и дальше уже работать не с «DTO, которому поверили», а с проверенным значением. Именно это я и пытался показать в части про границу приложения: снаружи unknown, дальше parse/schema, внутри — нормальный тип.
Единственное, я бы чуть уточнил формулировку про «гарантированно правильный тип»: гарантия появляется, когда схема становится источником истины и тип выводится из неё, например через z.infer. Если DTO и схема живут отдельно, между ними тоже возможен drift.
А про satisfies замечание принимаю. В статье я затронул его скорее как замену as для конфигов, карт, палитр и похожих объектов, но тему действительно можно раскрыть шире: где он помогает сохранить литеральные типы, где проверяет полноту ключей, а где не заменяет runtime-валидацию. Возможно, вынесу это в отдельный материал или дополню пример.
Спасибо за идею — добавил CR-05 с правом
cart.items.addи отдельный тест. Гипотеза подтвердилась частично: в cargo проверка прав действительно проходит через запрещённую связьentity → feature, но новых нарушений не появилось — использовалась уже существующая плохая граница. Добавил в статью результаты и сравнение графов до/после изменения.Спасибо, хороший вопрос — Вы как раз попали в одно из ограничений текущего стенда.
В этой версии авторизация не выделена в отдельную категорию и системно не разложена по всем шести вариантам. Кейс с утекшими проверками прав во вступлении был исходной мотивацией, но в измерительную часть вошли другие изменения: переиспользование карточки, удаление промокодов, кэширование каталога и правило доставки. Размещение сквозных политик стенд увы не сравнивает.
Концептуально я бы рассматривал
policies/не как седьмой вариант архитектуры, а как ортогональную границу. При этом полезно разделить получение текущей роли, само правило видаcanChangeLimit(user, card)и его применение в UI. В Clean такое правило может находиться в domain/application, в modular — рядом с модулем-владельцем, а в FSD — рядом с owning-слайсом с композицией выше. Отдельный общийpolicies/тоже выглядит рабочим решением, если он содержит узкие правила, а не превращается со временем во второйshared.Ваш эксперимент с корзиной звучит интересно. Отдельный change request на права доступа — например, добавление новой роли или изменение политики без размазывания проверок по UI — был бы хорошим дополнением к стенду. Спасибо за идею, возьму её в список следующих сценариев.
Спасибо за дополнение! Да, такой вариант в официальной документации React действительно есть, и для полноты его стоило упомянуть. Обновил пункт 4, согласно комментарию и документации.
При частичной корректировке состояния React допускает условный
setStateнепосредственно во время рендера. В таком случае текущий результат рендера отбрасывается, и React сразу повторяет рендер до обновления DOM, поэтому дочерние компоненты не успевают отрисоваться с устаревшим значением.При этом я бы уточнил два момента. Речь здесь всё-таки не про
useEffectс пустым массивом, а про эффект с зависимостью от изменившегосяprop, например[items]. И сам React рассматривает обновление состояния во время рендера скорее как запасной вариант: сначала рекомендует проверить, нельзя ли сбросить состояние черезkeyили вообще не хранить корректируемый объект в состоянии.В статье я показал именно последний вариант: хранить
selectedId, а актуальныйselectionвычислять из нового списка. Но согласен, что условныйsetStateво время рендера стоит добавить в чек-лист как отдельный допустимый вариант для случаев, когда состояние нельзя просто вычислить. Обновил и чек-лист.Спасибо!
Спасибо большое! Очень приятно, что статья не просто попала в закладки, но ещё и стала поводом для омаж-материала.
Прочитал статью — получилось действительно интересно. Я сам с
$molв боевых проектах не работал, поэтому было особенно любопытно посмотреть на похожую тему через другую призму и сравнить подходы со своей статьёй. Как раз такие материалы хорошо расширяют взгляд: видно, что одну и ту же задачу можно разложить и решить совсем по-разному.Спасибо, что поделились. Буду рад продолжению и новым материалам — тема точно заслуживает обсуждения.
Спасибо за комментарий, по сути согласен.
Для данных с внешней границы schema-валидация действительно более надёжный путь:
zod/yupпозволяют один раз разобрать ответ на входе и дальше уже работать не с «DTO, которому поверили», а с проверенным значением. Именно это я и пытался показать в части про границу приложения: снаружиunknown, дальше parse/schema, внутри — нормальный тип.Единственное, я бы чуть уточнил формулировку про «гарантированно правильный тип»: гарантия появляется, когда схема становится источником истины и тип выводится из неё, например через
z.infer. Если DTO и схема живут отдельно, между ними тоже возможен drift.А про
satisfiesзамечание принимаю. В статье я затронул его скорее как заменуasдля конфигов, карт, палитр и похожих объектов, но тему действительно можно раскрыть шире: где он помогает сохранить литеральные типы, где проверяет полноту ключей, а где не заменяет runtime-валидацию. Возможно, вынесу это в отдельный материал или дополню пример.