Кальтер / Блог

Как создать веб-приложение с ИИ: прототип, данные и запуск

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

Материал подготовлен с помощью ИИ; источники и расчёты проверены редакцией ZASLON.

Веб-приложение требует связать интерфейс, данные и серверную логику; на схеме: Экран и сценарий, Модель данных, Серверный маршрут.
Редакционная схема ZASLON. Условная иллюстрация механизма; не рыночные данные и не интерфейс сервиса.

Рассмотрим веб-приложение для обработки входящих заявок небольшой команды. Сотрудник должен создать заявку, назначить исполнителя и менять статус; другой участник видит только доступные ему записи. Это уже не набор статических страниц: интерфейсу нужно читать и менять данные, а серверу — проверять запросы и права.

Начни с модели заявки

Не генерируй формы, пока не зафиксировал сущности. Для первого среза достаточно:

Сущность Поля Назначение
request id, title, description, status, created_at, owner_id сама заявка
profile id, display_name отображаемые сведения об участнике
request_event id, request_id, actor_id, from_status, to_status, created_at история смены статуса, если она нужна продукту

Статусы должны быть конечными и понятными. Например: new → in_progress → done; переход done → new разрешай только если есть конкретный сценарий возврата. Поле «исполнитель» не следует выводить из имени пользователя в тексте. Это связь с идентификатором пользователя.

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

Раздели клиент, сервер и базу

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

Сервер отвечает за авторизацию и бизнес-правила: кто может создать заявку, кто может назначить другого исполнителя, какие переходы статуса разрешены. База сохраняет подтверждённые данные и может закреплять часть правил ограничениями. В PostgreSQL ограничения NOT NULL, UNIQUE, внешние ключи и CHECK помогают запрещать некорректные состояния на уровне таблиц (PostgreSQL constraints). Они не заменяют интерфейсную валидацию, но позволяют данным не зависеть только от одной формы.

Supabase описывает развитие приложения как несколько отдельных этапов, в том числе database, auth, security, storage и production (The Supabase way to build). Это схема для проверки пропущенных частей, не требование пользоваться Supabase. В любом стеке названия сервисов меняются, а границы остаются полезными.

Запрос для ИИ и порядок реализации

В проекте нужен трекер заявок. Сначала предложи структуру таблиц и список маршрутов. Сущность заявки: заголовок, описание, статус new/in_progress/done, дата создания, владелец, исполнитель. Не подключай оплату и не делай публичные заявки. Для каждого endpoint укажи проверку пользователя и ожидаемый ответ. Затем реализуй по одному шагу: список с фиктивными данными, форму создания, серверное сохранение, фильтр по статусу. После каждого шага перечисляй изменённые файлы и проверки.

План помогает заметить неучтённый доступ до того, как модель разнесёт одинаковое правило по нескольким компонентам. После плана последовательно потребуй: 1) список на фиктивных данных; 2) форму и серверную проверку; 3) чтение/запись в выбранное хранилище; 4) авторизацию; 5) тесты отказа и повторной отправки. Не подключай реальные данные, пока нет тестов на чужую заявку.

Доступ — отдельное поведение, а не скрытая кнопка

Составь матрицу прав. Например: автор видит собственные заявки; назначенный исполнитель видит назначенные ему; администратор видит все заявки. Затем запиши запреты: пользователь без сессии не читает записи; сотрудник не меняет чужую заявку; исполнитель не назначает себе роль администратора.

Если используется PostgreSQL Row Level Security, политики ограничивают доступ к строкам на уровне базы. PostgreSQL описывает модель row security и поведение, когда RLS включена, но применимой политики нет (Row Security Policies). Это не отменяет проверки на сервере и корректных grants. Проверяй доступ под ролью приложения, не только как владелец базы; иначе тест может обходить те самые ограничения.

Как доказать, что сохранение работает

Наличие строки после нажатия не показывает, что сервер подтвердил запись. Проведи конкретный сценарий: создай тестовую заявку, дождись ответа сервера, перезагрузи страницу, открой другой маршрут и найди её снова. Затем попробуй повторно отправить запрос, обновить запись после изменения статуса и открыть заявку под другой тестовой ролью.

Критерии готовности прототипа:

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

Next.js в руководстве по формам показывает свой путь обработки форм и серверных действий; он полезен как пример конкретного фреймворка, но не автоматически решает модель доступа в трекере (Next.js forms).

Граница прототипа

До использования в команде добавь журналирование нужных событий, резервное восстановление и безопасную обработку ошибок. Не включай реальные чувствительные сведения в демо-данные и снимки экрана. Прототип проверяет маршрут и модель; он не подтверждает аудит безопасности, доступность или пригодность для всех рабочих процессов. Если задача пока только объяснить идею и проверить одну функцию, сначала сузь её как MVP, вместо построения полного трекера.

Разбери запрос до сохранения: шаги и ответы сервера

Обычный сценарий можно записать так: сотрудник открывает список → сервер отдаёт разрешённые заявки → сотрудник отправляет новую → сервер проверяет сессию и обязательные поля → БД сохраняет строку → сервер возвращает идентификатор → клиент обновляет список. Это помогает увидеть, где заканчивается интерфейсная реакция и начинается подтверждённое состояние. Если браузер оптимистично добавил строку до ответа, при серверной ошибке он должен убрать её или показать состояние, которое требует повторить действие.

Запиши таблицу переходов: new → in_progress разрешён исполнителю; in_progress → done разрешён исполнителю; возврат done → in_progress запрещён или разрешён только администратору — выбор зависит от процесса, его нельзя угадывать за владельца. Для каждого перехода опиши ответ при успехе и отказе. Событие статуса должно сохранять тот же идентификатор заявки, а не создавать новую запись.

Если форма использует Server Action или иной endpoint, читай документацию своего фреймворка и не копируй синтаксис между проектами. Next.js guide показывает framework-specific form flow, но смысл «пользователь имеет право изменить эту заявку» остаётся отдельным правилом (Next.js forms).

Минимальный набор интеграционных проверок

Подготовь две тестовые учётные записи и несколько заявок с разными владельцами. Затем проверь: без сессии чтение приватного списка отказано; пользователь A создаёт заявку и видит её после перезагрузки; пользователь B не может читать или менять заявку A; исполнитель может выполнить разрешённый переход; запрещённый переход возвращает отказ и оставляет прежний статус; два быстрых одинаковых запроса не порождают неожиданный дубль. Используй искусственные данные, не реальные клиентские обращения.

Для ошибок сделай понятные состояния: отправляется, сохранено, не удалось, повторить. Сетевой timeout не означает, что сервер точно не получил операцию: прежде чем повторить, продумай идентификатор запроса или проверку результата, если дубликаты опасны. «Запись видна в интерфейсе» и «запрос вернулся без ошибки» тоже могут расходиться; проверь данные в выбранной системе хранения отдельным способом.

Граница готовности первого прототипа: пользовательский путь воспроизводится от входа до сохранённой строки; права проверены сервером; после reload результат совпадает с подтверждёнными данными; ключевые ошибки дают честную обратную связь. Это ещё не аудит безопасности и не разрешение использовать настоящие сведения без отдельного review.