feat(Production): Complete production deployment infrastructure

- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
This commit is contained in:
2025-10-25 19:18:37 +02:00
parent caa85db796
commit fc3d7e6357
83016 changed files with 378904 additions and 20919 deletions

View File

@@ -5,22 +5,23 @@ declare(strict_types=1);
namespace App\Framework\OAuth\Storage;
use App\Framework\Database\ConnectionInterface;
use App\Framework\OAuth\ValueObjects\OAuthToken;
use App\Framework\Exception\FrameworkException;
use App\Framework\Exception\ErrorCode;
use App\Framework\Exception\FrameworkException;
use App\Framework\OAuth\ValueObjects\OAuthToken;
/**
* OAuth Token Repository
*
* Handles persistence of OAuth tokens with automatic refresh handling
*/
final readonly class OAuthTokenRepository
final readonly class OAuthTokenRepository implements OAuthTokenRepositoryInterface
{
private const TABLE = 'oauth_tokens';
public function __construct(
private ConnectionInterface $connection,
) {}
) {
}
/**
* Find token for user and provider
@@ -71,10 +72,12 @@ final readonly class OAuthTokenRepository
if ($existing !== null) {
$updated = $existing->withRefreshedToken($token);
return $this->update($updated);
}
$storedToken = StoredOAuthToken::create($userId, $provider, $token);
return $this->insert($storedToken);
}
@@ -90,9 +93,9 @@ final readonly class OAuthTokenRepository
}
/**
* Delete expired tokens (cleanup job)
* Delete expired tokens without refresh token (cleanup job)
*/
public function deleteExpired(): int
public function deleteExpiredWithoutRefreshToken(): int
{
$sql = "DELETE FROM " . self::TABLE . "
WHERE expires_at < ? AND refresh_token IS NULL";
@@ -113,7 +116,7 @@ final readonly class OAuthTokenRepository
$rows = $this->connection->fetchAll($sql, [$userId]);
return array_map(
fn(array $row) => StoredOAuthToken::fromArray($row),
fn (array $row) => StoredOAuthToken::fromArray($row),
$rows
);
}
@@ -134,7 +137,7 @@ final readonly class OAuthTokenRepository
$rows = $this->connection->fetchAll($sql, [$expiryThreshold]);
return array_map(
fn(array $row) => StoredOAuthToken::fromArray($row),
fn (array $row) => StoredOAuthToken::fromArray($row),
$rows
);
}