EvApps – Telegram
EvApps
203 subscribers
1.23K photos
50 videos
1 file
238 links
IT-aутстафферы из Тулы💚
https://evapps.ru/

Здесь пишем про веб- и мобильную разработку

▶️ Наш чат для системных аналитиков: https://news.1rj.ru/str/pro_sa_evapps

▶️ Посмотреть, как мы живём: https://vk.com/evapps
Download Telegram
Роман_Бушняков_Презентация_к_вебинару.pdf
2 MB
Ловите презентацию к вебинару❗️
👍51🙏1
Media is too big
VIEW IN TELEGRAM
🎙 Запись второго выпуска нашего Подкаста IT-тоLк уже доступна!

💡 В этом выпуске наш системный аналитик Олег и мобильный разработчик Андрей делятся личным опытом как войти в IT , с чего начать и как выбрать направление, где и как учиться и как получить первую стажировку и работу, поделятся практическими советами и лайфхаками для новичков.

Найти Подкаст можно тут 👉 https://clck.ru/3Lv5x6
🔥61
🖐🏻Привет всем! Приглашаем на наш вебинар "Методы планирования – как успевать больше без стресса", который будет полезен для всех!
Мы поделимся проверенными методами планирования, которые помогут вам организовать свое время и увеличить продуктивность!

🔑 Что узнаете на вебинаре?
• Как метод «Съешь лягушку» поможет вам справиться с самыми сложными задачами.
• Правило 1-3-5, как правильно расставлять приоритеты.
• Timeboxing и метод Pomodoro для эффективного управления временем.

🚀 Вы научитесь избегать основных ошибок в планировании:
• Переоценка своих сил
• Отсутствие приоритетов
• Прокрастинация и «пожиратели времени»

📅 29 мая
🕒 18:30 (Мск)
👩🏻‍🦱 Виктория Павлюкова- системный аналитик
🔗 Регистрация на вебинар
🔥52
Бета-релиз Laravel-плагина для VS Code

Команда Laravel представила официальное расширение для Visual Studio Code, и в его описании есть любопытная деталь:

> This extension will occasionally boot your app in the background to collect information about your app for use in autocompletion, linking, hovering, and diagnostics

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

Традиционные инструменты, такие как PhpStorm, Laravel Idea и другие IDE, полагаются на статический анализ, который не всегда справляется с «магией» PHP. Например, плагин MetaStorm требует явно описывать динамику и конвенции в специальном синтаксисе.

Может ли runtime-анализ (динамический запуск приложения) помочь редактору лучше понять код по сравнению со статическим подходом? Интуитивно — да!

Мы считаем, что динамический анализ, в теории, имеет огромный потенциал. Особенно для сложных проектов, где статический анализ не всегда дает точную картину. Но, как это бывает с большинством новых технологий, важно подождать, пока плагин выйдет из бета-версии, станет более стабильным и легким в настройке. В идеале, если бы плагин интегрировал динамический и статический подходы, это было бы отличным решением для улучшения работы с Laravel-проектами.

А как считаете вы?

Поэтому следим за его развитием и ждем стабильного релиза, прежде чем интегрировать его в повседневную разработку.

🔗 Подробнее на Marketplace

#evapps_news
🔥4
🙌🏻Привет! На связи Юра, разработчик компании EvApps. На днях прочитал книгу Роберта Мартина "Идеальная работа" (или "Чистое мастерство") — пятую в серии "Чистое программирование".

Вот несколько важных моментов, которые точно стоит учесть:

📚 Мастерство: В будущем программисты не смогут просто списывать свои ошибки на неопытность. Бизнес и общество будут требовать от нас качественного кода, и работать в этой индустрии будут только настоящие мастера.

🧪 TDD и тестирование: TDD (разработка через тестирование) — это основа. Мартин подробно рассказывает, как с помощью тестов и маленьких итераций можно писать реально рабочий код. Тесты здесь — это почти как документация, только лучше.

🔄 Рефакторинг: Рефакторинг — это не просто улучшение кода, а его улучшение без изменения поведения. Мартин советует быть смелым: не бойтесь переименовывать переменные и делать код понятным. Если код не читается как книга, это уже проблема.

