docs: add false completion prevention rules and fix swagger gaps

Changes:
- Add FALSE_COMPLETION_PREVENTION.md documenting false completion patterns
- Add integrity check script (scripts/check-integrity.sh) for automated verification
- Fix swagger annotation gaps in 3 handlers (+10 annotations):
  - password_reset_handler.go: +4 annotations
  - totp_handler.go: +4 annotations
  - log_handler.go: +2 annotations
- Define IntegrationRedisSuite type for Redis integration tests
- Update QUALITY_STANDARD.md with swagger completeness and response format requirements
- Update PROJECT_EXPERIENCE_SUMMARY.md with new learnings on false completion

Integrity check now validates:
- Swagger annotation completeness per handler
- Response format uniformity (with OAuth whitelist)
- Test infrastructure type definitions
- Repository test coverage
This commit is contained in:
2026-04-11 23:38:43 +08:00
parent 339c740365
commit 4193b46b5f
8 changed files with 585 additions and 2 deletions

152
scripts/check-integrity.sh Normal file
View File

@@ -0,0 +1,152 @@
#!/bin/bash
# 完整性检查脚本
# 验证 swagger 注解完整性和响应格式统一性
#
# 使用方法:
# ./scripts/check-integrity.sh # 检查所有
# ./scripts/check-integrity.sh swagger # 只检查 swagger
# ./scripts/check-integrity.sh response # 只检查响应格式
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
ERRORS=0
check_swagger() {
echo "=== Swagger 注解完整性检查 ==="
local handler_dir="internal/api/handler"
local failures=0
for f in "$handler_dir"/*_handler.go; do
# Only count methods that take *gin.Context as first param (actual HTTP handlers)
local methods=$(grep -E "^func \(h \*[A-Za-z]+.*\) [A-Z].*\(c \*gin\.Context\)" "$f" | wc -l)
local annotations=$(grep -c "@Summary" "$f" || echo 0)
if [ "$methods" != "$annotations" ]; then
echo -e "${RED}FAIL${NC}: $(basename $f) - $methods handler methods, $annotations @Summary annotations"
failures=$((failures + 1))
else
echo -e "${GREEN}PASS${NC}: $(basename $f) - $methods/$annotations"
fi
done
if [ $failures -gt 0 ]; then
echo -e "\n${RED}Swagger 检查失败: $failures 个文件有问题${NC}"
ERRORS=$((ERRORS + failures))
else
echo -e "\n${GREEN}所有 handler 的 swagger 注解完整${NC}"
fi
}
check_response_format() {
echo ""
echo "=== 响应格式统一性检查 ==="
local failures=0
# 检查直接返回 TokenResponse 或 IntrospectResponse 的情况
# 白名单OAuth 标准端点RFC 6749, RFC 7009
# - /api/v1/sso/token (OAuth Token endpoint) - 必须直接返回 TokenResponse
# - /api/v1/sso/introspect (OAuth Token Introspection) - 必须直接返回 IntrospectResponse
local direct_returns=$(grep -rn "c.JSON.*TokenResponse\|c.JSON.*IntrospectResponse" internal/api/handler/ 2>/dev/null || true)
if [ -n "$direct_returns" ]; then
# 检查是否都是白名单端点
local non_oauth=0
while IFS=: read -r file line content; do
# 这些行是白名单端点,不需要包装
if [[ "$content" == *"TokenResponse"* ]] && [[ "$line" == "213" ]]; then
echo -e "${YELLOW}WHITELIST${NC}: $file:$line - OAuth Token endpoint (RFC 6749)"
elif [[ "$content" == *"IntrospectResponse"* ]] && [[ "$line" == "257" || "$line" == "261" ]]; then
echo -e "${YELLOW}WHITELIST${NC}: $file:$line - OAuth Introspection endpoint (RFC 7009)"
else
echo -e "${RED}ISSUE${NC}: $file:$line - $content"
non_oauth=$((non_oauth + 1))
fi
done <<< "$direct_returns"
if [ $non_oauth -gt 0 ]; then
echo ""
echo -e "${RED}发现 $non_oauth 个非 OAuth 端点使用直接返回格式${NC}"
failures=$((failures + non_oauth))
else
echo ""
echo -e "${GREEN}所有直接返回格式都是白名单端点(符合 RFC 标准)${NC}"
fi
else
echo -e "${GREEN}所有 handler 使用统一响应格式${NC}"
fi
if [ $failures -gt 0 ]; then
ERRORS=$((ERRORS + failures))
fi
}
check_test_types() {
echo ""
echo "=== 测试基础设施检查 ==="
# 检查 IntegrationRedisSuite 是否定义
# 定义存在返回 0不存在返回 1
if grep -q "type IntegrationRedisSuite struct" internal/repository/*.go 2>/dev/null; then
echo -e "${GREEN}IntegrationRedisSuite 类型已定义${NC}"
else
echo -e "${RED}发现问题: IntegrationRedisSuite 类型未定义${NC}"
echo "需要在 internal/repository/ 中定义 IntegrationRedisSuite 类型"
ERRORS=$((ERRORS + 1))
fi
}
check_coverage() {
echo ""
echo "=== 测试覆盖率验证 ==="
local coverage=$(go test ./internal/repository/... -cover -count=1 2>&1 | grep "coverage" | grep -oE "[0-9]+\.[0-9]+%" | head -1)
if [ -n "$coverage" ]; then
echo -e "${GREEN}Repository 测试覆盖率: $coverage${NC}"
else
echo -e "${RED}无法获取覆盖率${NC}"
ERRORS=$((ERRORS + 1))
fi
}
# 主逻辑
case "${1:-all}" in
swagger)
check_swagger
;;
response)
check_response_format
;;
types)
check_test_types
;;
coverage)
check_coverage
;;
all)
check_swagger
check_response_format
check_test_types
check_coverage
;;
*)
echo "用法: $0 [swagger|response|types|coverage|all]"
exit 1
;;
esac
echo ""
if [ $ERRORS -gt 0 ]; then
echo -e "${RED}完整性检查失败: $ERRORS 个问题${NC}"
exit 1
else
echo -e "${GREEN}所有完整性检查通过${NC}"
exit 0
fi