laravel-12-tech-specs/task10-pet-shelter.md

22 KiB
Raw Permalink Blame History

Техническое задание: Система помощи питомцам (Pet Shelter Management)

1. Описание проекта

Веб-платформа для приюта животных: каталог питомцев, заявки на усыновление, управление волонтёрами и историями лечения. Проект закрепляет навыки CRUD, загрузки файлов, статусных переходов, разграничения прав и совместной работы через Git.

Команда: 23 человека


2. Функциональные требования

2.1. Аутентификация и регистрация

  • Регистрация, вход, выход (Laravel Breeze)

2.2. Каталог питомцев

  • Просмотр списка питомцев с пагинацией
  • Фильтрация по видам (кошки, собаки, грызуны, птицы, рептилии)
  • Поиск по кличке, породе
  • Детальная страница питомца (фото, описание, вид, порода, возраст, пол, статус, истории лечения)

2.3. Управление питомцами (волонтёр/админ)

  • CRUD питомцев: кличка, вид, порода, возраст (примерный), пол, описание, фото (до 3), статус (доступен для усыновления, на лечении, усыновлён)
  • Загрузка фотографий питомца (валидация: jpg/png, макс. 2MB на каждое фото)
  • Особенности характера (свободный текст или теги)

2.4. Категории питомцев

  • CRUD категорий (видов): кошки, собаки, грызуны, птицы, рептилии
  • Описание вида, особенности содержания

2.5. Заявки на усыновление

  • Форма заявки: данные заявителя (ФИО, телефон, email, адрес), опыт содержания, цель усыновления, условия содержания
  • Привязка заявки к питомцу
  • Статусы заявки: новая, на рассмотрении, одобрена, отклонена, завершена
  • Волонтёр меняет статус заявки (новая → на рассмотрении → одобрена/отклонена)
  • При одобрении — питомец получает статус «усыновлён»
  • При отклонении — комментарий с причиной

2.6. Волонтёры

  • Профиль волонтёра: имя, телефон, email, дата начала волонтёрства, статус (активен/неактивен)
  • Расписание волонтёра: дата, время, тип деятельности (выгул, кормление, уборка)
  • CRUD расписания (волонтёр создаёт свои смены)

2.7. Истории питомцев

  • Записи о здоровье питомца: дата, описание (лечение, вакцинация, осмотр, операция)
  • Привязка к питомцу
  • Хронология на странице питомца

2.8. Панель волонтёра

  • Мои питомцы (за которыми закреплён)
  • Входящие заявки на усыновление (управление статусами)
  • Моё расписание
  • Добавление историй питомцев

2.9. Панель потенциального хозяина

  • Каталог питомцев
  • Мои заявки на усыновление (статусы)
  • Создание новой заявки

2.10. Панель администратора

  • Управление пользователями и ролями
  • Управление категориями питомцев
  • Модерация заявок
  • Общая статистика приюта

3. Структура базы данных

Таблица users

Поле Тип Описание
id BIGINT UNSIGNED Первичный ключ
name VARCHAR(255) Имя
email VARCHAR(255) Email (unique)
password VARCHAR(255) Хеш пароля
role ENUM('admin', 'volunteer', 'adopter') Роль
phone VARCHAR(20) | NULL Телефон
avatar VARCHAR(255) | NULL Аватар
volunteer_start_date DATE | NULL Дата начала волонтёрства (для волонтёров)
is_active BOOLEAN Активен ли (для волонтёров)
created_at TIMESTAMP
updated_at TIMESTAMP

Таблица pet_categories

Поле Тип Описание
id BIGINT UNSIGNED Первичный ключ
name VARCHAR(255) Название вида (кошки, собаки, ...)
slug VARCHAR(255) URL-идентификатор (unique)
description TEXT | NULL Описание вида
created_at TIMESTAMP
updated_at TIMESTAMP

Таблица pets

Поле Тип Описание
id BIGINT UNSIGNED Первичный ключ
name VARCHAR(255) Кличка питомца
slug VARCHAR(255) URL-идентификатор (unique)
species_id BIGINT UNSIGNED Вид (FK → pet_categories)
breed VARCHAR(255) | NULL Порода
age_estimate VARCHAR(50) Примерный возраст (например, «2 года», «6 месяцев»)
gender ENUM('male', 'female') Пол
description TEXT Описание, особенности характера
status ENUM('available', 'treatment', 'adopted', 'reserved') Статус
created_at TIMESTAMP
updated_at TIMESTAMP

