Files
bookhoard/PROJECT_GUIDELINES.md
T
john-okeefe 4d321528b2 docs: update comprehensive API documentation and project guides
This commit updates all documentation files throughout the project:

- Updated IMPLEMENTATION_PLAN.md with new implementation details
- Updated PROJECT_GUIDELINES.md with coding standards and practices
- Updated README.md with current project information
- Updated SCREENSHOT_AUTOMATION.md with new automation details
- Added TEST_DATA.md with test fixtures data
- Updated cover_image_serving_plan.md with static URL patterns

Documentation API updates:
- Updated API reference documentation for all endpoints including:
  - Authentication (login, logout, register, refresh_token)
  - Book matching (auto_link, bulk_link, link_book, search)
  - Collections (CRUD operations, shelf mappings, auto-assign rules)
  - Conflicts (bulk operations, resolve/dismiss)
  - Devices (registration, approval, shelf management)
  - Highlights (create, update, delete, get)
  - Kobo sync (bookmark, markup, initialization, sync)
  - KOReader sync (library, metadata, bookmarks, progress)
  - Libraries (CRUD, folders, media items, stats)
  - Media items (bulk operations, CRUD)
  - Notes (CRUD operations)
  - OPDS (acquisition, feeds, publication)
  - Progress (reading progress tracking)
  - Queue (device queue management)
  - Ratings (star ratings)
  - Scanner (watch mode, scan operations)
  - Sync protocols (Kobo, KOReader)
  - Users (profile, password, admin operations)
  - WebSocket protocols

- Updated user guides (admin, dashboard, settings, sync)
- Updated device setup guides (Kobo, KOReader)
- Updated developer guides (testing, contributing, operations)
- Updated scripts/README.md
2026-02-27 17:06:22 -05:00

20 KiB

Combined Project Guidelines for Bookhoard

🚨 CRITICAL PROHIBITIONS (Never violate these)

Backend & Database

  • NEVER modify backend code when working on frontend-only tasks
  • NEVER modify database schema unless explicitly instructed for full-stack changes
  • NEVER use Docker - use Podman only
  • NEVER build server binaries locally - all builds through Dockerfile/docker-compose
  • NEVER create new migration files - merge changes into current one until release
  • NEVER use git checkout on schema files without checking what will be lost
  • NEVER break existing functionality unless explicitly instructed
  • NEVER duplicate business logic - keep logic in services, not handlers
  • NEVER bypass service layer - all database operations must go through services

Testing

  • ALWAYS use setupTestServer() helper from cmd/server/tests/test_helpers.go
  • Share one test setup across all subtests - call setupTestServer() once at test function level, not per subtest
  • Prefer table-driven tests - use t.Run() with test cases instead of duplicate test functions
  • Configure database pools efficiently - use max_conns=1 for test pools (via pgxpool.ParseConfig()) to prevent connection exhaustion
  • NEVER create separate pgxpool per test - each pool creates 4 connections by default; 78 tests = 312 potential connections > PostgreSQL's 100 limit
  • NEVER call setupTestServer() in loops or within subtests - creates unnecessary database pools and exhausts connections
  • DO verify tests pass - run full test suite before completing work
  • Use t.Cleanup() properly - the TestServerSetup pattern automatically handles cleanup via t.Cleanup()

Frontend & Styling

  • NEVER modify backend/API for frontend features without user confirmation
  • NEVER use custom CSS - TailwindCSS classes only
    • ⚠️ EXCEPTION: templates/error.templ may have inline CSS because error pages must work when main app fails (404, server errors, CSS fails to load)
  • NEVER use JavaScript - convert all to TypeScript
    • ⚠️ EXCEPTION: Inline JS function calls in HTML attributes (e.g., onclick="myFunction()") are acceptable for simple interactions
  • NEVER use Object-Oriented Programming (no classes, inheritance, or this-capture)
  • DO use procedural/imperative style as your default
  • DO borrow functional techniques when they simplify code
  • DO avoid ideological purity - the best paradigm is the one that fits the problem
  • NEVER add new Dockerfiles without user confirmation
  • NEVER fetch initial data via AJAX on page load - use server-side rendering instead
  • NEVER break progressive enhancement - pages must work without JavaScript

Note: Go methods in the backend are fine and encouraged. This guideline applies to TypeScript/JavaScript frontend code only.**

