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:
152
scripts/check-integrity.sh
Normal file
152
scripts/check-integrity.sh
Normal 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
|
||||
Reference in New Issue
Block a user