🎨Дизайн и принципы: Не нужно делать лишнего. Следите, чтобы код был тестируемым и минимизируйте дублирование. Мартин советует придерживаться принципа YAGNI (You Aren’t Gonna Need It) — не добавляйте то, что вам не нужно.

👥Совместное программирование: Работать в паре — круто. Это помогает улучшать качество кода, особенно если оба разработчика опытные и готовы учиться друг у друга.

⚖️Этика программиста: Не забывайте про свою ответственность за код. Если вы не берете ответственность за возможные ошибки в программе, значит, вы не профессионал. Важно всегда быть честным и не бояться признаться, что что-то не знаете.

📈Качество и производительность: Качество — это не что-то, что можно достичь за один раз. Оно требует постоянного улучшения, а производительность должна быть стабильной. Не забывайте учиться и не стесняйтесь просить помощи, когда нужно.

📖 Советую прочесть всем, кто хочет расти как профессионал! А если уже читали — давайте обсудим в комментах. 👇
#evapps_польза
🔥8👍1
😊Привет, я Таня Драбовская, PHP-разработчик Evapps. Сегодня поговорим про технические аспекты кастомизации и масштабирования платформы Nextcloud!

🚀 Nextcloud представляет собой модульную клиент-серверную платформу, ориентированную на развёртывание приватных облачных решений.

Базовая функциональность включает:
- файловое хранилище,
- контроль доступа,
- веб-интерфейс,
- систему авторизации.

Архитектура построена на PHP с использованием собственного App Framework. Фронтенд реализован на Vue.js .
Серверная часть поддерживает интеграцию с MariaDB, PostgreSQL , Redis , S3-хранилищами, внешними файловыми системами и кеширующими решениями (OPcache, file-based cache).
Платформа поддерживает гибкую кастомизацию за счёт API, системы событий и разработки собственных модулей.

☝️Рассмотрим два основных кейса:

1️. Автоматическая сортировка файлов на основе MIME-типов
В рамках проекта была реализована логика автоматической сортировки загружаемых файлов на основе MIME-типов. Решение оформлено в виде отдельного приложения, использующего хук postWrite файловой подсистемы. При загрузке файл классифицируется и перемещается в предопределённую директорию (/Documents , /Images , /Videos ). UI-часть реализована на Vue.js ; конфигурация осуществляется через API и административную панель.

2️. Оптимизация полнотекстового поиска с использованием Elasticsearch
Для повышения удобства работы с хранилищами большого объёма был внедрён механизм полнотекстового поиска на базе Elasticsearch.

🔎 Ключевые технологии полнотекстового поиска:

• fulltextsearch — модуль Nextcloud, управляющий процессами индексации и поиска;
• fulltextsearch_elasticsearch — компонент для интеграции с Elasticsearch;
• Elasticsearch — внешний высокопроизводительный поисковый движок.

⚠️Проблемы стандартной реализации, с которыми мы столкнулись при работе:

• продолжительное время индексации при больших объёмах файлов (сотни тысяч документов)
• высокая нагрузка на центральный процессор сервера
• потенциальная деградация производительности и доступности сервиса для конечных пользователей

🛠Для минимизации задержек и снижения деградации производительности мы провели оптимизацию:

✔️ Распараллелили процесс индексации:
• внедрили асинхронный HTTP-клиент для отправки данных в Elasticsearch
• реализовали пакетную отправку данных (batch-запросы) по 500–1000 документов
• добавили обработку ошибок и механизм повторных попыток (retry)

✔️ Оптимизировали взаимодействие с базой данных Nextcloud:
• перешли с одиночных SQL-запросов на bulk INSERT
• использовали постоянные соединения к базе данных (persistent connections)

✔️ Донастроили Elasticsearch:
• отключили неиспользуемые в индексе поля для уменьшения объёма
• применили ngram-анализатор для ускоренного поиска коротких фрагментов текста

🎯 Комплексная оптимизация процессов индексации и поиска в Nextcloud позволила существенно повысить эффективность работы системы и снизить нагрузку на серверные ресурсы. Это обеспечило стабильную производительность при масштабной эксплуатации.

Готова ответить на ваши вопросы! 😊
4🔥4
Готов третий эпизод нашего подкаста - на этот раз обсудили "боли" рекрутеров, "художества" в резюме и отличие "мясных" резюме от тех, которые сочинил ChatGPT, с нашим руководителем отдела по работе с персоналом Александрой Радиной 💪