General

  • NEVER skip pre-commit hooks unless explicitly requested
  • NEVER force push to main/master branches
  • NEVER commit files with secrets (.env, credentials.json, etc.)
  • NEVER make assumptions - ask clarifying questions when uncertain
  • NEVER delete code without reading full context first (minimum 20 lines before/after)
  • NEVER make cascading fix-up edits without git diff review
    • After compilation error: STOP, review git diff, understand full impact
    • Use revert/reapply pattern instead of blind fixes
  • NEVER skip post-edit verification - must compile after each file edit
  • NEVER run git commands concurrently - always run sequentially:
    • Run git add <files> and wait for completion
    • Run git commit -m "<message>" and wait for completion
    • Run git push and wait for completion
    • Never use && to chain git commands together
  • Make good organized git commits for the entire project (not just what you changed) and push - run git add, commit, push sequentially as separate commands, no need to repeatedly check status
  • Indentation is always 2 spaces unless the language prohibits it

Cascading Fix-up Pattern (PROHIBITED)

WHAT NOT TO DO - This caused critical bugs:

// ❌ WRONG: Blindly making fixes after compilation error

Edit 1: Delete deprecated code
[Compilation error: undefined Register]

Edit 2: Try to fix error (over-broad deletion)
[More errors: undefined Login, GetProfile, etc.]

Edit 3: Try to fix again (worse damage)
[Even more errors: major functionality broken]

CORRECT APPROACH:

// ✅ CORRECT: Stop, understand, then fix deliberately

Edit 1: Delete deprecated code
[Compilation error: undefined Register]

STOP  Review git diff  Understand Register was accidentally deleted
RESTORE  Get exact Register function from git history
VERIFY  Compile successfully

Key Principle: When compilation errors occur after edits:

  1. STOP - Don't make more edits
  2. ANALYZE - Use git diff to understand what was changed
  3. RECOVER - Restore what was accidentally deleted/broken
  4. VERIFY - Compile and test before proceeding

🎯 CONTEXT-SPECIFIC RULES

When Working on Frontend-Only Tasks

  • DO NOT touch backend code - handlers, services, database layer
  • DO NOT modify API routes - use existing endpoints only
  • DO NOT change database schema - work with existing structure
  • If backend change seems necessary:
    1. Identify the required change
    2. Explain why you need it
    3. Provide impact analysis
    4. ASK FOR USER CONFIRMATION before proceeding

When Working on Full-Stack Tasks

  • Backend changes are allowed when explicitly part of the task
  • Still follow all database protocols (atomic changes, validation, etc.)
  • If modifying database schema: Update local database after schema.sql changes (see Database Operations section)
  • Still use Podman for all builds
  • Still include Bruno tests for API changes

MANDATORY REQUIREMENTS

Database Operations (Full-Stack Tasks Only)

  • Follow pgx v5 standards for all database operations
  • Treat schema changes as ATOMIC - complete success or complete rejection
  • ⚠️ CRITICAL: This is a pre-production application (NO production deployments exist)
    • When database/schema/schema.sql is updated, local databases must be updated
    • Option 1 (Recommended): Recreate database with fresh schema:
      podman compose down -v  # Delete volumes (WARNING: loses all data)
      podman compose up -d    # Start fresh with new schema
      
    • Option 2: Manually apply schema changes to existing database using psql
    • DO NOT create migration files - no legacy schema support needed
  • Use pre-change checklist: read schema → identify columns → plan changes → verify → read back
  • Post-change validation: ensure schema.sql, models.go, and queries.sql are in sync

Build & Deployment

  • Use Podman exclusively (not Docker)
  • All builds through existing Dockerfile and docker-compose.yml
  • Stop building server binaries - everything goes through containers

API Changes (Full-Stack Tasks Only)

  • Include Bruno OpenCollection YAML requests with all API documentation
  • Tests must be comprehensive and cover three contexts: no user, user, and admin
  • Maintain backward compatibility for mobile apps and external consumers

Frontend & Styling

  • Always use TailwindCSS classes for all styling
  • Convert all JavaScript to TypeScript
  • Never use Object-Oriented Programming (no classes, inheritance, or this-capture)
  • Use procedural/imperative style as your default
  • Borrow functional techniques when they simplify code
  • Avoid ideological purity - the best paradigm is the one that fits the problem
  • Extract domain concepts/types only when clearly beneficial - apply YAGNI, avoid over-engineering
  • Render initial data server-side in Go templates for fast page loads
  • Use JavaScript/HTMX for CRUD operations (create, update, delete)
  • Ensure progressive enhancement - pages work without JavaScript

Service Layer Architecture

  • All business logic in services - never in handlers
  • Services must be reusable by both SSR handlers and API endpoints
  • Database operations through services only - never direct from handlers
  • When adding features: Add service logic → Create API endpoint → Use SSR for initial render → Use JS for updates