Таблица pet_photos

Поле Тип Описание
id BIGINT UNSIGNED Первичный ключ
pet_id BIGINT UNSIGNED FK → pets
photo_path VARCHAR(255) Путь к изображению
is_primary BOOLEAN Главное фото (true/false)
created_at TIMESTAMP
updated_at TIMESTAMP

Таблица adoption_applications

Поле Тип Описание
id BIGINT UNSIGNED Первичный ключ
pet_id BIGINT UNSIGNED Питомец (FK → pets)
applicant_id BIGINT UNSIGNED Заявитель (FK → users)
full_name VARCHAR(255) ФИО заявителя
phone VARCHAR(20) Телефон
email VARCHAR(255) Email
address TEXT Адрес проживания
experience TEXT Опыт содержания животных
purpose TEXT Цель усыновления
living_conditions TEXT Условия содержания
status ENUM('new', 'under_review', 'approved', 'rejected', 'completed') Статус
rejection_reason TEXT | NULL Причина отклонения
volunteer_notes TEXT | NULL Заметки волонтёра
created_at TIMESTAMP
updated_at TIMESTAMP

Таблица volunteer_schedules

Поле Тип Описание
id BIGINT UNSIGNED Первичный ключ
volunteer_id BIGINT UNSIGNED Волонтёр (FK → users)
pet_id BIGINT UNSIGNED | NULL Питомец (FK → pets), NULL если общая смена
schedule_date DATE Дата смены
start_time TIME Время начала
end_time TIME Время окончания
activity_type ENUM('walking', 'feeding', 'cleaning', 'grooming', 'other') Тип деятельности
notes TEXT | NULL Заметки
created_at TIMESTAMP
updated_at TIMESTAMP

Таблица pet_histories

Поле Тип Описание
id BIGINT UNSIGNED Первичный ключ
pet_id BIGINT UNSIGNED FK → pets
history_date DATE Дата записи
type ENUM('vaccination', 'treatment', 'examination', 'surgery', 'other') Тип записи
description TEXT Описание
veterinarian VARCHAR(255) | NULL Ветеринар
created_by BIGINT UNSIGNED Создатель записи (FK → users)
created_at TIMESTAMP
updated_at TIMESTAMP

4. Маршруты и контроллеры

// Публичные маршруты
Route::get('/', [PetController::class, 'index'])->name('pets.index');
Route::get('/pets/{pet:slug}', [PetController::class, 'show'])->name('pets.show');

// Аутентифицированные маршруты
Route::middleware('auth')->group(function () {
    // Заявки на усыновление
    Route::prefix('applications')->name('applications.')->group(function () {
        Route::post('/apply/{pet}', [ApplicationController::class, 'store'])->name('apply');
        Route::get('/my-applications', [ApplicationController::class, 'myApplications'])->name('my');
        Route::get('/{application}', [ApplicationController::class, 'show'])->name('show');
    });

    // Расписание волонтёра
    Route::prefix('volunteer')->name('volunteer.')->middleware('can:be-volunteer')->group(function () {
        Route::resource('schedules', VolunteerScheduleController::class);
        Route::get('dashboard', [VolunteerDashboardController::class, 'index'])->name('dashboard');
    });

    // Управление питомцами (волонтёр/админ)
    Route::prefix('shelter')->name('shelter.')->middleware('can:manage-pets')->group(function () {
        Route::resource('pets', ShelterPetController::class);
        Route::resource('pets.photos', PetPhotoController::class)->scoped(['pets' => 'pet']);
        Route::resource('pets.histories', PetHistoryController::class)->scoped(['pets' => 'pet']);

        // Управление заявками
        Route::get('applications', [ShelterApplicationController::class, 'index'])->name('applications.index');
        Route::get('applications/{application}', [ShelterApplicationController::class, 'show'])->name('applications.show');
        Route::post('applications/{application}/review', [ShelterApplicationController::class, 'startReview'])->name('applications.review');
        Route::post('applications/{application}/approve', [ShelterApplicationController::class, 'approve'])->name('applications.approve');
        Route::post('applications/{application}/reject', [ShelterApplicationController::class, 'reject'])->name('applications.reject');
        Route::post('applications/{application}/complete', [ShelterApplicationController::class, 'complete'])->name('applications.complete');
    });

    // Админка
    Route::prefix('admin')->name('admin.')->middleware('can:access-admin-panel')->group(function () {
        Route::resource('users', AdminUserController::class);
        Route::resource('categories', AdminCategoryController::class);
        Route::get('dashboard', [AdminDashboardController::class, 'index'])->name('dashboard');
    });
});

