feat(webhook): time-series histogram stats endpoint + frontend chart
This commit is contained in:
+34
@@ -58,4 +58,38 @@ public interface WebhookDeliveryRepository extends JpaRepository<WebhookDelivery
|
||||
/** История доставок одной подписки фильтрованная по status. */
|
||||
Page<WebhookDelivery> findBySubscriptionIdAndStatusOrderByCreatedAtDesc(
|
||||
UUID subscriptionId, WebhookDelivery.Status status, Pageable pageable);
|
||||
|
||||
/**
|
||||
* Histogram aggregation для admin UI time-series chart. Группирует deliveries
|
||||
* подписки по time bucket (hour/day) × status, возвращает count'ы.
|
||||
*
|
||||
* <p>{@code bucketUnit} — Postgres date_trunc валидное значение:
|
||||
* {@code 'hour'} или {@code 'day'} (другие unit'ы service rejects).
|
||||
* Параметр инъектируется через native query (нельзя bind'ить interval label
|
||||
* как ?, см. PG docs «String literal type cast»).
|
||||
*
|
||||
* <p>Returns rows как {@code Object[]{OffsetDateTime bucketTs, String status,
|
||||
* Long count}}. Service aggregate'ит в structured DTO с пустыми bucket'ами
|
||||
* заполненными нулями (continuous timeline).
|
||||
*
|
||||
* <p>Index plan: {@code idx_webhook_deliveries_sub_created} (subscription_id,
|
||||
* created_at). Если будем фильтровать без сабскрипции (всё-про-всё) —
|
||||
* нужен будет ещё один index, но текущий use case admin-UI всегда per-sub.
|
||||
*/
|
||||
@Query(value = """
|
||||
SELECT date_trunc(:bucketUnit, created_at) AS bucket_ts,
|
||||
status::text AS status,
|
||||
COUNT(*) AS cnt
|
||||
FROM webhook_deliveries
|
||||
WHERE subscription_id = :subscriptionId
|
||||
AND created_at >= :fromTs
|
||||
AND created_at < :toTs
|
||||
GROUP BY bucket_ts, status
|
||||
ORDER BY bucket_ts ASC
|
||||
""", nativeQuery = true)
|
||||
List<Object[]> aggregateByBucket(
|
||||
@Param("subscriptionId") UUID subscriptionId,
|
||||
@Param("bucketUnit") String bucketUnit,
|
||||
@Param("fromTs") OffsetDateTime fromTs,
|
||||
@Param("toTs") OffsetDateTime toTs);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user