feat(blocking): определять и показывать хостер в матрице блокировок
Docker / build (push) Failing after 26s

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-08-25 13:19:02 +07:00
co-authored by Cursor
parent efebcaf16d
commit 60a22b9450
15 changed files with 273 additions and 13 deletions
@@ -1,7 +1,7 @@
import { describe, expect, it } from 'vitest'
import type { Filter } from '@/components/reui/filters'
import { filterCensorcheckRuns, groupRunsByService, collectServiceColumns, collectProbeColumns, shortHostLabel } from './blocking-filters'
import type { CensorcheckRunDto } from './types'
import { runHosterLabel, type CensorcheckRunDto } from './types'
const run = (overrides: Partial<CensorcheckRunDto> = {}): CensorcheckRunDto => ({
id: 'ccrun-1',
@@ -88,6 +88,37 @@ describe('filterCensorcheckRuns', () => {
]),
).toHaveLength(0)
})
it('фильтрует по хостеру из прогона, если инвентарь пуст', () => {
const unmatched = run({
matchedVpsId: null,
vps: null,
detectedHoster: 'DigitalOcean',
})
expect(
filterCensorcheckRuns([unmatched], [
{ id: '1', field: 'hoster', operator: 'contains', values: ['digital'] },
]),
).toHaveLength(1)
expect(
filterCensorcheckRuns([unmatched], [
{ id: '1', field: 'hoster', operator: 'contains', values: ['hetzner'] },
]),
).toHaveLength(0)
})
})
describe('runHosterLabel', () => {
it('предпочитает имя из инвентаря', () => {
expect(runHosterLabel(run())).toBe('Hoster')
expect(runHosterLabel(run({ detectedHoster: 'Hetzner' }))).toBe('Hoster')
})
it('берёт detectedHoster если VPS не сматчен', () => {
expect(runHosterLabel(run({ matchedVpsId: null, vps: null, detectedHoster: 'Hetzner' }))).toBe(
'Hetzner',
)
})
})
describe('groupRunsByService', () => {
@@ -39,7 +39,7 @@ export function filterCensorcheckRuns(
continue
}
if (filter.field === 'hoster') {
const name = (run.vps?.providerName ?? '').toLowerCase()
const name = `${run.vps?.providerName ?? ''} ${run.detectedHoster ?? ''}`.toLowerCase()
const hit = values.some((value) => name.includes(value.toLowerCase()) || name === value.toLowerCase())
if (!hit) return false
continue
@@ -13,7 +13,7 @@ import {
} from './blocking-filters'
import { resolveServiceIcon, ServiceGlyph } from './service-icons'
import { StatusMatrixCell } from './status-matrix-cell'
import type { CensorcheckRunDto } from './types'
import { runHosterLabel, type CensorcheckRunDto } from './types'
/** DNA data-grid-base-4: auto width + H-scroll + pin start. Preview: https://reui.io/preview/base/data-grid-base-4 */
export const BLOCKING_MATRIX_GRID = {
@@ -31,12 +31,14 @@ function vpsIdentityColumn(): DataGridColumn<CensorcheckRunDto> {
icon: ServerIcon,
enableHiding: false,
enablePinning: true,
size: 220,
minSize: 180,
size: 240,
minSize: 200,
sortValue: (row) => row.vps?.dns || row.probePublicIp,
cell: (row) => {
const title = row.vps?.dns || row.probePublicIp
const ip = row.probePublicIp
const hoster = runHosterLabel(row)
const secondary = hoster ? `${ip} · ${hoster}` : ip
const link = row.matchedVpsId ? (
<Link
to="/vps/$vpsId"
@@ -49,7 +51,7 @@ function vpsIdentityColumn(): DataGridColumn<CensorcheckRunDto> {
) : (
<span className="font-medium">Unknown VPS</span>
)
return dataGridCellStack(link, ip)
return dataGridCellStack(link, secondary)
},
}
}
@@ -1,5 +1,5 @@
import { Link } from '@tanstack/react-router'
import { GlobeIcon, MapPinIcon, ServerIcon, ShieldAlertIcon } from 'lucide-react'
import { Building2Icon, GlobeIcon, MapPinIcon, ServerIcon, ShieldAlertIcon } from 'lucide-react'
import { useQuery } from '@tanstack/react-query'
import {
@@ -16,6 +16,7 @@ import {
CENSORCHECK_STATUS_LABELS,
formatCheckedAt,
formatVpsResources,
runHosterLabel,
type CensorcheckRunDto,
} from './types'
@@ -67,6 +68,12 @@ export function CheckRunSheet({ run, open, onOpenChange }: CheckRunSheetProps) {
</Link>
) : undefined,
},
{
id: 'hoster',
icon: <Building2Icon />,
label: 'Хостер',
description: runHosterLabel(detail) || '—',
},
{
id: 'geo',
icon: <MapPinIcon />,
@@ -40,6 +40,7 @@ export type CensorcheckRunDto = {
createdAt: string
completedAt: string
observedSourceIp: string | null
detectedHoster?: string | null
vps: CensorcheckVpsInfo | null
results?: CensorcheckResultDto[]
}
@@ -67,12 +68,19 @@ export function formatCheckedAt(iso: string): string {
return date.toLocaleString('ru-RU')
}
export function runHosterLabel(run: CensorcheckRunDto): string {
const inventory = run.vps?.providerName?.trim() ?? ''
if (inventory) return inventory
return run.detectedHoster?.trim() ?? ''
}
export function runSearchText(run: CensorcheckRunDto): string {
const parts = [
run.probePublicIp,
run.claimedPublicIp ?? '',
run.vps?.dns ?? '',
run.vps?.providerName ?? '',
run.detectedHoster ?? '',
run.vps?.country ?? '',
...(run.results ?? []).map((row) => `${row.serviceKey} ${row.serviceLabel}`),
]