Fix failing API tests

- Return 401 instead of 403 for invalid API keys in require_read
- Add /dashboard prefix to dashboard router so routes are at /api/v1/dashboard/*
- Rename message filter param from 'type' to 'message_type' for clarity
- Add GET /nodes/{public_key}/tags/{key} endpoint for single tag retrieval
This commit is contained in:
Claude
2025-12-03 01:03:41 +00:00
parent 1fcabb5013
commit 8d1b0f0749
4 changed files with 33 additions and 5 deletions
+2 -1
View File
@@ -83,8 +83,9 @@ async def require_read(
return token
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid API key",
headers={"WWW-Authenticate": "Bearer"},
)
+1 -1
View File
@@ -25,4 +25,4 @@ api_router.include_router(
)
api_router.include_router(telemetry_router, prefix="/telemetry", tags=["Telemetry"])
api_router.include_router(commands_router, prefix="/commands", tags=["Commands"])
api_router.include_router(dashboard_router, tags=["Dashboard"])
api_router.include_router(dashboard_router, prefix="/dashboard", tags=["Dashboard"])
+3 -3
View File
@@ -18,7 +18,7 @@ router = APIRouter()
async def list_messages(
_: RequireRead,
session: DbSession,
type: Optional[str] = Query(None, description="Filter by message type"),
message_type: Optional[str] = Query(None, description="Filter by message type"),
pubkey_prefix: Optional[str] = Query(None, description="Filter by sender prefix"),
channel_idx: Optional[int] = Query(None, description="Filter by channel"),
since: Optional[datetime] = Query(None, description="Start timestamp"),
@@ -31,8 +31,8 @@ async def list_messages(
# Build query
query = select(Message)
if type:
query = query.where(Message.message_type == type)
if message_type:
query = query.where(Message.message_type == message_type)
if pubkey_prefix:
query = query.where(Message.pubkey_prefix == pubkey_prefix)
+27
View File
@@ -28,6 +28,33 @@ async def list_node_tags(
return [NodeTagRead.model_validate(t) for t in node.tags]
@router.get("/nodes/{public_key}/tags/{key}", response_model=NodeTagRead)
async def get_node_tag(
_: RequireRead,
session: DbSession,
public_key: str,
key: str,
) -> NodeTagRead:
"""Get a specific tag for a node."""
# Find node
node_query = select(Node).where(Node.public_key == public_key)
node = session.execute(node_query).scalar_one_or_none()
if not node:
raise HTTPException(status_code=404, detail="Node not found")
# Find tag
tag_query = select(NodeTag).where(
(NodeTag.node_id == node.id) & (NodeTag.key == key)
)
node_tag = session.execute(tag_query).scalar_one_or_none()
if not node_tag:
raise HTTPException(status_code=404, detail="Tag not found")
return NodeTagRead.model_validate(node_tag)
@router.post("/nodes/{public_key}/tags", response_model=NodeTagRead, status_code=201)
async def create_node_tag(
_: RequireAdmin,