Code Organization

  • Minimize project structure changes
  • Place new files in contextually appropriate directories
  • Follow KISS, DRY, and YAGNI principles
  • Use multiple, logical git commits with clear messages
  • NEVER duplicate types between handlers and templates - define data types in handlers, reuse directly in templates
  • DO share handler types with templates - templates should use handlers.CollectionData, handlers.BookInfo, etc. directly
  • NEVER create parallel type systems - no templates.XxxData types for data that originates from handlers
  • DO enhance handler types with template-specific fields when needed (e.g., add Icon, FormattedDate fields to handlers structs)
  • DO keep template-only types in templates package - PageData, UnsafeHTML, and template-specific utilities are appropriate
  • NEVER create conversion helper functions to map between handler and template types - use handler types directly

Configuration & Environment

  • If .env is missing, auto-generate secure values
  • Never commit secrets to repository

Code Modification Safety

  • Post-Edit Verification (MANDATORY for ALL file modifications):
    • Run go build for affected packages immediately after each edit
    • Review git diff filename to verify only intended changes
    • Validate functionality still works as expected
    • Never proceed to next file until current edit is verified
  • Backup Before Large Changes:
    • Create a stash: git stash push -m "Pre-cleanup snapshot" before removing >50 lines
    • Or create a backup branch: git branch backup-before-cleanup
    • This allows instant recovery if mistakes occur
  • Large Deletion Safety Pattern:
    • Read at least 20 lines before/after deletion target
    • Include unique identifiers in match (function signatures, specific comments)
    • Use narrow matches - avoid generic patterns
    • Verify line numbers match intended section

Documentation

Documentation Structure (updated with full docs system):

  • README.md - Project overview, quick start, and setup instructions only
  • docs/ - Comprehensive documentation system with search
  • docs/developer/api/ - API reference documentation (split by endpoint/category)
  • docs/user/ - User-facing features, guides, and workflows
  • docs/user/devices/ - Device setup guides (KOBO, KOReader, etc.)
  • docs/contributing/ - Development and contribution guides

Where to document changes:

Change Type Location Examples
User-facing features docs/user/ New features, UI changes, workflows
API endpoints docs/developer/api/<category>/<endpoint>.md New endpoints, modified responses, authentication changes
API behavior Update existing docs/developer/api/ files Parameter changes, error codes, rate limits
Device setup docs/user/devices/ New device support, setup instructions
Development docs/contributing/ Build changes, architecture decisions
Quick start/setup README.md Installation, environment setup, first-run
Breaking changes Both README.md and relevant docs/ Migration guides, deprecation notices
Bug fixes Update relevant docs/ only if user-visible Clarifications, troubleshooting additions
Bruno OpenCollection YAML tests .yml files in bruno folder in appropriate folder/sub-folder API contract testing, examples

Documentation Update Workflow:

  1. Identify the audience (end users, developers, API consumers)
  2. Choose appropriate location based on table above
  3. Update documentation before or with code changes
  4. Verify documentation renders at /docs endpoint
  5. Test search finds new/updated content
  6. For API changes: Update both docs/developer/api/ files AND Bruno OpenCollection YAML .yml files
  7. Commit separately with clear message: docs: <description>

When in doubt:

  • End-user visible → docs/user/
  • API reference → docs/developer/api/
  • Setup/onboarding → README.md
  • Development related → docs/contributing/

Process & Continuity

  • If mid-task and receive "no response", continue the task
  • Verify no regressions before modifying/removing code

🔧 TECHNICAL STANDARDS

Backend Stack

  • Language: Go 1.25+
  • Database: PostgreSQL 15+ with pgx v5 driver only
  • Authentication: JWT tokens with bcrypt password hashing
  • Architecture: Service layer pattern (handlers → services → database)

Frontend Stack

  • Styling: TailwindCSS (no custom CSS)
  • Language: TypeScript (no JavaScript)
  • Templates: HTMX with server-side rendering
  • Patterns: Procedural/imperative with functional techniques where helpful (no OOP)

Containerization

  • Runtime: Podman (not Docker)
  • Build: Existing Dockerfile and docker-compose.yml only
  • No local builds allowed

🔄 ERROR RECOVERY PROTOCOL

When code modification mistakes occur (deleted wrong code, broke compilation, etc.):

