docker compose up --build- Открыть
http://localhost:8080
Docker сам подготовит .env, сгенерирует APP_KEY и выполнит миграции.
- Приложение (Docker):
http://localhost:8080 - Локальный запуск без Docker (artisan serve):
http://127.0.0.1:8000 - Swagger UI (API):
http://localhost:8080/api
- Приложение:
http://localhost:8080 - MySQL: порт
3307на хосте (в контейнере3306) - Основные сервисы:
app(PHP-FPM),web(nginx),db(MySQL)
.env.docker— базовые переменные для Docker.envсоздается автоматически при старте контейнера.env.testing— настройки для тестов (SQLite in-memory)- При запуске без Docker нужно вручную создать
.envи сгенерироватьAPP_KEY- Если видите
MissingAppKeyException, выполнитеphp artisan key:generate - Для Docker после генерации ключа перезапустите контейнеры
- Если ошибка появляется сразу после
docker compose up, выполнитеdocker compose downи запустите снова
- Если видите
Запуск:
docker compose up --build
Остановка:
docker compose down
Тесты (в контейнере, рекомендовано):
docker compose run --rm --entrypoint php app artisan test
docker compose run --rm --entrypoint php app artisan test
Локальный запуск без Docker:
cp .env.example .env
php artisan key:generate
php artisan migrate
php artisan serve
Необходимо создать БД под управлением MySQL со следующими сущностями:
- id
- Логин
- Пароль
- Имя
- Фамилия
- Дата регистрации
- Дата рождения Все поля, кроме "Дата рождения", не могут принимать нулевые значения.
- id
- Заголовок
- Текст
- Дата создания
- Создатель (сущность Пользователь)
- Участники (сущность Пользователи) Все значения ненулевые.
Разработать RESTful API для:
- регистрация пользователя
- авторизация пользователя
- создание события
- получение списка событий
- участие в событии
- отмена участия в событии
- удаление события создателем
Ответ с сервера должен приходить в виде такого JSON:
{"error":null, "result":{"id":1, "first_name":"Вася", "last_name":"Петров"}}Создать простую админку, используя AdminLTE:
- регистрация пользователя
- авторизация пользователя
- список событий
- информация о пользователе
Если в процессе регистрации или авторизации произошла ошибка, необходимо показать диалоговое окно с описанием ошибки. При успешной регистрации или авторизации открывается окно со списком событий (см. скрин). При просмотре НЕ своего события внизу находится кнопка "Принять участие", при просмотре своего события - кнопка "Отказаться от участия". Элементы "Все события" и "Участники" должны обновляться каждые 30 секунд, по возможности, без перезагрузки страницы. При клике на участника показывается экран информации об участнике в произвольном виде.
- БД MySQL: сущности
usersиevents, связь многие-ко-многимevent_user - REST API: регистрация, авторизация, создание/список событий, участие/отмена, удаление создателем
- Формат ответа:
{"error": ..., "result": ...} - Админка AdminLTE: регистрация, авторизация, список событий, профиль пользователя
- Документация API в Swagger UI:
http://localhost:8080/api - Диалоговые ошибки при неуспешной регистрации/авторизации
- Автообновление списков событий/участников каждые 30 секунд
Базовый URL: http://localhost:8080/api
{
"error": null,
"result": {}
}Для защищенных маршрутов требуется заголовок:
Authorization: Bearer <token>
POST /register— регистрацияPOST /login— авторизацияGET /events— список событий (auth, поддерживаетsort,direction,per_page,page)POST /events— создание события (auth)POST /events/{event}/join— участие (auth)POST /events/{event}/leave— отмена участия (auth)DELETE /events/{event}— удаление события создателем (auth)
Пример запроса:
{
"login": "user1",
"password": "secret123",
"first_name": "Ivan",
"last_name": "Petrov",
"birth_date": "2000-01-01"
}Пример ответа:
{
"error": null,
"result": {
"id": 1,
"first_name": "Ivan",
"last_name": "Petrov",
"token": "..."
}
}Пример запроса:
{
"login": "user1",
"password": "secret123"
}Пример ответа:
{
"error": null,
"result": {
"id": 1,
"first_name": "Ivan",
"last_name": "Petrov",
"token": "..."
}
}Headers:
Authorization: Bearer <token>
Пример запроса:
{
"title": "Событие",
"body": "Описание события"
}Пример ответа:
{
"error": null,
"result": {
"id": 1,
"title": "Событие"
}
}Headers:
Authorization: Bearer <token>
Query параметры:
sort:created_at|title(по умолчаниюcreated_at)direction:asc|desc(по умолчаниюdesc)per_page: 1..100 (по умолчанию 20)page: номер страницы
Пример ответа:
{
"error": null,
"result": {
"items": [
{
"id": 1,
"title": "Событие",
"body": "Описание события",
"created_at": "2025-01-21 10:00:00",
"creator": {
"id": 1,
"first_name": "Ivan",
"last_name": "Petrov"
},
"participants": [
{
"id": 1,
"first_name": "Ivan",
"last_name": "Petrov"
}
],
"is_creator": true,
"is_participant": true
}
],
"pagination": {
"current_page": 1,
"per_page": 20,
"total": 1,
"last_page": 1
},
"sort": {
"field": "created_at",
"direction": "desc"
}
}
}Headers:
Authorization: Bearer <token>
Пример ответа:
{
"error": null,
"result": {
"event_id": 1,
"joined": true
}
}Headers:
Authorization: Bearer <token>
Пример ответа:
{
"error": null,
"result": {
"event_id": 1,
"joined": false
}
}Headers:
Authorization: Bearer <token>
Пример ответа:
{
"error": null,
"result": {
"event_id": 1,
"deleted": true
}
}