fix(assets): case-insensitive hostname sort + null-safe last_scan
Hostnames now sort by LOWER(hostname) so 'alpine' < 'Webserver'. last_scan ORDER BY applies nulls_last on both asc and desc (was implicit on desc only). Fixes feedback 2026-06-02 #1.
This commit is contained in:
@@ -7,7 +7,7 @@ from typing import Optional, List, Any
|
||||
from datetime import datetime
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Query
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import asc, desc, nulls_last
|
||||
from sqlalchemy import asc, desc, func, nulls_last
|
||||
from pydantic import BaseModel, field_validator
|
||||
|
||||
from app.database import get_db
|
||||
@@ -387,9 +387,15 @@ async def list_assets(
|
||||
sort_dir = desc if sort_order == "desc" else asc
|
||||
if sort_by in _SORT_MAP_DIRECT:
|
||||
col = _SORT_MAP_DIRECT[sort_by]
|
||||
# last_scan can be NULL (never-synced) — keep them at the bottom.
|
||||
if sort_by == "last_scan":
|
||||
query = query.order_by(sort_dir(nulls_last(col)))
|
||||
# NULL-safe on BOTH directions — never-scanned assets land at
|
||||
# the bottom regardless of asc/desc (PG: NULLS LAST is independent
|
||||
# of the primary direction).
|
||||
query = query.order_by(nulls_last(sort_dir(col)))
|
||||
elif sort_by == "hostname":
|
||||
# Case-insensitive alpha sort — a host called "alpine" must
|
||||
# not outrank "Webserver" because the literal `A` > `W`.
|
||||
query = query.order_by(nulls_last(sort_dir(func.lower(col))))
|
||||
else:
|
||||
query = query.order_by(sort_dir(col))
|
||||
elif sort_by == "policy_name":
|
||||
|
||||
Reference in New Issue
Block a user