Контроллеры

  • PetController — публичный каталог и детальный просмотр
  • ApplicationController — подача и просмотр своих заявок
  • VolunteerScheduleController — CRUD расписания волонтёра
  • ShelterPetController — CRUD питомцев (волонтёр/админ)
  • PetPhotoController — загрузка/удаление фото питомца
  • PetHistoryController — CRUD историй питомца
  • ShelterApplicationController — управление заявками (смена статусов)
  • VolunteerDashboardController, AdminUserController, AdminCategoryController, AdminDashboardController — панели

5. Роли, Gates и Policies

Роли

Роль Описание
admin Полный доступ, управление пользователями, категориями, модерация
volunteer Управление питомцами, заявками, расписанием, историями питомцев
adopter Просмотр каталога, подача заявок на усыновление, просмотр своих заявок

Gates

Gate::define('be-volunteer', function (User $user) {
    return in_array($user->role, ['admin', 'volunteer']);
});

Gate::define('manage-pets', function (User $user) {
    return in_array($user->role, ['admin', 'volunteer']);
});

Gate::define('access-admin-panel', function (User $user) {
    return $user->role === 'admin';
});

Policies

PetPolicy:

  • view — все (публичный каталог)
  • create, update, delete — volunteer или admin

PetPhotoPolicy:

  • create, delete — volunteer или admin

PetHistoryPolicy:

  • create, update, delete — volunteer или admin
  • view — все

AdoptionApplicationPolicy:

  • create — adopter (не подавал одобренную заявку на этого питомца)
  • view — заявитель, волонтёр/admin
  • review, approve, reject, complete — volunteer или admin

VolunteerSchedulePolicy:

  • create, update, delete — владелец расписания (волонтёр) или admin
  • view — volunteer или admin

6. Требования к интерфейсу (Bootstrap 5)

Компоненты

  • Навбар — логотип, каталог питомцев, «Мои заявки», панель волонтёра, профиль
  • Карточки питомцев — главное фото, кличка, вид (бейдж), порода, возраст, статус (бейдж)
  • Страница питомца — галерея фото (карусель или грид), описание, характеристики, кнопка «Усыновить», истории питомца (хронология)
  • Карусель фото — Bootstrap Carousel для галереи питомца
  • Форма заявки — Bootstrap-форма с валидацией, textarea для опыта и условий
  • Таблица заявок — питомец, заявитель, статус (цветные бейджи), действия
  • Календарь/таблица расписания — дата, время, тип деятельности
  • Хронология историй — вертикальный timeline (Bootstrap + кастомные стили)
  • Дашборд волонтёра — статистика (карточки), входящие заявки, ближайшее расписание
  • Адаптивная сеткаcol-md-4 для карточек, col-md-8 + col-md-4 для основного контента

Цветовая схема статусов питомца

  • Доступен — bg-success
  • На лечении — bg-warning
  • Усыновлён — bg-primary
  • Зарезервирован — bg-info

Цветовая схема статусов заявки

  • Новая — bg-info
  • На рассмотрении — bg-warning
  • Одобрена — bg-success
  • Отклонена — bg-danger
  • Завершена — bg-secondary

7. Git-workflow для команды

Распределение модулей (для 2 человек)

Участник Модуль Ветки
Участник A Питомцы, категории, фото, заявки на усыновление feature/pets-crud, feature-categories, feature-pet-photos
Участник B Расписание волонтёра, истории, дашборд, UI feature/applications, feature-application-statuses, feature-approval-flow