👀 Смотрим в нашем сообществе в ВК: https://vk.com/video-78780379_456239279
🔥101
Всем привет!
На связи снова разработчики EvApps💪
Сегодня поговорим про DTO (Data Transfer Objects), а именно разберем, зачем и как использовать его в Laravel.

⭕️ DTO (Объект Передачи Данных) - это шаблон проектирования, используемый для передачи данных между уровнями в программной архитектуре. Основная цель DTO - отделить различные уровни или компоненты приложения, позволяя им взаимодействовать друг с другом, не вникая в детали реализации друг друга.

Итак, DTO - это простой объект передачи данных, который помогает отделить и изолировать компоненты друг от друга.

Если мы знаем структуру данных используемую в конкретном участке кода, то нам легко его поддерживать и изменять, тут нам и помогает DTO.

❇️ Например, код контроллера сохранения статьи:

public function store(Request $request): JsonResponse
{
return response()->json([
$this->service->createArticle($request->all()),
Response::HTTP_CREATED
]);
}


В данном примере мы не знаем, что вернет метод $request->all().

Мы можем создать свой класс CreateArticleRequest и, при необходимости, смотреть, что он возвращает. Но теперь валидация данных связана с HTTP Request, и если нам нужно вызвать метод createArticle в другом месте кода, то нужно будет вручную передавать объект CreateArticleRequest. К тому же, класс CreateArticleRequest вернёт массив полей и мы не можем принудительно указать тип данных передаваемых в метод createArticle.

Используя DTO мы решим проблемы описанные выше.

⭕️ Как использовать?
Как мы сказали выше, DTO - это простой объект для сопоставления свойств.

❇️ Создадим класс DTO:

final readonly class CreateArticleDTO
{
public function __construct(
public string $noscript,
public string $denoscription,
public string $body,
) {}
}


В объявлении класса DTO используем ключевые слова final readonly, то есть запрещаем наследовать класс DTO и переопределять свойства объекта, поэтому после создания класса DTO его контекст нельзя будет изменить, и мы можем быть уверены, что получим на вход именно нашу DTO, которую указали в контракте метода createArticle. Эти действия позволят нам использовать контекстный объект и добавить безопасность типов.

Контроллер теперь выглядит вот так:

public function store(Request $request): JsonResponse
{
return response()->json([
$this->service->createArticle(new CreateArticleDTO(...$request->all())),
Response::HTTP_CREATED
]);
}


Благодаря именованным аргументам в PHP8 мы легко создаем экземпляр CreateArticleDTO, используя конструкцию new CreateArticleDTO (...$request->all())

Такой подход использования DTO позволяет решить проблемы:

Мы всегда знаем какие данные получит метод;
Мы явно указываем тип переданных данных;
Мы не привязаны к объекту CreateArticleRequest и можем вызвать createArticle в любом месте нашего кода.

Теперь код стал более качественным и поддерживаемым👍

А вы в своих Laravel-проектах используете DTO или работаете напрямую с массивами/Request?

#PHP #Laravel #DTO #backend #паттерны_проектирования #чистый_код #туториал
🔥3🤔1
👋 Всем привет!

В прошлых постах мы говорили про различные системы и инструменты, которые помогают решать задачи разработчика.

А сегодня поговорим о том, как в Bitrix можно организовать компонент не просто для отображения, а как полноценный контроллер с CRUD-операциями.

Обработчик запросов в классе компонента (файл class.php) позволяет:

Инкапсулировать весь код в одном классе
Повторно использовать методы, данные и параметры компонента
Использовать языковые фразы, шаблоны компонента
Переопределять в компонентах-потомках стандартное поведение

Чтобы класс компонента мог обрабатывать запросы, необходимо:

▶️ Реализовать интерфейс \Bitrix\Main\Engine\Contract\Controllerable

▶️ Определить методы-действия с суффиксом Action

▶️ Реализовать метод configureActions (обычно возвращает пустой массив — конфигурацию по умолчанию)

▶️ Если нужно добавлять, обрабатывать ошибки, то стоит реализовать \Bitrix\Main\Errorable

При выполнении компонента в аяксовом режиме выполняются последовательно:

1️⃣CBitrixComponent::onIncludeComponentLang

2️⃣ CBitrixComponent::onPrepareComponentParams

