Enable Discovery debug logging for production troubleshooting

- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
2025-08-11 20:13:26 +02:00
parent 59fd3dd3b1
commit 55a330b223
3683 changed files with 2956207 additions and 16948 deletions

View File

@@ -0,0 +1,249 @@
<?php
declare(strict_types=1);
namespace App\Framework\Waf\Feedback;
use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\Waf\DetectionCategory;
use App\Framework\Waf\DetectionSeverity;
use PDO;
/**
* Database implementation of the feedback repository
*/
final readonly class DatabaseFeedbackRepository implements FeedbackRepositoryInterface
{
/**
* @param PDO $pdo Database connection
*/
public function __construct(
private PDO $pdo
) {
}
/**
* {@inheritdoc}
*/
public function saveFeedback(DetectionFeedback $feedback): void
{
$stmt = $this->pdo->prepare('
INSERT INTO waf_feedback (
detection_id, feedback_type, user_id, comment,
timestamp, category, severity, context
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
');
$stmt->execute([
$feedback->detectionId,
$feedback->feedbackType->value,
$feedback->userId,
$feedback->comment,
$feedback->timestamp->toSqlString(),
$feedback->category->value,
$feedback->severity->value,
json_encode($feedback->context),
]);
}
/**
* {@inheritdoc}
*/
public function getFeedbackForDetection(string $detectionId): array
{
$stmt = $this->pdo->prepare('
SELECT
detection_id, feedback_type, user_id, comment,
timestamp, category, severity, context
FROM waf_feedback
WHERE detection_id = ?
ORDER BY timestamp DESC
');
$stmt->execute([$detectionId]);
return $this->hydrateMultipleResults($stmt);
}
/**
* {@inheritdoc}
*/
public function getFeedbackByCategory(DetectionCategory $category, ?Timestamp $since = null): array
{
$sql = '
SELECT
detection_id, feedback_type, user_id, comment,
timestamp, category, severity, context
FROM waf_feedback
WHERE category = ?
';
$params = [$category->value];
if ($since !== null) {
$sql .= ' AND timestamp >= ?';
$params[] = $since->toSqlString();
}
$sql .= ' ORDER BY timestamp DESC';
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
return $this->hydrateMultipleResults($stmt);
}
/**
* {@inheritdoc}
*/
public function getFeedbackByFeedbackType(FeedbackType $feedbackType, ?Timestamp $since = null): array
{
$sql = '
SELECT
detection_id, feedback_type, user_id, comment,
timestamp, category, severity, context
FROM waf_feedback
WHERE feedback_type = ?
';
$params = [$feedbackType->value];
if ($since !== null) {
$sql .= ' AND timestamp >= ?';
$params[] = $since->toSqlString();
}
$sql .= ' ORDER BY timestamp DESC';
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
return $this->hydrateMultipleResults($stmt);
}
/**
* {@inheritdoc}
*/
public function getFeedbackStats(): array
{
// Get total count
$totalStmt = $this->pdo->query('SELECT COUNT(*) FROM waf_feedback');
$totalCount = (int)$totalStmt->fetchColumn();
// Get counts by feedback type
$typeStmt = $this->pdo->query('
SELECT feedback_type, COUNT(*) as count
FROM waf_feedback
GROUP BY feedback_type
');
$typeStats = [];
while ($row = $typeStmt->fetch(PDO::FETCH_ASSOC)) {
$typeStats[$row['feedback_type']] = (int)$row['count'];
}
// Get counts by category
$categoryStmt = $this->pdo->query('
SELECT category, COUNT(*) as count
FROM waf_feedback
GROUP BY category
');
$categoryStats = [];
while ($row = $categoryStmt->fetch(PDO::FETCH_ASSOC)) {
$categoryStats[$row['category']] = (int)$row['count'];
}
// Get counts by severity
$severityStmt = $this->pdo->query('
SELECT severity, COUNT(*) as count
FROM waf_feedback
GROUP BY severity
');
$severityStats = [];
while ($row = $severityStmt->fetch(PDO::FETCH_ASSOC)) {
$severityStats[$row['severity']] = (int)$row['count'];
}
// Get trend data (last 30 days)
$trendStmt = $this->pdo->query('
SELECT
DATE(timestamp) as date,
feedback_type,
COUNT(*) as count
FROM waf_feedback
WHERE timestamp >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY DATE(timestamp), feedback_type
ORDER BY date
');
$trendData = [];
while ($row = $trendStmt->fetch(PDO::FETCH_ASSOC)) {
if (! isset($trendData[$row['date']])) {
$trendData[$row['date']] = [];
}
$trendData[$row['date']][$row['feedback_type']] = (int)$row['count'];
}
return [
'total_count' => $totalCount,
'by_feedback_type' => $typeStats,
'by_category' => $categoryStats,
'by_severity' => $severityStats,
'trend_data' => $trendData,
];
}
/**
* {@inheritdoc}
*/
public function getRecentFeedback(int $limit = 10): array
{
$stmt = $this->pdo->prepare('
SELECT
detection_id, feedback_type, user_id, comment,
timestamp, category, severity, context
FROM waf_feedback
ORDER BY timestamp DESC
LIMIT ?
');
$stmt->execute([$limit]);
return $this->hydrateMultipleResults($stmt);
}
/**
* Hydrates multiple DetectionFeedback objects from a PDO statement
*
* @param \PDOStatement $stmt The executed PDO statement
* @return DetectionFeedback[] Array of DetectionFeedback objects
*/
private function hydrateMultipleResults(\PDOStatement $stmt): array
{
$results = [];
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$results[] = $this->hydrateFromRow($row);
}
return $results;
}
/**
* Hydrates a DetectionFeedback object from a database row
*
* @param array $row Database row
* @return DetectionFeedback
*/
private function hydrateFromRow(array $row): DetectionFeedback
{
return new DetectionFeedback(
detectionId: $row['detection_id'],
feedbackType: FeedbackType::from($row['feedback_type']),
userId: $row['user_id'],
comment: $row['comment'],
timestamp: Timestamp::fromString($row['timestamp']),
category: DetectionCategory::from($row['category']),
severity: DetectionSeverity::from($row['severity']),
context: json_decode($row['context'] ?? '{}', true) ?: []
);
}
}