Распределение модулей (для 3 человек)

Участник Модуль Ветки
Участник A Питомцы, категории, загрузка фото, каталог feature/pets-crud, feature-categories, feature-pet-photos
Участник B Заявки на усыновление, статусные переходы feature/applications, feature-application-statuses, feature-approval-flow
Участник C Расписание волонтёра, истории питомцев, UI, дашборд feature-volunteer-schedules, feature-pet-histories, feature-dashboard-ui

Правила

  1. Ветка develop — основная ветка разработки
  2. Каждый участник создаёт фич-ветки от develop
  3. Минимум 3 PR на участника
  4. Обязательный код-ревью перед мёржем
  5. Conventional Commits

Визуализация workflow (2 участника)

gitGraph
   commit id: "init" tag: "v1.0"
   branch develop
   checkout develop
   branch feature/pets-crud
   checkout develop
   branch feature/applications
   checkout feature/pets-crud
   commit id: "feat: add pets CRUD"
   commit id: "feat: add pet photos"
   checkout feature/applications
   commit id: "feat: add adoption applications"
   commit id: "feat: add application statuses"
   checkout develop
   merge feature/pets-crud tag: "PR + review"
   merge feature/applications tag: "PR + review"
   checkout main
   merge develop tag: "release v1.1"

Визуализация workflow (3 участника)

gitGraph
   commit id: "init" tag: "v1.0"
   branch develop
   checkout develop
   branch feature/pets-crud
   checkout develop
   branch feature/applications
   checkout develop
   branch feature-volunteer-schedules
   checkout feature/pets-crud
   commit id: "feat: add pets CRUD"
   commit id: "feat: add pet categories"
   checkout feature/applications
   commit id: "feat: add adoption applications"
   commit id: "feat: add application statuses"
   checkout feature-volunteer-schedules
   commit id: "feat: add volunteer schedules"
   commit id: "feat: add pet histories"
   checkout develop
   merge feature/pets-crud tag: "PR + review"
   merge feature/applications tag: "PR + review"
   merge feature-volunteer-schedules tag: "PR + review"
   checkout main
   merge develop tag: "release v1.1"

8. Критерии приёмки

Обязательно

  • CRUD питомцев с загрузкой фото (до 3 фото на питомца)
  • CRUD категорий питомцев
  • Каталог питомцев с пагинацией и фильтрацией по видам
  • Подача заявки на усыновление (форма с валидацией всех полей)
  • Просмотр своих заявок (заявитель)
  • Управление статусами заявок волонтёром (новая → на рассмотрении → одобрена/отклонена)
  • При одобрении заявки — обновление статуса питомца на «adopted»
  • При отклонении — обязательная причина
  • CRUD расписания волонтёра
  • CRUD историй питомцев (лечение, вакцинация, осмотр)
  • Панель волонтёра (мои питомцы, заявки, расписание)
  • Policies: adoptter не может управлять питомцами или заявками
  • Адаптивная Bootstrap-вёрстка
  • Flash-сообщения
  • Git-история: минимум 3 ветки на участника, PR с ревью

Дополнительно (бонусные баллы)

  • Поиск питомцев по кличке и породе
  • Фильтрация по возрасту и полу
  • Галерея фото (Bootstrap Carousel)
  • Экспорт расписания волонтёра в PDF
  • Уведомления (email при изменении статуса заявки)
  • Мягкое удаление питомцев и историй
  • Тесты: PHPUnit Feature-тесты для ApplicationController
  • API: RESTful API для каталога питомцев

9. Дополнительные задания (для продвинутых)

  1. Уведомления: email заявителю при изменении статуса заявки
  2. Совместимость: рекомендации питомцев заявителю на основе его опыта и условий
  3. Статистика приюта: дашборд с графиками (Chart.js) — усыновления по месяцам, популярные виды
  4. Тесты: PHPUnit Feature-тесты для статусных переходов заявок
  5. API: RESTful API для каталога питомцев и подачи заявок
  6. Queue: асинхронная отправка email-уведомлений
  7. Events & Listeners: событие «заявка одобрена» → обновление статуса питомца + email

10. Рекомендуемые материалы