Запуск действия с фильтрами:
<?php

namespace local\components\vendor\example;

use CBitrixComponent;
use Bitrix\Main\Error;
use Bitrix\Main\Engine\Contract\Controllerable;

if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();

class ExampleComponent extends CBitrixComponent implements Controllerable
{
public function executeComponent()
{
// этот код не будет выполняться при запуске ajax-действий
}

public function configureActions()
{
return [];
}

public function onPrepareComponentParams($arParams)
{
// подготовка параметров
}

public function createAction(array $fields): ?array
{
$example = Example::add($fields);
if (!$example) {
$this->addError(new Error('Could not create example.', {код_ошибки}));
return null;
}
return $example->toArray();
}

public function viewAction(int $id): ?array
{
$example = Example::getById($id);
if (!$example) {
$this->addError(new Error('Could not find example.', {код_ошибки}));
return null;
}
return $example->toArray();
}

public function listAction(array $fields): ?array
{
$examples = Example::getList($fields);
return array_map(static fn ($example) => $example->toArray(), $examples);
}

public function updateAction(int $id, array $fields): ?array
{
$example = Example::update($id, $fields);
if (!$example) {
$this->addError(new Error('Could not update example.', {код_ошибки}));
return null;
}
return $example->toArray();
}

public function deleteAction(int $id): ?array
{
$example = Example::delete($id);
if (!$example) {
$this->addError(new Error('Could not delete example.', {код_ошибки}));
return null;
}
return $example->toArray();
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1
👋 Всем привет

Сегодня мы поговорим про CSS и как правильно настроить загрузку шрифтов с помощью дескриптора font-display в @font-face.
Этот дескриптор важен для управления тем, как будет отображаться текст до того, как шрифт будет загружен.

@font-face {
  font-display: auto;
  font-display: block;
  font-display: swap;
  font-display: fallback;
  font-display: optional;
}


🔑 Параметры для font-display:

* auto — поведение по умолчанию, зависит от браузера.
* block — текст скрыт до 3 секунд; если шрифт не загрузился, показывается запасной, потом текст перерисовывается. Плюс: текст с нужным шрифтом без «скачка». Минус: может быть невидимым, может сильно ухудшить UX и LCP.
* swap — сразу показывается запасной шрифт, после загрузки шрифта происходит замена. Плюс: текст виден, улучшает UX и SEO. Минус: возможен визуальный «скачок».
* fallback — скрытие 100 мс, потом запасной шрифт; если основной не загрузился через 3 с, остаётся запасной. Замена на загруженный шрифт без перезагрузки не произойдёт.
* optional — скрытие 100 мс, затем запасной шрифт; замена на основной возможна только после обновления страницы.

Рекомендация: чаще всего используйте swap (он стоит по умолчанию в Google Fonts), а если необходимо избежать мелькания текста, выбирайте optional.

Материалы:
MDN Web Docs — font-display
W3C — CSS Fonts Module Level 4

Как вы настраиваете `font-display` в своих проектах?

#frontend #CSS #UIUX #WebDev
🔥4
Привет всем!

🚀 Сегодня запускаем серию постов, в которых будем подробно разбирать паттерны интеграции ограниченных контекстов. Для начала поговорим о трех подходах, которые играют ключевую роль в организации взаимодействия между командами и контекстами.

Cooperation 🌐
Этот паттерн идеально подходит для команд с устоявшимися коммуникациями. Это может быть одна команда или несколько команд с взаимозависимыми целями, когда успех одной зависит от успеха другой. Главное здесь — это качественная взаимодействие между участниками процесса.

Partnership 🤝
В этом случае команды работают совместно, без диктата одной команды над другой. Если нужно внести изменения в контракты, команды договариваются и оперативно внедряют изменения, что позволяет получить быструю обратную связь. Однако для распределённых команд этот паттерн может стать проблемой из-за сложности в коммуникации.

Shared Kernel 🧩
Иногда модели, ограниченные контекстом, частично реализованы в разных контекстах. Однако важно, чтобы общее ядро удовлетворяло требованиям обоих контекстов и оставалось минималистичным, чтобы избежать каскадных изменений. В идеале, общее ядро должно содержать только те элементы, которые необходимы для интеграции, и изменения требуют обязательных тестов в обоих контекстах.

В следующем посте продолжим рассматривать, когда и как применять Shared Kernel и перейдем к другим паттернам интеграции!

#development #паттерны #boundedcontext #cooperation #sharedkernel #Partnership
1
Привет снова 👋
Продолжаем нашу серию постов о паттернах, и сегодня поговорим о трех интересных паттернах интеграции, которые помогут наладить взаимодействие между контекстами в условиях автономности команд.

Customer-Supplier 🏷🔗
Этот паттерн можно представить как поток: контекст Customer находится ниже по течению, а Supplier — выше. В отличие от кооперативных паттернов, здесь обе стороны могут решать свои задачи независимо. Однако это может создать дисбаланс во взаимоотношениях.

Conformist 🔄
Здесь Customer принимает контракты, предложенные Supplier, не имея возможности их изменять. Этот паттерн часто встречается в случае использования внешних сервисов или когда Supplier определяет отраслевой стандарт, который должен быть принят всеми контекстами, расположенными ниже.

Anticorruption Layer 🛡🔄
Когда Customer не соглашается с контрактами Supplier, он создает внутренний слой, который трансформирует контракты Supplier в те, которые отвечают потребностям Customer. Этот слой защищает бизнес-логику Customer от внешних изменений и помогает адаптировать контракты под нужды конкретного контекста.

Завершим нашу серию постов в следующем посте, расскажем про Open-Host Service и Separate Ways.

#development #паттерны #customersupplier #anticorruptionlayer #Conformist #boundedcontext
🆒3
Media is too big
VIEW IN TELEGRAM
С пятницей, коллеги!

Сегодня разбавляем серьезный контент... наболевшим🤯

В новом эпизоде нашего подкаста IT ToLк by EvApps системный аналитик Олег и мобильный разработчик Андрей разгоняют про боли и слёзы айтишников.

▶️ Четвертый эпизод уже в ВК - https://vk.cc/cPE3fD
🔥5😁1
Привет, друзья 👋
В этом посте завершаем нашу серию и рассмотрим два последних паттерна, которые могут быть полезны в ситуациях, когда требуется особая защита и автономность для контекстов.

Open-Host Service 🌐🔐
Этот паттерн противоположен Anticorruption Layer. Здесь Supplier создает защитный слой, чтобы обезопасить своих пользователей от изменений в своей системе. Он использует публичные контракты (published language), которые помогают изолировать изменения внутри Supplier и позволить ему развиваться автономно от нижележащих контекстов.

Separate Ways 🛑🚶‍♂️
Последний тип взаимодействия, по сути, исключает само взаимодействие между командами. Этот паттерн применяется в случаях, когда команды не могут или не хотят взаимодействовать по различным причинам.

Такая ситуация может возникнуть, если из-за организационных или политических факторов достижение согласия между командами занимает много времени и значительно увеличивает стоимость разработки. Также, если затраты на дублирование и поддержку функциональности (чаще всего это касается generic subdomains) ниже, чем на разработку общего решения и интеграцию между контекстами.

Иногда модели ограниченных контекстов настолько отличаются друг от друга, что использование паттернов типа Customer-Supplier становится слишком дорогим в реализации и обслуживании. В таких случаях проще и выгоднее просто продублировать функциональность, чем пытаться интегрировать её в рамках общего контекста.

Примечание: ⚠️ Следует избегать паттерна Separate Ways в реализации core subdomains.

#development #паттерны #openhostservice #separateways #boundedcontext
Привет 👋

💡 Сегодня разбираем базовую, но важную тему в Git — три способа интеграции изменений между ветками: Merge, Rebase и Fast-Forward.
Каждый из них влияет на историю коммитов и рабочий процесс команды.

🔀Merge
Объединяет изменения из одной ветки в другую, создавая отдельный merge-коммит.
Вид ветки: сохраняет полную и разветвлённую структуру — видно, где ветки расходились и сходились.
Когда использовать: при объединении фич в main ветку, когда важно сохранить контекст разработки, особенно в командной работе.

♻️Rebase
Переносит коммиты ветки на новую, обычно на актуальное состояние main ветки.
Вид ветки: становится линейной, без merge-коммитов — будто работа шла поверх main ветки.
Когда использовать: удобно для локальных веток, чтобы очистить историю перед слиянием.

Fast-Forward Merge
Происходит, если основная ветка не расходилась с твоей. В этом случае Git перемещает указатель вперёд без создания нового коммита.
Вид ветки: полностью линейная, как после rebase.
Когда использовать: если в целевой ветке не было других изменений. Можно указать флаг --ff-only.

📚Отличия:
Структура ветки: git merge сохраняет разветвлённую структуру с merge-коммитами; git rebase создаёт линейную структуру, переписывая коммиты; fast-forward даёт линейную структуру, перемещая указатель.

ID коммитов: git merge сохраняет оригинальные ID коммитов; git rebase создаёт новые ID для перебазированных коммитов.

Безопасность: git merge обычно безопаснее для общих веток, так как не переписывает историю; git rebase следует использовать с осторожностью на общих ветках из-за переписывания истории.

Выбирайте учитывая ваши рабочие процессы и приоритеты команды — что важнее: чистая история или точное сохранение контекста разработки.

🖥 Попрактиковаться с ветками и коммитами можно на интерактивном тренажёре: Learn Git Branching

#git #development #merge #rebase #fastforward #workflow
👍5
Сегодня нейросетям всё чаще доверяют писать и править код, чтобы ускорить разработку.
Но нередко результат — день, потраченный на устранение хаоса.
Этот кейс — не обвинение ИИ, а напоминание: важно понимать, с чем мы работаем

💡 Почему нейросети ломают код?
Нейросеть — не разработчик, а языковая модель.
Она не понимает код — она предсказывает, что выглядит как правильный ответ.
Ее цель — звучать уверенно, а не быть точной.
Поэтому она может предложить «исправление», которое в итоге ломает всё.
Она видит не систему, а текст — и делает то, что статистически похоже на решение.

📘 1. Оптимизирован не под правду, а под уверенность.
Модель обучена звучать убедительно, даже если ошибается.
Её «награда» — не корректность, а ощущение правильности.

💻 2. Не тестируют и не исполняют.
Разработчик проверяет код, запускает тесты, видит окружение и файлы проекта.
AI-ассистенты, даже встроенные в редактор, могут «видеть» файлы и окружение, но не запускают код и не проверяют его работу.
Они просто предсказывают, как может выглядеть «фикс» — не зная, сработает ли он на самом деле.

🧠 3. Не помнит, а делает вид, что помнит.
Контекст диалога ограничен — старые детали теряются.
Но вместо того чтобы признаться, ИИ «достраивает» логику самостоятельно, будто всё под контролем.

⚙️ Нейросети не ломают системы специально.
Они делает это, потому что не понимают, что такое система.
Они не видят ваших дедлайнов, пользователей, окружения — только текст.
А когда текст становится единственной мерой истины, реальность перестаёт иметь значение.

ИИ не должен заменять разработчиков — ему нужны разработчики, которые помнят, как выглядит реальность.
Используйте его, чтобы усиливать свои навыки, а не подменять их.
Потому что в тот момент, когда вы отдаёте ему свой код — вы отдаёте ему контроль.

#ai #development #code #workflow #risk #vibe_coding
🏆1
Forwarded from Двач
This media is not supported in your browser
VIEW IN TELEGRAM
ChatGPT, когда в очередной раз выдал говёный код с ошибкой:
Всем привет🖐
Недавно, у нас возникла идея рассмотреть lazy loading не только как инструмент оптимизации, но и как возможный способ защиты чувствительного кода.

Lazy-loading — это способ загружать модули, компоненты или шаблоны только тогда, когда они действительно нужны, а не при первом запуске приложения.
В React и других фреймворках это реализуется через:
- разделение модулей,
- конфигурацию роутов,
- отложенную загрузку компонентов.

Преимущества стандартны:
⚡️ быстреее начальная загрузка
📉 меньше трафика
🚀 выше производительность

В React это реализуется через React.lazy() и Suspense:
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
return (
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
);
}

Такое разбиение кода уменьшает размер бандла и повышает скорость загрузки.

Во время разбирательств, мы заметили странную вещь — почти ни один фреймворк не упоминает lazy-loading в контексте безопасности. Только как оптимизацию.

Но если задуматься:
В серверно-рендеримых приложениях чувствительный код не возвращается клиенту, пока пользователь не прошёл аутентификацию.
В SPA всё иначе — весь код загружается сразу, даже тот, что должен быть доступен только после входа.

Lazy-loading позволяет решить это:
мы можем не загружать части приложения с чувствительной логикой до тех пор, пока пользователь не авторизован.

Вот пример с использованием OAuth2-библиотеки для клиентской аутентификации:
<AuthenticatedTemplate>
<p>Вход выполнен как: {user?.username}</p>
</AuthenticatedTemplate>

Вместо простого текста здесь может быть целый <ComplexApp /> — с десятками килобайт JS, потенциально раскрывающих уязвимости.

Решение: оборачивать такие блоки в <Suspense> и загружать их только после подтверждённой аутентификации.

Классическое SPA грузит всё и сразу, включая закрытый функционал.
Lazy-loading — загружает только то, что нужно конкретному пользователю в данный момент.

Это не «панацея» для безопасности, но важный слой защиты:
Чем меньше кода попадает в браузер, тем меньше поверхность атаки.

- Должны ли мы использовать lazy-loading не только ради скорости, но и ради защиты кода?
- Да. Определённо должны.

🧠 А вы что думаете? Встречали такой способ использования lazy-loading?

#webdev #security #architecture #frontend #development
3🔥3
Представьте: утро, обычный рабочий день.
Открываешь приложение — и что-то не так.
База не поднимается. Файлы повреждены. Или какой-то баг просто всё удалил.

В голове сразу мысль: «Ладно, не страшно — есть же бэкапы».
Но при попытке восстановить — тишина.
Архивы пустые, повреждённые или восстанавливаются бесконечно.

Горькая правда:
бэкап ничего не стоит, пока ты не попробовал его восстановить.

Недавно у одной из команд случилась такая история.
Меняли схему базы данных в одном из проектов, и во время миграции что-то пошло не так — SQLite база повредилась.
Попробовали развернуть резервную копию — но и она оказалась битой.

Позже выяснилось, что копирование шло в тот момент, когда приложение ещё писало данные.
Система месяцами создавала битые бэкапы — и никто не знал, потому что восстановление ни разу не проверялось.

К счастью, это были тестовые данные. Но если бы прод?
Пользовательские данные, проект, репутация — всё под угрозой.

Часто живёшь в иллюзии, что раз бэкап есть — значит, всё под контролем.
На деле это копия, которая может не сработать в тот момент, когда она нужна.

Что важно бэкапить:
🧠 Код — GitHub, GitLab
🗄 Базу — Postgres, MySQL, Supabase, SQLite
🖼 Файлы пользователей — изображения, документы
🔐 Конфиги и секреты — .env, API-ключи, настройки деплоя

Главная ошибка:
ты не знаешь, работает ли бэкап, пока не попробуешь восстановление.
Без этого — он как кот Шрёдингера, запертый в коробке.

Как делают большие компании:
— GitLab ежедневно тестирует восстановление и следит за метриками
— Basecamp проводит «тесты катастроф» — симулирует исчезновение датацентра

Типовая схема:
• Делать бэкапы автоматически (ночные дампы, снапшоты)
• Восстанавливать в тестовую среду
• Проверять: база поднимается, файлы читаются, логин работает (плюс smoke-тесты)
• Отправлять алерты при сбоях
• Периодически симулировать сбой и измерять скорость восстановления

Что и как проверять:
💻 Код: Push в GitHub/GitLab (с 2FA) → клонировать в новую папку и собрать проект
🗄 База данных: pg_dump / .backup / PITR → восстановить в тестовую БД и проверить данные
🖼 Файлы пользователей: S3 / B2 / GCS → случайно скачать несколько файлов и открыть
🔐 Конфиги и секреты: 1Password / Bitwarden / VeraCrypt → запустить проект, используя только эти конфиги

💡 Для SQLite:
копирование живой .db может её повредить.
Используй:
sqlite3 mydb.db "VACUUM INTO backup.db"

Так создаётся чистая копия без ошибок.

Когда тестировать восстановление:
— Раз в месяц: локально проверить случайный бэкап
— Раз в квартал: полный тест — база + файлы + приложение
— Раз в год: симулировать потерю устройства и попробовать вернуть

Почему это важно:
Один сбой может уничтожить проект, если вы не проверяли восстановление.

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

Потому что бэкапы — это не паранойя.
Это способ быть уверенным, что завтра твой проект не исчезнет. ❤️

#backup #development #risk #code
7
🚀 Почему dev-серверы часто запускаются на localhost:3000 (и сейчас ещё на 5173)

Когда ты запускаешь сервер localhost:3000 или localhost:5173, это не случайность.
За этими портами — история веб-разработки: от Ruby on Rails и Java до Node.js и Vite.

💡 Что такое порт?
Порт — это номер, по которому на компьютере слушает сервис.

Представь, что твой компьютер — это здание, а порты — двери с номерами.
Когда ты заходишь на localhost:3000, ты буквально открываешь дверь № 3000, чтобы увидеть своё приложение.

Всего таких дверей 65 535:
🔹 0–1023 — системные (HTTP 80, HTTPS 443, SSH 22)
🔹 1024–49151 — пользовательские (3000, 8000, 8080 и др.)
🔹 49152–65535 — временные (используются ОС)

Так что 3000 — просто одно из множества возможных значений.

⚙️ Порт 3000 — путь от Rails к Node.js
В Ruby on Rails по умолчанию сервер разработки запускался на 3000.

Позже, с ростом Node.js и Express, в официальных примерах часто встречалась строка:
app.listen(3000, () => console.log('Server running on port 3000'));

Эта привычка закрепилась: её копировали в туториалах, курсах и шаблонах.
React, Next.js и другие фреймворки просто продолжили эту традицию.

Сегодня 3000 — неофициальный “Hello World” порт веб-разработки.

🐍 Порт 8000 — классика Python
Ещё до Node, Python-разработчики поднимали локальные HTTP-сервера командой:
python3 -m http.server

По умолчанию сервер слушал 8000 — безопасный номер, не требующий прав администратора.

Фреймворк Django тоже выбрал этот порт.
Со временем 8000 стал синонимом “запустил и проверил локально”.

☕️ Порт 8080 — наследие Java
В 90-х порты ниже 1024 требовали root-прав.
Java-разработчики из Apache Tomcat и Jetty придумали обход:
80 → 8080

Выглядит похоже, но работает без повышенных прав.
С тех пор 8080 стал стандартом для “серьёзных” серверов вроде Spring Boot.

⚡️ Порт 5173 — современный штрих от Vite
Когда появился Vite, авторы выбрали порт с пасхалкой:
51 = VI
73 = TE
👉 5173 = VITE 😎

Теперь каждый npm run dev открывает localhost:5173 — фирменный почерк нового поколения фронтенда.

🧠 Можно ли использовать другие порты?
Конечно!

Многие привыкают к 3000 и паникуют, увидев:
Error: Port 3000 already in use

Но свободных портов тысячи.
Попробуй:
npm run dev -- --port=42069
vite --port=13337

И никаких конфликтов 😄

🕰 Заключение

8080 — обход ограничений Java
8000 — прагматичный выбор Python
3000 — наследие Rails и Node.js
5173 — фирменный порт Vite

Эти цифры — не просто числа.
Это часть истории веб-разработки с 90-х годов.

Когда в следующий раз запустишь:
👉 http://localhost:3000/
вспомни — за этим числом десятилетия привычек и технологий.

Если порт занят — не убивай процесс.
Просто выбери другое число.
Сделай его своим фирменным портом 😉

Безопасный диапазон: 1024–49151
И когда будешь запускать сервер — делай это с уважением😁

А вы оставляете порт по умолчанию или меняете на свой?

#development #webdev #frontend #backend
👍5🔥1
🚀 Наши друзья из Intelsy проводят вебинар для тех, кто руководит ИТ и хочет навести порядок в хаосе 1С-проектов - а мы такое всецело поддерживаем!

Тема: Будни ИТ-директора: стабильность, быстродействие, борьба с 1С

Дата: 6 ноября в 11:00 по мск

Формат: открытый разговор без маркетинговых лозунгов

О чем поговорим:
– какие вопросы тянет на себе ИТ-директор;
– зачем нужны внешние спецы при собственном штате;
– к кому обращаться за ресурсами и как не ошибиться;
– как работает обращение к внешним ресурсам и что остается за кадром.

📍 Регистрация — по ссылке, без спама и рассылок.

Вебинар
Вебинар
Вебинар

🔥 Залетай, если хочешь меньше хаоса и больше стабильности в своих 1С-проектах.