diff --git a/.gitignore b/.gitignore index 6d81922..735ee1a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ /.direnv/ /.reference/ /backend/.phpunit.cache/ -/.postgres/ diff --git a/backend/.env.example b/backend/.env.example deleted file mode 100644 index b13deb0..0000000 --- a/backend/.env.example +++ /dev/null @@ -1,5 +0,0 @@ -DB_HOST=127.0.0.1 -DB_PORT=5432 -DB_NAME=rabbigerzi -DB_USER=postgres -DB_PASSWORD= diff --git a/backend/.gitignore b/backend/.gitignore index d3842e4..c15afe2 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -1,3 +1,2 @@ vendor/ .phpunit.cache/ -.env diff --git a/backend/app/Auth/PostgresSessionRepository.php b/backend/app/Auth/PostgresSessionRepository.php deleted file mode 100644 index 728e094..0000000 --- a/backend/app/Auth/PostgresSessionRepository.php +++ /dev/null @@ -1,64 +0,0 @@ - $dto->token, - 'user_id' => $dto->user->getId(), - 'created_at' => $dto->createdAt->format('Y-m-d H:i:s'), - 'expires_at' => $dto->expiresAt->format('Y-m-d H:i:s'), - ]); - - return new Session( - token: $record->token, - user: $dto->user, - createdAt: $dto->createdAt, - expiresAt: $dto->expiresAt, - ); - } - - public function findByToken(string $token): ?Session - { - $record = SessionModel::where('token', $token)->first(); - - if ($record === null) { - return null; - } - - $userRecord = $record->user; - - if ($userRecord === null) { - return null; - } - - $user = new User( - id: $userRecord->id, - email: new EmailAddress($userRecord->email), - passwordHash: $userRecord->password_hash, - ); - - return new Session( - token: $record->token, - user: $user, - createdAt: $record->created_at instanceof \DateTimeImmutable - ? $record->created_at - : new \DateTimeImmutable($record->created_at->format('Y-m-d H:i:s')), - expiresAt: $record->expires_at instanceof \DateTimeImmutable - ? $record->expires_at - : new \DateTimeImmutable($record->expires_at->format('Y-m-d H:i:s')), - ); - } - - public function deleteByToken(string $token): void - { - SessionModel::where('token', $token)->delete(); - } -} diff --git a/backend/app/Middleware/CorsMiddleware.php b/backend/app/Middleware/CorsMiddleware.php deleted file mode 100644 index e20630f..0000000 --- a/backend/app/Middleware/CorsMiddleware.php +++ /dev/null @@ -1,40 +0,0 @@ -getMethod() === 'OPTIONS') { - return $this->withCorsHeaders(new Response(204)); - } - - return $this->withCorsHeaders($handler->handle($request)); - } - - private function withCorsHeaders(ResponseInterface $response): ResponseInterface - { - return $response - ->withHeader('Access-Control-Allow-Origin', self::ALLOWED_ORIGIN) - ->withHeader('Access-Control-Allow-Credentials', 'true') - ->withHeader( - 'Access-Control-Allow-Headers', - 'Content-Type, Authorization', - ) - ->withHeader( - 'Access-Control-Allow-Methods', - 'GET, POST, OPTIONS', - ); - } -} diff --git a/backend/app/User/PostgresUserRepository.php b/backend/app/User/PostgresUserRepository.php deleted file mode 100644 index e0989ee..0000000 --- a/backend/app/User/PostgresUserRepository.php +++ /dev/null @@ -1,53 +0,0 @@ - $dto->email->value(), - 'password_hash' => $dto->passwordHash, - ]); - - return new User( - id: $record->id, - email: new EmailAddress($record->email), - passwordHash: $record->password_hash, - ); - } - - public function findByEmail(EmailAddress $email): ?User - { - $record = UserModel::where('email', $email->value())->first(); - - if ($record === null) { - return null; - } - - return new User( - id: $record->id, - email: new EmailAddress($record->email), - passwordHash: $record->password_hash, - ); - } - - public function find(int $id): ?User - { - $record = UserModel::find($id); - - if ($record === null) { - return null; - } - - return new User( - id: $record->id, - email: new EmailAddress($record->email), - passwordHash: $record->password_hash, - ); - } -} diff --git a/backend/bin/migrate b/backend/bin/migrate deleted file mode 100755 index 98729b2..0000000 --- a/backend/bin/migrate +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env php -safeLoad(); - - require $root . '/config/database.php'; - - $migrationsDir = $root . '/database/migrations'; - $files = glob($migrationsDir . '/*.php'); - - if ($files === false || $files === []) { - echo "No migration files found.\n"; - exit(0); - } - - sort($files); - - foreach ($files as $file) { - $className = require $file; - - if (! class_exists($className)) { - echo "Migration file {$file} did not define class {$className}\n"; - exit(1); - } - - $migration = new $className(); - - if (! $migration instanceof Migration) { - echo "Class {$className} must extend " . Migration::class . "\n"; - exit(1); - } - - echo "Running {$className}...\n"; - $migration->up(); - } - - echo "Done.\n"; -})(); diff --git a/backend/bin/seed b/backend/bin/seed deleted file mode 100755 index 46a5ca2..0000000 --- a/backend/bin/seed +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env php -safeLoad(); - - require $root . '/config/database.php'; - - $container = require $root . '/config/container.php'; - - $userRepo = $container->get(UserRepository::class); - $hasher = $container->get(PasswordHasher::class); - - $seedEmail = 'admin@rabbigerzi.test'; - $seedPassword = 'password'; - - $email = new EmailAddress($seedEmail); - - if ($userRepo->findByEmail($email) !== null) { - echo "Seed user {$seedEmail} already exists, skipping.\n"; - exit(0); - } - - $userRepo->create(new CreateUserDto( - email: $email, - passwordHash: $hasher->hash($seedPassword), - )); - - echo "Created seed user {$seedEmail} / {$seedPassword}\n"; -})(); diff --git a/backend/bin/serve b/backend/bin/serve deleted file mode 100755 index 22d9b98..0000000 --- a/backend/bin/serve +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash -set -e - -REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" -export PGDATA="${PGDATA:-$REPO_ROOT/.postgres}" -export PGHOST="${PGHOST:-$PGDATA}" -export PGUSER="${PGUSER:-postgres}" -export PGDATABASE="${PGDATABASE:-rabbigerzi}" -export DB_HOST="${DB_HOST:-127.0.0.1}" -export DB_PORT="${DB_PORT:-5432}" -export DB_NAME="${DB_NAME:-rabbigerzi}" -export DB_USER="${DB_USER:-postgres}" -export DB_PASSWORD="${DB_PASSWORD:-}" - -echo "[serve] waiting for postgres..." -until pg_isready -h "$PGHOST" -q 2>/dev/null; do - sleep 1 -done - -echo "[serve] creating database if it does not exist..." -createdb --no-password "$PGDATABASE" 2>/dev/null || echo "[serve] database already exists" - -echo "[serve] running migrations..." -php "$REPO_ROOT/backend/bin/migrate" - -echo "[serve] seeding..." -php "$REPO_ROOT/backend/bin/seed" - -echo "[serve] starting PHP dev server..." -exec php -S 127.0.0.1:8000 -t "$REPO_ROOT/backend/public/" "$REPO_ROOT/backend/public/index.php" diff --git a/backend/composer.json b/backend/composer.json index 2cbcd56..2eff6bd 100644 --- a/backend/composer.json +++ b/backend/composer.json @@ -2,8 +2,7 @@ "name": "pilzno/rabbigerzi", "autoload": { "psr-4": { - "App\\": "app/", - "App\\Database\\": "database/" + "App\\": "app/" } }, "autoload-dev": { @@ -20,9 +19,7 @@ "require": { "slim/slim": "4.*", "slim/psr7": "^1.8", - "php-di/slim-bridge": "^3.4", - "illuminate/database": "^13.9", - "vlucas/phpdotenv": "^5.6" + "php-di/slim-bridge": "^3.4" }, "require-dev": { "phpunit/phpunit": "^13.1" diff --git a/backend/composer.lock b/backend/composer.lock index 0e05072..efc5f97 100644 --- a/backend/composer.lock +++ b/backend/composer.lock @@ -4,226 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a725ae7bcb77972ad95e6a77d5616893", + "content-hash": "917fa1f2f884c4b5975eed6baa5d5064", "packages": [ - { - "name": "brick/math", - "version": "0.17.1", - "source": { - "type": "git", - "url": "https://github.com/brick/math.git", - "reference": "6aef71a9fbbd1ee7be0e313cd627f8e6f7125a5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/6aef71a9fbbd1ee7be0e313cd627f8e6f7125a5b", - "reference": "6aef71a9fbbd1ee7be0e313cd627f8e6f7125a5b", - "shasum": "" - }, - "require": { - "php": "^8.2" - }, - "require-dev": { - "phpstan/phpstan": "2.1.22", - "phpunit/phpunit": "^11.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Brick\\Math\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Arbitrary-precision arithmetic library", - "keywords": [ - "Arbitrary-precision", - "BigInteger", - "BigRational", - "arithmetic", - "bigdecimal", - "bignum", - "bignumber", - "brick", - "decimal", - "integer", - "math", - "mathematics", - "rational" - ], - "support": { - "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.17.1" - }, - "funding": [ - { - "url": "https://github.com/BenMorel", - "type": "github" - } - ], - "time": "2026-04-19T20:55:20+00:00" - }, - { - "name": "carbonphp/carbon-doctrine-types", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", - "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d", - "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "conflict": { - "doctrine/dbal": "<4.0.0 || >=5.0.0" - }, - "require-dev": { - "doctrine/dbal": "^4.0.0", - "nesbot/carbon": "^2.71.0 || ^3.0.0", - "phpunit/phpunit": "^10.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "KyleKatarn", - "email": "kylekatarnls@gmail.com" - } - ], - "description": "Types to use Carbon in Doctrine", - "keywords": [ - "carbon", - "date", - "datetime", - "doctrine", - "time" - ], - "support": { - "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", - "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" - }, - "funding": [ - { - "url": "https://github.com/kylekatarnls", - "type": "github" - }, - { - "url": "https://opencollective.com/Carbon", - "type": "open_collective" - }, - { - "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", - "type": "tidelift" - } - ], - "time": "2024-02-09T16:56:22+00:00" - }, - { - "name": "doctrine/inflector", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/inflector.git", - "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b", - "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^12.0 || ^13.0", - "phpstan/phpstan": "^1.12 || ^2.0", - "phpstan/phpstan-phpunit": "^1.4 || ^2.0", - "phpstan/phpstan-strict-rules": "^1.6 || ^2.0", - "phpunit/phpunit": "^8.5 || ^12.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Inflector\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", - "homepage": "https://www.doctrine-project.org/projects/inflector.html", - "keywords": [ - "inflection", - "inflector", - "lowercase", - "manipulation", - "php", - "plural", - "singular", - "strings", - "uppercase", - "words" - ], - "support": { - "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.1.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", - "type": "tidelift" - } - ], - "time": "2025-08-10T19:31:58+00:00" - }, { "name": "fig/http-message-util", "version": "1.1.5", @@ -280,533 +62,6 @@ }, "time": "2020-11-24T22:02:12+00:00" }, - { - "name": "graham-campbell/result-type", - "version": "v1.1.4", - "source": { - "type": "git", - "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/e01f4a821471308ba86aa202fed6698b6b695e3b", - "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.5" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7" - }, - "type": "library", - "autoload": { - "psr-4": { - "GrahamCampbell\\ResultType\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "description": "An Implementation Of The Result Type", - "keywords": [ - "Graham Campbell", - "GrahamCampbell", - "Result Type", - "Result-Type", - "result" - ], - "support": { - "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.4" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", - "type": "tidelift" - } - ], - "time": "2025-12-27T19:43:20+00:00" - }, - { - "name": "illuminate/collections", - "version": "v13.9.0", - "source": { - "type": "git", - "url": "https://github.com/illuminate/collections.git", - "reference": "dda57c96a3e2620e4218ba54c818d55c9c2fcd4f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/dda57c96a3e2620e4218ba54c818d55c9c2fcd4f", - "reference": "dda57c96a3e2620e4218ba54c818d55c9c2fcd4f", - "shasum": "" - }, - "require": { - "illuminate/conditionable": "^13.0", - "illuminate/contracts": "^13.0", - "illuminate/macroable": "^13.0", - "php": "^8.3", - "symfony/polyfill-php84": "^1.36", - "symfony/polyfill-php85": "^1.36", - "symfony/polyfill-php86": "^1.36" - }, - "suggest": { - "illuminate/http": "Required to convert collections to API resources (^13.0).", - "symfony/var-dumper": "Required to use the dump method (^7.4 || ^8.0)." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "13.0.x-dev" - } - }, - "autoload": { - "files": [ - "functions.php", - "helpers.php" - ], - "psr-4": { - "Illuminate\\Support\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "The Illuminate Collections package.", - "homepage": "https://laravel.com", - "support": { - "issues": "https://github.com/laravel/framework/issues", - "source": "https://github.com/laravel/framework" - }, - "time": "2026-05-05T20:55:51+00:00" - }, - { - "name": "illuminate/conditionable", - "version": "v13.9.0", - "source": { - "type": "git", - "url": "https://github.com/illuminate/conditionable.git", - "reference": "7f1ef52d9a346f829421b296adfb7644a951b216" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/conditionable/zipball/7f1ef52d9a346f829421b296adfb7644a951b216", - "reference": "7f1ef52d9a346f829421b296adfb7644a951b216", - "shasum": "" - }, - "require": { - "php": "^8.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "13.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Support\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "The Illuminate Conditionable package.", - "homepage": "https://laravel.com", - "support": { - "issues": "https://github.com/laravel/framework/issues", - "source": "https://github.com/laravel/framework" - }, - "time": "2026-02-25T16:07:55+00:00" - }, - { - "name": "illuminate/container", - "version": "v13.9.0", - "source": { - "type": "git", - "url": "https://github.com/illuminate/container.git", - "reference": "71daf6ee3788e6930e7eb8454d840f1ccfd6a313" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/container/zipball/71daf6ee3788e6930e7eb8454d840f1ccfd6a313", - "reference": "71daf6ee3788e6930e7eb8454d840f1ccfd6a313", - "shasum": "" - }, - "require": { - "illuminate/contracts": "^13.0", - "illuminate/reflection": "^13.0", - "php": "^8.3", - "psr/container": "^1.1.1 || ^2.0.1", - "symfony/polyfill-php84": "^1.36", - "symfony/polyfill-php85": "^1.36" - }, - "provide": { - "psr/container-implementation": "1.1 || 2.0" - }, - "suggest": { - "illuminate/auth": "Required to use the Auth attribute", - "illuminate/cache": "Required to use the Cache attribute", - "illuminate/config": "Required to use the Config attribute", - "illuminate/database": "Required to use the DB attribute", - "illuminate/filesystem": "Required to use the Storage attribute", - "illuminate/log": "Required to use the Log or Context attributes" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "13.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Container\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "The Illuminate Container package.", - "homepage": "https://laravel.com", - "support": { - "issues": "https://github.com/laravel/framework/issues", - "source": "https://github.com/laravel/framework" - }, - "time": "2026-05-05T20:55:51+00:00" - }, - { - "name": "illuminate/contracts", - "version": "v13.9.0", - "source": { - "type": "git", - "url": "https://github.com/illuminate/contracts.git", - "reference": "71dba8668753f7c6ea862bc4258eba6513b592ec" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/71dba8668753f7c6ea862bc4258eba6513b592ec", - "reference": "71dba8668753f7c6ea862bc4258eba6513b592ec", - "shasum": "" - }, - "require": { - "php": "^8.3", - "psr/container": "^1.1.1 || ^2.0.1", - "psr/simple-cache": "^1.0 || ^2.0 || ^3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "13.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Contracts\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "The Illuminate Contracts package.", - "homepage": "https://laravel.com", - "support": { - "issues": "https://github.com/laravel/framework/issues", - "source": "https://github.com/laravel/framework" - }, - "time": "2026-05-06T18:50:26+00:00" - }, - { - "name": "illuminate/database", - "version": "v13.9.0", - "source": { - "type": "git", - "url": "https://github.com/illuminate/database.git", - "reference": "c0f1b78ed5e4cbdad0744181050aa689c477124f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/database/zipball/c0f1b78ed5e4cbdad0744181050aa689c477124f", - "reference": "c0f1b78ed5e4cbdad0744181050aa689c477124f", - "shasum": "" - }, - "require": { - "brick/math": "^0.14.2 || ^0.15 || ^0.16 || ^0.17", - "ext-pdo": "*", - "illuminate/collections": "^13.0", - "illuminate/container": "^13.0", - "illuminate/contracts": "^13.0", - "illuminate/macroable": "^13.0", - "illuminate/support": "^13.0", - "laravel/serializable-closure": "^2.0.10", - "php": "^8.3", - "symfony/polyfill-php84": "^1.36", - "symfony/polyfill-php85": "^1.36", - "symfony/polyfill-php86": "^1.36" - }, - "suggest": { - "ext-filter": "Required to use the Postgres database driver.", - "fakerphp/faker": "Required to use the eloquent factory builder (^1.24).", - "illuminate/console": "Required to use the database commands (^13.0).", - "illuminate/events": "Required to use the observers with Eloquent (^13.0).", - "illuminate/filesystem": "Required to use the migrations (^13.0).", - "illuminate/http": "Required to convert Eloquent models to API resources (^13.0).", - "illuminate/pagination": "Required to paginate the result set (^13.0).", - "symfony/finder": "Required to use Eloquent model factories (^7.4 || ^8.0)." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "13.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Database\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "The Illuminate Database package.", - "homepage": "https://laravel.com", - "keywords": [ - "database", - "laravel", - "orm", - "sql" - ], - "support": { - "issues": "https://github.com/laravel/framework/issues", - "source": "https://github.com/laravel/framework" - }, - "time": "2026-05-10T15:49:54+00:00" - }, - { - "name": "illuminate/macroable", - "version": "v13.9.0", - "source": { - "type": "git", - "url": "https://github.com/illuminate/macroable.git", - "reference": "59b5b5f3cf290a91db8cf6cd3d35ff56978bc057" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/macroable/zipball/59b5b5f3cf290a91db8cf6cd3d35ff56978bc057", - "reference": "59b5b5f3cf290a91db8cf6cd3d35ff56978bc057", - "shasum": "" - }, - "require": { - "php": "^8.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "13.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Illuminate\\Support\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "The Illuminate Macroable package.", - "homepage": "https://laravel.com", - "support": { - "issues": "https://github.com/laravel/framework/issues", - "source": "https://github.com/laravel/framework" - }, - "time": "2026-04-29T09:35:06+00:00" - }, - { - "name": "illuminate/reflection", - "version": "v13.9.0", - "source": { - "type": "git", - "url": "https://github.com/illuminate/reflection.git", - "reference": "4fe1659f068ab2b50131cf906c5d8bba4e34df0c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/reflection/zipball/4fe1659f068ab2b50131cf906c5d8bba4e34df0c", - "reference": "4fe1659f068ab2b50131cf906c5d8bba4e34df0c", - "shasum": "" - }, - "require": { - "illuminate/collections": "^13.0", - "illuminate/contracts": "^13.0", - "php": "^8.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "13.0.x-dev" - } - }, - "autoload": { - "files": [ - "helpers.php" - ], - "psr-4": { - "Illuminate\\Support\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "The Illuminate Reflection package.", - "homepage": "https://laravel.com", - "support": { - "issues": "https://github.com/laravel/framework/issues", - "source": "https://github.com/laravel/framework" - }, - "time": "2026-03-10T20:04:12+00:00" - }, - { - "name": "illuminate/support", - "version": "v13.9.0", - "source": { - "type": "git", - "url": "https://github.com/illuminate/support.git", - "reference": "3367c25b040788835fd043fbddb64bd5af659ec6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/3367c25b040788835fd043fbddb64bd5af659ec6", - "reference": "3367c25b040788835fd043fbddb64bd5af659ec6", - "shasum": "" - }, - "require": { - "doctrine/inflector": "^2.0", - "ext-ctype": "*", - "ext-filter": "*", - "ext-mbstring": "*", - "illuminate/collections": "^13.0", - "illuminate/conditionable": "^13.0", - "illuminate/contracts": "^13.0", - "illuminate/macroable": "^13.0", - "illuminate/reflection": "^13.0", - "nesbot/carbon": "^3.8.4", - "php": "^8.3", - "symfony/polyfill-php85": "^1.36", - "voku/portable-ascii": "^2.0.2" - }, - "conflict": { - "tightenco/collect": "<5.5.33" - }, - "replace": { - "spatie/once": "*" - }, - "suggest": { - "illuminate/filesystem": "Required to use the Composer class (^13.0).", - "laravel/serializable-closure": "Required to use the once function (^2.0.10).", - "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.7).", - "league/uri": "Required to use the Uri class (^7.5.1).", - "ramsey/uuid": "Required to use Str::uuid() (^4.7).", - "symfony/process": "Required to use the Composer class (^7.4 || ^8.0).", - "symfony/uid": "Required to use Str::ulid() (^7.4 || ^8.0).", - "symfony/var-dumper": "Required to use the dd function (^7.4 || ^8.0).", - "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.6.1)." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "13.0.x-dev" - } - }, - "autoload": { - "files": [ - "functions.php", - "helpers.php" - ], - "psr-4": { - "Illuminate\\Support\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "The Illuminate Support package.", - "homepage": "https://laravel.com", - "support": { - "issues": "https://github.com/laravel/framework/issues", - "source": "https://github.com/laravel/framework" - }, - "time": "2026-05-10T15:47:41+00:00" - }, { "name": "laravel/serializable-closure", "version": "v2.0.13", @@ -868,111 +123,6 @@ }, "time": "2026-04-16T14:03:50+00:00" }, - { - "name": "nesbot/carbon", - "version": "3.11.4", - "source": { - "type": "git", - "url": "https://github.com/CarbonPHP/carbon.git", - "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/e890471a3494740f7d9326d72ce6a8c559ffee60", - "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60", - "shasum": "" - }, - "require": { - "carbonphp/carbon-doctrine-types": "<100.0", - "ext-json": "*", - "php": "^8.1", - "psr/clock": "^1.0", - "symfony/clock": "^6.3.12 || ^7.0 || ^8.0", - "symfony/polyfill-mbstring": "^1.0", - "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0 || ^8.0" - }, - "provide": { - "psr/clock-implementation": "1.0" - }, - "require-dev": { - "doctrine/dbal": "^3.6.3 || ^4.0", - "doctrine/orm": "^2.15.2 || ^3.0", - "friendsofphp/php-cs-fixer": "^v3.87.1", - "kylekatarnls/multi-tester": "^2.5.3", - "phpmd/phpmd": "^2.15.0", - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.1.22", - "phpunit/phpunit": "^10.5.53", - "squizlabs/php_codesniffer": "^3.13.4 || ^4.0.0" - }, - "bin": [ - "bin/carbon" - ], - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Carbon\\Laravel\\ServiceProvider" - ] - }, - "phpstan": { - "includes": [ - "extension.neon" - ] - }, - "branch-alias": { - "dev-2.x": "2.x-dev", - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Carbon\\": "src/Carbon/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Brian Nesbitt", - "email": "brian@nesbot.com", - "homepage": "https://markido.com" - }, - { - "name": "kylekatarnls", - "homepage": "https://github.com/kylekatarnls" - } - ], - "description": "An API extension for DateTime that supports 281 different languages.", - "homepage": "https://carbonphp.github.io/carbon/", - "keywords": [ - "date", - "datetime", - "time" - ], - "support": { - "docs": "https://carbonphp.github.io/carbon/guide/getting-started/introduction.html", - "issues": "https://github.com/CarbonPHP/carbon/issues", - "source": "https://github.com/CarbonPHP/carbon" - }, - "funding": [ - { - "url": "https://github.com/sponsors/kylekatarnls", - "type": "github" - }, - { - "url": "https://opencollective.com/Carbon#sponsor", - "type": "opencollective" - }, - { - "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", - "type": "tidelift" - } - ], - "time": "2026-04-07T09:57:54+00:00" - }, { "name": "nikic/fast-route", "version": "v1.3.0", @@ -1193,129 +343,6 @@ }, "time": "2024-06-19T15:47:45+00:00" }, - { - "name": "phpoption/phpoption", - "version": "1.9.5", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/php-option.git", - "reference": "75365b91986c2405cf5e1e012c5595cd487a98be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/75365b91986c2405cf5e1e012c5595cd487a98be", - "reference": "75365b91986c2405cf5e1e012c5595cd487a98be", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.44 || ^9.6.25 || ^10.5.53 || ^11.5.34" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, - "branch-alias": { - "dev-master": "1.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpOption\\": "src/PhpOption/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh" - }, - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "description": "Option Type for PHP", - "keywords": [ - "language", - "option", - "php", - "type" - ], - "support": { - "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.9.5" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", - "type": "tidelift" - } - ], - "time": "2025-12-27T19:41:33+00:00" - }, - { - "name": "psr/clock", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/clock.git", - "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", - "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Psr\\Clock\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for reading the clock.", - "homepage": "https://github.com/php-fig/clock", - "keywords": [ - "clock", - "now", - "psr", - "psr-20", - "time" - ], - "support": { - "issues": "https://github.com/php-fig/clock/issues", - "source": "https://github.com/php-fig/clock/tree/1.0.0" - }, - "time": "2022-11-25T14:36:26+00:00" - }, { "name": "psr/container", "version": "2.0.2", @@ -1640,57 +667,6 @@ }, "time": "2024-09-11T13:17:53+00:00" }, - { - "name": "psr/simple-cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\SimpleCache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for simple caching", - "keywords": [ - "cache", - "caching", - "psr", - "psr-16", - "simple-cache" - ], - "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" - }, - "time": "2021-10-29T13:26:27+00:00" - }, { "name": "ralouphie/getallheaders", "version": "3.0.3", @@ -1929,908 +905,6 @@ } ], "time": "2025-11-21T12:23:44+00:00" - }, - { - "name": "symfony/clock", - "version": "v8.0.8", - "source": { - "type": "git", - "url": "https://github.com/symfony/clock.git", - "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/b55a638b189a6faa875e0ccdb00908fb87af95b3", - "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3", - "shasum": "" - }, - "require": { - "php": ">=8.4", - "psr/clock": "^1.0" - }, - "provide": { - "psr/clock-implementation": "1.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/now.php" - ], - "psr-4": { - "Symfony\\Component\\Clock\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Decouples applications from the system clock", - "homepage": "https://symfony.com", - "keywords": [ - "clock", - "psr20", - "time" - ], - "support": { - "source": "https://github.com/symfony/clock/tree/v8.0.8" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2026-03-30T15:14:47+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.37.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "141046a8f9477948ff284fa65be2095baafb94f2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", - "reference": "141046a8f9477948ff284fa65be2095baafb94f2", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2026-04-10T16:19:22+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.37.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", - "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", - "shasum": "" - }, - "require": { - "ext-iconv": "*", - "php": ">=7.2" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2026-04-10T17:25:58+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.37.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", - "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2026-04-10T16:19:22+00:00" - }, - { - "name": "symfony/polyfill-php84", - "version": "v1.37.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/88486db2c389b290bf87ff1de7ebc1e13e42bb06", - "reference": "88486db2c389b290bf87ff1de7ebc1e13e42bb06", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php84\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.37.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2026-04-10T18:47:49+00:00" - }, - { - "name": "symfony/polyfill-php85", - "version": "v1.37.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/fcfa4973a9917cef23f2e38774da74a2b7d115ee", - "reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php85\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.5+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.37.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2026-04-26T13:10:57+00:00" - }, - { - "name": "symfony/polyfill-php86", - "version": "v1.37.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php86.git", - "reference": "33d8fc5a705481e21fe3a81212b26f9b1f61749c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php86/zipball/33d8fc5a705481e21fe3a81212b26f9b1f61749c", - "reference": "33d8fc5a705481e21fe3a81212b26f9b1f61749c", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php86\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.6+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php86/tree/v1.37.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2026-04-26T13:13:48+00:00" - }, - { - "name": "symfony/translation", - "version": "v8.0.10", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation.git", - "reference": "f63e9342e12646a57c91ef8a366a4f9d8e557b67" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/f63e9342e12646a57c91ef8a366a4f9d8e557b67", - "reference": "f63e9342e12646a57c91ef8a366a4f9d8e557b67", - "shasum": "" - }, - "require": { - "php": ">=8.4", - "symfony/polyfill-mbstring": "^1.0", - "symfony/translation-contracts": "^3.6.1" - }, - "conflict": { - "nikic/php-parser": "<5.0", - "symfony/http-client-contracts": "<2.5", - "symfony/service-contracts": "<2.5" - }, - "provide": { - "symfony/translation-implementation": "2.3|3.0" - }, - "require-dev": { - "nikic/php-parser": "^5.0", - "psr/log": "^1|^2|^3", - "symfony/config": "^7.4|^8.0", - "symfony/console": "^7.4|^8.0", - "symfony/dependency-injection": "^7.4|^8.0", - "symfony/finder": "^7.4|^8.0", - "symfony/http-client-contracts": "^2.5|^3.0", - "symfony/http-kernel": "^7.4|^8.0", - "symfony/intl": "^7.4|^8.0", - "symfony/polyfill-intl-icu": "^1.21", - "symfony/routing": "^7.4|^8.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^7.4|^8.0" - }, - "type": "library", - "autoload": { - "files": [ - "Resources/functions.php" - ], - "psr-4": { - "Symfony\\Component\\Translation\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides tools to internationalize your application", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/translation/tree/v8.0.10" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2026-05-06T11:30:54+00:00" - }, - { - "name": "symfony/translation-contracts", - "version": "v3.7.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation-contracts.git", - "reference": "0ab302977a952b42fd51475c4ebac81f8da0a95d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/0ab302977a952b42fd51475c4ebac81f8da0a95d", - "reference": "0ab302977a952b42fd51475c4ebac81f8da0a95d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Translation\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to translation", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.7.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://github.com/nicolas-grekas", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2026-01-05T13:30:16+00:00" - }, - { - "name": "vlucas/phpdotenv", - "version": "v5.6.3", - "source": { - "type": "git", - "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "955e7815d677a3eaa7075231212f2110983adecc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/955e7815d677a3eaa7075231212f2110983adecc", - "reference": "955e7815d677a3eaa7075231212f2110983adecc", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "graham-campbell/result-type": "^1.1.4", - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.5", - "symfony/polyfill-ctype": "^1.26", - "symfony/polyfill-mbstring": "^1.26", - "symfony/polyfill-php80": "^1.26" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "ext-filter": "*", - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "suggest": { - "ext-filter": "Required to use the boolean validator." - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, - "branch-alias": { - "dev-master": "5.6-dev" - } - }, - "autoload": { - "psr-4": { - "Dotenv\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Vance Lucas", - "email": "vance@vancelucas.com", - "homepage": "https://github.com/vlucas" - } - ], - "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", - "keywords": [ - "dotenv", - "env", - "environment" - ], - "support": { - "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.3" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", - "type": "tidelift" - } - ], - "time": "2025-12-27T19:49:13+00:00" - }, - { - "name": "voku/portable-ascii", - "version": "2.1.1", - "source": { - "type": "git", - "url": "https://github.com/voku/portable-ascii.git", - "reference": "8e1051fe39379367aecf014f41744ce7539a856f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/8e1051fe39379367aecf014f41744ce7539a856f", - "reference": "8e1051fe39379367aecf014f41744ce7539a856f", - "shasum": "" - }, - "require": { - "php": ">=7.1.0" - }, - "require-dev": { - "phpunit/phpunit": "~8.5 || ~9.6 || ~10.5 || ~11.5" - }, - "suggest": { - "ext-intl": "Use Intl for transliterator_transliterate() support" - }, - "type": "library", - "autoload": { - "psr-4": { - "voku\\": "src/voku/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Lars Moelleken", - "homepage": "https://www.moelleken.org/" - } - ], - "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", - "homepage": "https://github.com/voku/portable-ascii", - "keywords": [ - "ascii", - "clean", - "php" - ], - "support": { - "issues": "https://github.com/voku/portable-ascii/issues", - "source": "https://github.com/voku/portable-ascii/tree/2.1.1" - }, - "funding": [ - { - "url": "https://www.paypal.me/moelleken", - "type": "custom" - }, - { - "url": "https://github.com/voku", - "type": "github" - }, - { - "url": "https://opencollective.com/portable-ascii", - "type": "open_collective" - }, - { - "url": "https://www.patreon.com/voku", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", - "type": "tidelift" - } - ], - "time": "2026-04-26T05:33:54+00:00" } ], "packages-dev": [ diff --git a/backend/config/container.php b/backend/config/container.php index 0ceac29..d01341b 100644 --- a/backend/config/container.php +++ b/backend/config/container.php @@ -3,9 +3,7 @@ use App\Auth\BcryptPasswordHasher; use App\Auth\Clock; use App\Auth\PasswordHasher; -use App\Auth\PostgresSessionRepository; use App\Auth\RandomTokenGenerator; -use App\Auth\SessionRepository; use App\Auth\SystemClock; use App\Auth\TokenGenerator; use App\Auth\UseCases\AuthenticateUser\AuthenticateUser; @@ -13,9 +11,8 @@ use App\Auth\UseCases\CreateSession\CreateSession; use App\Auth\UseCases\Logout\Logout; use App\Controllers\AuthController; use App\Middleware\AuthMiddleware; -use App\User\PostgresUserRepository; -use App\User\UserRepository; use DI\ContainerBuilder; +use Psr\Container\ContainerInterface; $builder = new ContainerBuilder(); @@ -26,10 +23,6 @@ $builder->addDefinitions([ TokenGenerator::class => DI\create(RandomTokenGenerator::class), Clock::class => DI\create(SystemClock::class), - // Repositories - UserRepository::class => DI\create(PostgresUserRepository::class), - SessionRepository::class => DI\create(PostgresSessionRepository::class), - // Use cases AuthenticateUser::class => DI\autowire(), CreateSession::class => DI\autowire(), diff --git a/backend/config/database.php b/backend/config/database.php deleted file mode 100644 index 06a2816..0000000 --- a/backend/config/database.php +++ /dev/null @@ -1,20 +0,0 @@ -addConnection([ - 'driver' => 'pgsql', - 'host' => $_ENV['DB_HOST'], - 'port' => $_ENV['DB_PORT'], - 'database' => $_ENV['DB_NAME'], - 'username' => $_ENV['DB_USER'], - 'password' => $_ENV['DB_PASSWORD'], - 'charset' => 'utf8', -]); - -$capsule->setAsGlobal(); -$capsule->bootEloquent(); - -return $capsule; diff --git a/backend/config/routes.php b/backend/config/routes.php index e2f963f..cd9f359 100644 --- a/backend/config/routes.php +++ b/backend/config/routes.php @@ -2,14 +2,11 @@ use App\Controllers\AuthController; use App\Middleware\AuthMiddleware; -use App\Middleware\CorsMiddleware; use Slim\App; use Slim\Routing\RouteCollectorProxy; return function (App $app): void { - $app->add(CorsMiddleware::class); - $app->get('/me', [AuthController::class, 'me']) ->add(AuthMiddleware::class); diff --git a/backend/database/Migration.php b/backend/database/Migration.php deleted file mode 100644 index 9e6b286..0000000 --- a/backend/database/Migration.php +++ /dev/null @@ -1,18 +0,0 @@ - 'datetime', - 'created_at' => 'datetime', - ]; - - public function user(): BelongsTo - { - return $this->belongsTo(UserModel::class, 'user_id'); - } -} diff --git a/backend/database/UserModel.php b/backend/database/UserModel.php deleted file mode 100644 index cd73d2f..0000000 --- a/backend/database/UserModel.php +++ /dev/null @@ -1,21 +0,0 @@ - 'int', - ]; -} diff --git a/backend/database/migrations/2026_05_17_000001_create_users_table.php b/backend/database/migrations/2026_05_17_000001_create_users_table.php deleted file mode 100644 index 117da05..0000000 --- a/backend/database/migrations/2026_05_17_000001_create_users_table.php +++ /dev/null @@ -1,26 +0,0 @@ -create('users', function ($table) { - $table->increments('id'); - $table->string('email', 255)->unique(); - $table->string('password_hash', 255); - $table->timestamps(); - }); - } - - public function down(): void - { - Capsule::schema()->dropIfExists('users'); - } -} - -return CreateUsersTable::class; diff --git a/backend/database/migrations/2026_05_17_000002_create_sessions_table.php b/backend/database/migrations/2026_05_17_000002_create_sessions_table.php deleted file mode 100644 index 0648531..0000000 --- a/backend/database/migrations/2026_05_17_000002_create_sessions_table.php +++ /dev/null @@ -1,30 +0,0 @@ -create('sessions', function ($table) { - $table->string('token')->primary(); - $table->integer('user_id')->unsigned(); - $table->foreign('user_id') - ->references('id') - ->on('users') - ->cascadeOnDelete(); - $table->dateTime('expires_at'); - $table->dateTime('created_at'); - }); - } - - public function down(): void - { - Capsule::schema()->dropIfExists('sessions'); - } -} - -return CreateSessionsTable::class; diff --git a/backend/public/index.php b/backend/public/index.php index f2c5154..0209daf 100644 --- a/backend/public/index.php +++ b/backend/public/index.php @@ -6,19 +6,14 @@ use Slim\App; (static function (): void { $root = dirname(__DIR__); - require $root . '/vendor/autoload.php'; + require $root.'/vendor/autoload.php'; - $dotenv = Dotenv\Dotenv::createImmutable($root); - $dotenv->safeLoad(); - - require $root . '/config/database.php'; - - $container = require $root . '/config/container.php'; + $container = require $root.'/config/container.php'; /** @var App $app */ $app = Bridge::create($container); - (require $root . '/config/routes.php')($app); + (require $root.'/config/routes.php')($app); $app->run(); })(); diff --git a/flake.nix b/flake.nix index 945ae9d..c312b7c 100644 --- a/flake.nix +++ b/flake.nix @@ -24,25 +24,6 @@ postgresql process-compose ]; - - shellHook = '' - REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" - export PGDATA="$REPO_ROOT/.postgres" - export PGHOST="$PGDATA" - export PGUSER="postgres" - export PGDATABASE="rabbigerzi" - - if [ ! -d "$PGDATA" ]; then - echo "[pg] initializing cluster at $PGDATA" - initdb --auth=trust --username=postgres --no-locale --encoding=UTF8 >/dev/null - { - echo "listen_addresses = '127.0.0.1'" - echo "unix_socket_directories = '$PGDATA'" - } >> "$PGDATA/postgresql.conf" - fi - - echo "[dev] run 'process-compose up' to start postgres + backend + vite" - ''; }; } ); diff --git a/frontend/rabbi_gerzi/.env b/frontend/rabbi_gerzi/.env deleted file mode 100644 index c2058b5..0000000 --- a/frontend/rabbi_gerzi/.env +++ /dev/null @@ -1 +0,0 @@ -VITE_API_BASE_URL=http://localhost:8000 diff --git a/frontend/rabbi_gerzi/cypress/e2e/login.cy.ts b/frontend/rabbi_gerzi/cypress/e2e/login.cy.ts deleted file mode 100644 index 5629504..0000000 --- a/frontend/rabbi_gerzi/cypress/e2e/login.cy.ts +++ /dev/null @@ -1,48 +0,0 @@ -describe('admin login page', () => { - it('renders the login form with email, password, and submit button', () => { - cy.visit('/login') - - cy.get('[data-cy="login-email"]').should('be.visible') - cy.get('[data-cy="login-password"]').should('be.visible') - cy.get('[data-cy="login-submit"]').should('be.visible') - }) - - it('is not linked from the home page', () => { - cy.visit('/') - - cy.contains('login').should('not.exist') - cy.contains('Login').should('not.exist') - cy.contains('admin').should('not.exist') - cy.contains('Admin').should('not.exist') - cy.get('a[href="/login"]').should('not.exist') - }) - - it('shows an error on failed login', () => { - cy.visit('/login') - - cy.get('[data-cy="login-email"]').type('bad@example.com') - cy.get('[data-cy="login-password"]').type('wrongpassword') - cy.get('[data-cy="login-submit"]').click() - - cy.get('[data-cy="login-error"]').should('be.visible') - }) - - it('is not linked from any navigation element on the home page', () => { - cy.visit('/') - - cy.get('header a').each(($link) => { - cy.wrap($link).should('not.have.attr', 'href', '/login') - }) - }) - - it('logs in with valid credentials and redirects to the home page', () => { - cy.visit('/login') - - cy.get('[data-cy="login-email"]').type('admin@rabbigerzi.test') - cy.get('[data-cy="login-password"]').type('password') - cy.get('[data-cy="login-submit"]').click() - - cy.url().should('eq', Cypress.config().baseUrl + '/') - cy.getCookie('auth_token').should('exist') - }) -}) diff --git a/frontend/rabbi_gerzi/src/router/index.ts b/frontend/rabbi_gerzi/src/router/index.ts index 32a0e58..9a5c8a6 100644 --- a/frontend/rabbi_gerzi/src/router/index.ts +++ b/frontend/rabbi_gerzi/src/router/index.ts @@ -1,6 +1,5 @@ import { createRouter, createWebHistory } from 'vue-router' import HomePage from '@/views/HomePage.vue' -import LoginPage from '@/views/LoginPage.vue' const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), @@ -10,11 +9,6 @@ const router = createRouter({ name: 'home', component: HomePage, }, - { - path: '/login', - name: 'login', - component: LoginPage, - }, ], }) diff --git a/frontend/rabbi_gerzi/src/stores/auth.ts b/frontend/rabbi_gerzi/src/stores/auth.ts deleted file mode 100644 index e39185e..0000000 --- a/frontend/rabbi_gerzi/src/stores/auth.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { ref, computed } from 'vue' -import { defineStore } from 'pinia' - -interface User { - id: number - email: string -} - -const API_BASE_URL = import.meta.env.VITE_API_BASE_URL as string - -export const useAuthStore = defineStore('auth', () => { - const user = ref(null) - const loginError = ref(null) - const isSubmitting = ref(false) - - const isAuthenticated = computed(() => user.value !== null) - - async function login(email: string, password: string): Promise { - loginError.value = null - isSubmitting.value = true - - try { - const response = await fetch(`${API_BASE_URL}/login`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - credentials: 'include', - body: JSON.stringify({ email, password }), - }) - - if (!response.ok) { - const data: { error?: string } = await response.json() - loginError.value = data.error ?? 'Login failed' - return false - } - - const data: { user: User } = await response.json() - user.value = data.user - return true - } catch { - loginError.value = 'Network error - could not reach server' - return false - } finally { - isSubmitting.value = false - } - } - - async function fetchUser(): Promise { - try { - const response = await fetch(`${API_BASE_URL}/me`, { - credentials: 'include', - }) - - if (!response.ok) { - user.value = null - return - } - - const data: { user: User } = await response.json() - user.value = data.user - } catch { - user.value = null - } - } - - async function logout(): Promise { - try { - await fetch(`${API_BASE_URL}/logout`, { - method: 'POST', - credentials: 'include', - }) - } finally { - user.value = null - } - } - - return { user, loginError, isSubmitting, isAuthenticated, login, fetchUser, logout } -}) diff --git a/frontend/rabbi_gerzi/src/views/LoginPage.vue b/frontend/rabbi_gerzi/src/views/LoginPage.vue deleted file mode 100644 index 11fa4ba..0000000 --- a/frontend/rabbi_gerzi/src/views/LoginPage.vue +++ /dev/null @@ -1,157 +0,0 @@ - - - - - diff --git a/process-compose.yml b/process-compose.yml index 7f71fe0..fc0b4b3 100644 --- a/process-compose.yml +++ b/process-compose.yml @@ -1,22 +1,9 @@ -version: "0.5" +version: "1" processes: - postgres: - command: postgres -D "$PGDATA" -k "$PGDATA" -c listen_addresses=127.0.0.1 - shutdown: - signal: 2 - readiness_probe: - exec: - command: pg_isready -h "$PGDATA" - initial_delay_seconds: 1 - period_seconds: 2 - backend: - command: bash backend/bin/serve + command: php -S 127.0.0.1:8000 -t backend/public/ working_dir: . - depends_on: - postgres: - condition: process_healthy availability: restart: always