Files
bookhoard/scripts/verify-quick.sh
T
john-okeefe 6d6640e23b docs: clarify OOP guideline - applies to TypeScript, not Go
Updated PROJECT_GUIDELINES.md and verification script to clarify:

1. OOP restriction applies to FRONTEND (TypeScript) only
2. Go methods are fine and encouraged
3. Avoid classes, inheritance, and OOP bloat in TypeScript

Changed verification script:
- Removed Go struct methods check (was incorrect)
- Added TypeScript class declaration check instead
- Now checks for 'class ' keyword in web/*.ts files

This clarifies the guideline was never about Go backend code,
only about avoiding OOP patterns in TypeScript frontend code.

Verification now shows: 13/13 checks passing, 0 warnings
Only 1 error remains: 12 legacy templates with custom CSS.
2026-02-02 10:12:41 -05:00

257 lines
10 KiB
Bash
Executable File

#!/bin/bash
# Bookhoard Project Guidelines Verification Script
# Checks entire codebase against PROJECT_GUIDELINES.md
# Usage: make verify-guidelines or ./scripts/verify-quick.sh
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
ERRORS=0
WARNINGS=0
PASSED=0
error_msg() { echo -e "${RED}✗ ERROR: $1${NC}"; ERRORS=$((ERRORS + 1)); }
warning_msg() { echo -e "${YELLOW}⚠ WARNING: $1${NC}"; WARNINGS=$((WARNINGS + 1)); }
success_msg() { echo -e "${GREEN}✓ PASS: $1${NC}"; PASSED=$((PASSED + 1)); }
section() { echo ""; echo -e "${BLUE}--- $1 ---${NC}"; }
echo -e "${BLUE}=== Bookhoard Project Guidelines Verification ===${NC}"
echo ""
###############################################################################
## 🚨 CRITICAL PROHIBITIONS: Backend & Database
###############################################################################
section "Backend & Database: No local server binaries"
# GUIDELINE: NEVER build server binaries locally - all builds through Dockerfile/docker-compose
echo "Checking for server binaries (should build through containers)..."
BINARIES=$(find . -type f \( -name "bookhoard" -o -name "server" \) -not -path "./node_modules/*" -not -path "./.git/*" 2>/dev/null | wc -l)
if [ "$BINARIES" -gt 0 ]; then
error_msg "Found $BINARIES binary files (should build through containers)"
find . -type f \( -name "bookhoard" -o -name "server" \) -not -path "./node_modules/*" -not -path "./.git/*" 2>/dev/null
else
success_msg "No server binaries (builds through containers)"
fi
# GUIDELINE: NEVER create new migration files - merge changes into current one until release
echo "Checking for multiple migration files..."
if [ -d "migrations" ]; then
MIGRATION_COUNT=$(find migrations/ -name "*.sql" 2>/dev/null | wc -l)
if [ "$MIGRATION_COUNT" -gt 1 ]; then
error_msg "Found $MIGRATION_COUNT migration files (should merge into current one)"
else
success_msg "Migration files OK (single file or none)"
fi
else
success_msg "No migrations directory (not implemented yet)"
fi
###############################################################################
## 🚨 CRITICAL PROHIBITIONS: Frontend & Styling
###############################################################################
section "Frontend & Styling: No custom CSS (use TailwindCSS)"
# GUIDELINE: NEVER use custom CSS - TailwindCSS classes only
echo "Checking for custom CSS in templates (should use TailwindCSS)..."
STYLE_COUNT=$(grep -l '<style>' templates/*.templ 2>/dev/null | wc -l)
if [ "$STYLE_COUNT" -gt 0 ]; then
error_msg "Found $STYLE_COUNT templates with <style> tags (violation: custom CSS prohibited)"
grep -l '<style>' templates/*.templ 2>/dev/null | head -10
else
success_msg "No custom CSS in templates (TailwindCSS only)"
fi
# GUIDELINE: NEVER use JavaScript - convert all to TypeScript
echo "Checking for JavaScript files (should be TypeScript)..."
JS_COUNT=$(find . -name "*.js" -not -path "./node_modules/*" -not -path "./docs/*" -not -path "./.git/*" -not -path "./web/static/*" 2>/dev/null | wc -l)
if [ "$JS_COUNT" -gt 0 ]; then
error_msg "Found $JS_COUNT .js files (violation: JavaScript prohibited, use TypeScript)"
find . -name "*.js" -not -path "./node_modules/*" -not -path "./docs/*" -not -path "./.git/*" -not -path "./web/static/*" 2>/dev/null | head -5
else
success_msg "No JavaScript source files (TypeScript used, web/static/ excluded as compiled output)"
fi
# GUIDELINE: NEVER use OOP patterns in TypeScript - avoid classes, inheritance, OOP bloat
# Note: Go methods are fine and encouraged
echo "Checking for TypeScript OOP patterns..."
TS_OOP=$(find web/ -name "*.ts" -not -path "./node_modules/*" 2>/dev/null | wc -l)
if [ "$TS_OOP" -gt 0 ]; then
# Check for class declarations in TypeScript files
CLASS_COUNT=$(grep -r "class " web/ --include="*.ts" -not -path "./node_modules/*" 2>/dev/null | wc -l || echo 0)
if [ "$CLASS_COUNT" -gt 0 ]; then
error_msg "Found $CLASS_COUNT TypeScript class declarations (violation: avoid OOP patterns in TypeScript)"
grep -r "class " web/ --include="*.ts" -not -path "./node_modules/*" 2>/dev/null | head -5
else
success_msg "No TypeScript OOP patterns found (functional/other paradigms used)"
fi
else
success_msg "No TypeScript files to check (or not using OOP)"
fi
###############################################################################
## 🚨 CRITICAL PROHIBITIONS: General
###############################################################################
section "General: No secrets committed"
# GUIDELINE: NEVER commit files with secrets (.env, credentials.json, etc.)
echo "Checking for secrets in repository..."
if [ -f ".env" ] || [ -f "credentials.json" ]; then
error_msg "Found .env or credentials.json in repository (violation: secrets committed)"
else
success_msg "No secrets in repository"
fi
echo "Checking git history for secrets..."
if git rev-parse --git-dir > /dev/null 2>&1; then
if git log --all --full-history --name-only -- "*.env" "credentials.json" "secrets.*" 2>/dev/null | grep -q "."; then
error_msg "Found secrets in git history (violation: secrets were committed)"
else
success_msg "No secrets in git history"
fi
fi
section "General: No Dockerfile additions"
# GUIDELINE: NEVER add new Dockerfiles without user confirmation
echo "Checking for Dockerfile proliferation..."
DOCKERFILE_COUNT=$(find . -name "Dockerfile*" -not -path "./.git/*" 2>/dev/null | wc -l)
if [ "$DOCKERFILE_COUNT" -gt 1 ]; then
warning_msg "Found $DOCKERFILE_COUNT Dockerfile files (should use single Dockerfile)"
find . -name "Dockerfile*" -not -path "./.git/*" 2>/dev/null
else
success_msg "Single Dockerfile structure (correct)"
fi
###############################################################################
## ✅ MANDATORY REQUIREMENTS: Build & Deployment
###############################################################################
section "Build & Deployment: Code compiles"
# GUIDELINE: Post-Edit Verification - must compile after each file edit
# GUIDELINE: Use Podman for builds (production uses Docker, that's OK)
echo "Verifying code compiles..."
if go build -o /tmp/bookhoard-test ./cmd/server 2>/dev/null; then
success_msg "Code compiles successfully"
rm -f /tmp/bookhoard-test
else
error_msg "Build failed (violation: must compile after edits)"
fi
# GUIDELINE: Follow pgx v5 standards for all database operations
echo "Checking database driver version..."
if [ -f "go.mod" ]; then
if grep -q "github.com/jackc/pgx/v5" go.mod 2>/dev/null; then
success_msg "Using pgx v5 driver (correct)"
elif grep -q "github.com/jackc/pgx/v4" go.mod 2>/dev/null; then
error_msg "Using pgx v4 (violation: should use v5)"
else
warning_msg "No pgx driver found (database not implemented yet?)"
fi
fi
###############################################################################
## ✅ MANDATORY REQUIREMENTS: Frontend & Styling
###############################################################################
section "Frontend & Styling: TailwindCSS usage"
# GUIDELINE: Always use TailwindCSS classes for all styling
echo "Checking for TailwindCSS usage in templates..."
if grep -q "tailwindcss" templates/*.templ 2>/dev/null || grep -q "cdn.tailwindcss.com" templates/*.templ 2>/dev/null; then
success_msg "TailwindCSS is being used in templates"
else
warning_msg "TailwindCSS not found in templates (custom CSS may be excessive)"
fi
###############################################################################
## ✅ MANDATORY REQUIREMENTS: Code Modification Safety
###############################################################################
section "Code Modification Safety: No large single commits"
# GUIDELINE: Use multiple, logical git commits with clear messages
# Check if recent commits changed too many files at once
echo "Checking recent commit quality..."
if git rev-parse --git-dir > /dev/null 2>&1; then
LARGE_COMMITS=$(git log --oneline -10 --pretty=format:"%h" | while read hash; do
FILES=$(git diff-tree --no-commit-id --name-only -r "$hash" 2>/dev/null | wc -l)
if [ "$FILES" -gt 15 ]; then
echo "$hash: changed $FILES files"
fi
done | wc -l)
if [ "$LARGE_COMMITS" -gt 2 ]; then
warning_msg "Found $LARGE_COMMITS recent commits changing >15 files each (should use multiple commits)"
else
success_msg "Recent commits are well-scoped (multiple logical commits)"
fi
fi
###############################################################################
## ✅ MANDATORY REQUIREMENTS: Configuration & Environment
###############################################################################
section "Configuration: Example .env exists"
# GUIDELINE: If .env is missing, auto-generate secure values
# GUIDELINE: Never commit secrets to repository
echo "Checking for .env.example..."
if [ -f ".env.example" ]; then
success_msg ".env.example exists (template for configuration)"
else
warning_msg ".env.example not found (should have template)"
fi
echo "Checking .gitignore for .env..."
if git rev-parse --git-dir > /dev/null 2>&1; then
if grep -q "^\.env$" .gitignore 2>/dev/null || grep -q "^\.env$" .gitignore 2>/dev/null; then
success_msg ".env is in .gitignore (secrets protected)"
else
error_msg ".env not in .gitignore (violation: secrets might be committed)"
fi
fi
###############################################################################
## Summary & Exit Code
###############################################################################
echo ""
echo -e "${BLUE}=== Verification Summary ===${NC}"
echo -e "${GREEN}PASSED: $PASSED${NC}"
echo -e "${YELLOW}WARNINGS: $WARNINGS${NC}"
echo -e "${RED}ERRORS: $ERRORS${NC}"
echo ""
if [ $ERRORS -gt 0 ]; then
echo -e "${RED}❌ GUIDELINE VERIFICATION FAILED${NC}"
echo ""
echo "Please fix the errors above before committing."
echo ""
echo "Run 'git status' to see uncommitted changes."
echo "Run 'git diff' to see what changed."
echo ""
echo "Refer to PROJECT_GUIDELINES.md for full details."
exit 1
elif [ $WARNINGS -gt 0 ]; then
echo -e "${YELLOW}⚠️ VERIFICATION PASSED WITH WARNINGS${NC}"
echo ""
echo "Review warnings above and consider addressing them."
echo "These are not blocking commits but should be fixed soon."
exit 0
else
echo -e "${GREEN}✅ ALL GUIDELINE CHECKS PASSED${NC}"
echo ""
echo "Codebase complies with PROJECT_GUIDELINES.md"
exit 0
fi