Agent Skillslncrawl/lightnovel-crawler › add-api-endpoint

add-api-endpoint

GitHub

指导在lncrawl项目中添加或修改FastAPI端点,涵盖路由聚合、用户/管理员安全认证、DTO/DAO模型使用、分页及错误处理规范。

.claude/skills/add-api-endpoint/SKILL.md lncrawl/lightnovel-crawler

Trigger Scenarios

需要新增或修改API接口 涉及lncrawl/server/api/目录的代码变更 需要配置路由安全依赖

Install

npx skills add lncrawl/lightnovel-crawler --skill add-api-endpoint -g -y
More Options

Non-standard path

npx skills add https://github.com/lncrawl/lightnovel-crawler/tree/dev/.claude/skills/add-api-endpoint -g -y

Use without installing

npx skills use lncrawl/lightnovel-crawler@add-api-endpoint

指定 Agent (Claude Code)

npx skills add lncrawl/lightnovel-crawler --skill add-api-endpoint -a claude-code -g -y

安装 repo 全部 skill

npx skills add lncrawl/lightnovel-crawler --all -g -y

预览 repo 内 skill

npx skills add lncrawl/lightnovel-crawler --list

SKILL.md

Frontmatter
{
    "name": "add-api-endpoint",
    "description": "Add or modify a FastAPI endpoint in lncrawl — router aggregation, ensure_user\/ensure_admin security, DTO vs DAO models, pagination, ServerErrors. Use when touching lncrawl\/server\/api\/, security.py, or server\/models\/."
}

Server API (lncrawl/server/api/)

Each domain is one module with a module-level router = APIRouter() and relative paths. server/api/__init__.py aggregates them: one include_router(alias, prefix, tags, dependencies=[Security(...)]) block per module; the composite router mounts at /api in server/app.py.

Recipe: new endpoint / router

  1. Add the handler to the matching server/api/<domain>.py (or create a new module + include_router block in __init__.py).
  2. Auth: router-level dependencies=[Security(ensure_user)] covers most modules; use Security(ensure_admin) for admin routers. To get the caller inside a handler, add a user: User = Security(ensure_user) parameter; to tighten one route inside a looser router, use per-route dependencies=[Security(ensure_admin)].
  3. Delegate all logic to a service singleton (ctx.<service>) — handlers stay thin. Return DAO SQLModel objects or server/models/ Pydantic DTOs directly; FastAPI serializes them.
  4. Request bodies are Pydantic models in server/models/ (re-exported from its __init__.py) via Body(...); query/path params via Query(...)/Path(...).
  5. Quota/permission checks go through ctx.tier.<check>(user) — never inline tier logic.

Security model (server/security.py)

  • ensure_user accepts either HTTP Basic (email+password) or a Bearer JWT; rejects inactive users. JWT scopes = provided scopes ∪ {user.role, user.tier} (services/users.py); verify_token requires all Security(..., scopes=[...]) scopes.
  • ensure_admin = ensure_user with the ADMIN scope plus an explicit role check (the role check matters because the Basic-auth path bypasses scope verification).
  • ensure_local exists but is currently used by no endpoint — don't copy it as a live pattern without checking.
  • WebSocket routers must not inherit HTTP security dependencies — that's why the LSP router is included first, without a parent dependency (see the comment in api/__init__.py). The only WebSocket is /api/lsp.
  • Protected static files (/static/novels|images|sources/...) authenticate via a ?token= query param (StaticFilesGuard middleware), not headers — that's how the web UI loads images and downloads artifacts.

Conventions

  • Paths: list endpoints extend the router prefix with a bare "s"@router.get("s") under prefix /novel serves GET /api/novels while @router.get("/{novel_id}") serves GET /api/novel/{id}. Follow it for new list routes.
  • Pagination: Paginated[T] (server/models/pagination.py) = {total, offset, limit, items}; conventional params offset: int = Query(default=0), limit: Query(default=20, le=100). When adding filters, apply the same conditions to the total count query — some existing services count unfiltered totals; don't copy that.
  • Errors: raise the pre-instantiated singletons from ServerErrors (lncrawl/exceptions.py), optionally .with_extra(detail). Add new error kinds to that catalog; do not hand-roll HTTPException. Exception handlers registered in app.py produce {"error": ..., "detail": ...} bodies. WebSocket errors use the separate WebSocketError classes.
  • Swagger UI at /docs, ReDoc at /redoc, raw spec at /openapi.json; /health is the unauthenticated liveness probe.
  • server/web/ is committed build output synced from the lncrawl-web repo's artifacts branch by the "Sync Web" workflow — never hand-edit it.

Version History

  • b76d44a Current 2026-07-25 09:00

Same Skill Collection

.claude/skills/add-job-type/SKILL.md
.claude/skills/add-source/SKILL.md
.claude/skills/db-migration/SKILL.md
.claude/skills/output-and-translation/SKILL.md
.claude/skills/releasing/SKILL.md
.claude/skills/triage-source-issues/SKILL.md

Metadata

Files
0
Version
59b0382
Hash
9ed84a37
Indexed
2026-07-25 09:00

Accueil - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-29 05:35
浙ICP备14020137号-1 $Carte des visiteurs$