Standardize API response envelopes: use items for collection responses and update tests

This commit is contained in:
2026-04-28 20:48:00 +02:00
parent 1c673d600c
commit b27765928a
23 changed files with 186 additions and 104 deletions

View File

@@ -4,6 +4,8 @@
* `backend/app/models/ban.py` — dashboard dashboard sections.
*/
import type { PaginatedListResponse } from "./response";
// ---------------------------------------------------------------------------
// Time-range selector
// ---------------------------------------------------------------------------
@@ -57,16 +59,7 @@ export interface DashboardBanItem {
*
* Mirrors `DashboardBanListResponse` from `backend/app/models/ban.py`.
*/
export interface DashboardBanListResponse {
/** Ban items for the current page. */
items: DashboardBanItem[];
/** Total number of bans in the selected time window. */
total: number;
/** Current 1-based page number. */
page: number;
/** Maximum items per page. */
page_size: number;
}
export interface DashboardBanListResponse extends PaginatedListResponse<DashboardBanItem> {}
// ---------------------------------------------------------------------------
// Ban trend

View File

@@ -2,6 +2,8 @@
* TypeScript interfaces for the configuration and server settings API.
*/
import type { CollectionResponse } from "./response";
// ---------------------------------------------------------------------------
// Ban-time escalation
// ---------------------------------------------------------------------------
@@ -66,10 +68,7 @@ export interface JailConfigResponse {
jail: JailConfig;
}
export interface JailConfigListResponse {
items: JailConfig[];
total: number;
}
export interface JailConfigListResponse extends CollectionResponse<JailConfig> {}
export interface JailConfigUpdate {
ban_time?: number | null;
@@ -535,10 +534,7 @@ export interface InactiveJail {
has_local_override: boolean;
}
export interface InactiveJailListResponse {
items: InactiveJail[];
total: number;
}
export interface InactiveJailListResponse extends CollectionResponse<InactiveJail> {}
/**
* Optional override values when activating an inactive jail.

View File

@@ -7,7 +7,16 @@
* - `backend/app/models/geo.py` (GeoDetail / IpLookupResponse)
*/
import type { BantimeEscalation, BackendType, LogEncoding } from "./config";
import type {
BantimeEscalation,
BackendType,
LogEncoding,
} from "./config";
import type {
CollectionResponse,
PaginatedListResponse,
CommandResponse,
} from "./response";
// ---------------------------------------------------------------------------
// Jail statistics
@@ -64,12 +73,14 @@ export interface JailSummary {
*
* Mirrors `JailListResponse` from `backend/app/models/jail.py`.
*/
export interface JailListResponse {
/** All known jails. */
items: JailSummary[];
/** Total number of jails. */
total: number;
}
export interface JailListResponse extends CollectionResponse<JailSummary> {}
/**
* Response from `GET /api/jails/{name}/ignoreip`.
*
* Mirrors `IgnoreListResponse` from `backend/app/models/jail.py`.
*/
export interface IgnoreListResponse extends CollectionResponse<string> {}
// ---------------------------------------------------------------------------
// Jail detail
@@ -83,6 +94,8 @@ export interface JailListResponse {
export interface Jail {
/** Machine-readable jail name. */
name: string;
/** Whether the jail is enabled in the configuration. */
enabled: boolean;
/** Whether the jail is running. */
running: boolean;
/** Whether the jail is in idle mode. */
@@ -95,8 +108,10 @@ export interface Jail {
fail_regex: string[];
/** Ignore-regex patterns used to whitelist log lines. */
ignore_regex: string[];
/** Date-pattern used for timestamp parsing, or empty string. */
date_pattern: string;
/** IP addresses and networks explicitly ignored by the jail. */
ignore_ips: string[];
/** Date-pattern used for timestamp parsing, or `null` when unset. */
date_pattern: string | null;
/** Log file encoding (e.g. `"UTF-8"`). */
log_encoding: LogEncoding;
/** Action names attached to this jail. */
@@ -136,9 +151,7 @@ export interface JailDetailResponse {
*
* Mirrors `JailCommandResponse` from `backend/app/models/jail.py`.
*/
export interface JailCommandResponse {
/** Human-readable result message. */
message: string;
export interface JailCommandResponse extends CommandResponse {
/** Target jail name, or `"*"` for operations on all jails. */
jail: string;
}
@@ -172,12 +185,7 @@ export interface ActiveBan {
*
* Mirrors `ActiveBanListResponse` from `backend/app/models/ban.py`.
*/
export interface ActiveBanListResponse {
/** List of all currently active bans. */
items: ActiveBan[];
/** Total number of active bans. */
total: number;
}
export interface ActiveBanListResponse extends CollectionResponse<ActiveBan> {}
// ---------------------------------------------------------------------------
// Geo / IP lookup
@@ -207,16 +215,7 @@ export interface UnbanAllResponse {
*
* Mirrors `JailBannedIpsResponse` from `backend/app/models/ban.py`.
*/
export interface JailBannedIpsResponse {
/** Active ban entries for the current page. */
items: ActiveBan[];
/** Total matching entries (after applying any search filter). */
total: number;
/** Current page number (1-based). */
page: number;
/** Number of items per page. */
page_size: number;
}
export interface JailBannedIpsResponse extends PaginatedListResponse<ActiveBan> {}
export interface GeoDetail {
/** ISO 3166-1 alpha-2 country code (e.g. `"DE"`), or `null`. */

View File

@@ -0,0 +1,27 @@
/**
* Standardized API response envelope types.
*
* These wrappers mirror the backend response envelope contract defined in
* `backend/app/models/response.py`.
*/
export interface CollectionResponse<T> {
/** Data items in the collection. */
items: T[];
/** Total number of items in the collection. */
total: number;
}
export interface PaginatedListResponse<T> extends CollectionResponse<T> {
/** Current page number (1-based). */
page: number;
/** Number of items per page. */
page_size: number;
}
export interface CommandResponse {
/** Human-readable result message. */
message: string;
/** Whether the command succeeded. */
success: boolean;
}