Immediate Actions

  1. STOP - Don't make more edits
  2. ASSESS - What was deleted? Is it critical?
  3. REVIEW - Run git diff to see exact changes
  4. RESTORE - Choose appropriate recovery method:
    • Recent mistake: git checkout -- filename
    • Complex restoration: Use git show HEAD:filename to recover deleted code
    • Multiple files: git reset HEAD~1 (if safe)
  5. VERIFY - Compile and test restored code
  6. DOCUMENT - Note what went wrong for future reference

Recovery Examples

# Recover a deleted function from original file
git show HEAD:internal/handlers/auth.go | sed -n '70,275p' > recovery.txt

# Revert entire file to original state
git checkout HEAD -- internal/handlers/auth.go

# Use git stash to save current state before rollback
git stash push -m "Broken state before fix"
git checkout -- internal/handlers/auth.go

Prevention (Learn From Mistakes)

  • Why did the mistake happen?
  • Was it too-broad matching?
  • Was it insufficient context reading?
  • Was it cascading fix-up attempts?
  • Update guidelines to prevent recurrence

📋 WORKFLOW CHECKLISTS

Before Making Frontend-Only Changes

  • Identify if backend modification could make implementation simpler
  • Plan to use existing API endpoints only
  • If backend change seems necessary, prepare confirmation request:
    • Required change description
    • Why it would help
    • Impact analysis
    • Alternative approaches considered
  • Plan git commit structure (multiple logical commits)
  • Identify documentation location (see Documentation section):
    • User-facing feature → docs/user/
    • UI/workflow changes → docs/user/
    • Setup instructions → README.md

Before Making Full-Stack Changes

  • Read current schema completely (if database changes)
  • Identify all columns that must be preserved
  • Plan exact changes needed
  • Verify Podman will be used for builds
  • Plan git commit structure (multiple logical commits)
  • Identify documentation location:
    • API changes → docs/developer/api/<category>/
    • New endpoints → Create new .md file in docs/developer/api/
    • API behavior → Update existing docs/developer/api/ files
    • Breaking changes → Both README.md + relevant docs/
    • Bruno OpenCollection YAML .yml files → Update/create alongside API changes

During Schema Changes (Full-Stack Only)

  • Read current schema completely
  • Identify all columns that must be preserved
  • Plan exact changes needed
  • Set up verification step
  • Make intended changes
  • Immediately verify by reading back modified sections
  • Confirm ALL expected columns are present
  • Verify schema.sql, models.go, and queries.sql are in sync
  • Update local database (choose ONE):
    • Option 1 - Recreate database (recommended, loses data):
      podman compose down -v  # Delete all volumes
      podman compose up -d    # Start with fresh schema
      
    • Option 2 - Manual SQL migration (preserves data):
      podman exec bookhoard_db psql -U postgres -d bookhoard -c "YOUR SQL HERE"
      
  • Verify database has new schema (check column types, indexes, etc.)

After API Changes

  • Create/update Bruno OpenCollection YAML requests
  • Test with no user context
  • Test with regular user context
  • Test with admin context
  • Verify backward compatibility

Before Committing

  • Run verification script: bash scripts/verify-guidelines.sh
  • Fix any errors - verification must pass (0 errors) to commit
  • Note warnings - informational only, do not auto-fix
  • Run tests: go test ./... -v
  • Run lint/typecheck if available
  • Ensure no secrets in changes
  • Verify logical commit structure
  • Update documentation (see Documentation section):
    • User-facing changes → docs/user/
    • API changes → docs/developer/api/ + Bruno OpenCollection YAML .yml files
    • Setup/onboarding → README.md
    • Development changes → docs/contributing/
  • Verify docs render at /docs endpoint
  • Test docs search finds new content

Error Recovery Protocol (If Code Mistakes Occur)

  • Stop immediately - don't make more edits
  • Assess impact: What was deleted? Is it critical?
  • Review git diff: See exact changes made
  • Restore strategy:
    • If recent mistake: git checkout -- filename
    • If complex: Reconstruct from git diff using git show HEAD:filename
  • Verify recovery: Compile and test restored code
  • Document mistake: Note what went wrong for future reference

Phase Completion Verification (Before Declaring "Complete")

  • All target code is removed/intact as intended
  • No unintended code was deleted
  • All affected files compile successfully
  • Run go build ./... for entire project
  • Run verification script: bash scripts/verify-guidelines.sh - must pass (0 errors)
  • No critical functionality was broken
  • Git diff shows only intended changes
  • Review all modified files with git diff --stat

🏗 ARCHITECTURAL PATTERNS

Current: Hybrid SSR

Browser → Go template (with data) → Display instantly
                    ↓
          JavaScript for interactivity (CRUD)
                    ↓
               Shared service layer

Ultimately, whenever you are unsure just ask for confirmation.