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
20 KiB
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 checkouton 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 fromcmd/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=1for test pools (viapgxpool.ParseConfig()) to prevent connection exhaustion - ❌ NEVER create separate
pgxpoolper 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 - theTestServerSetuppattern automatically handles cleanup viat.Cleanup()
Frontend & Styling
- ❌ NEVER modify backend/API for frontend features without user confirmation
- ❌ NEVER use custom CSS - TailwindCSS classes only
- ⚠️ EXCEPTION:
templates/error.templmay have inline CSS because error pages must work when main app fails (404, server errors, CSS fails to load)
- ⚠️ EXCEPTION:
- ❌ NEVER use JavaScript - convert all to TypeScript
- ⚠️ EXCEPTION: Inline JS function calls in HTML attributes (e.g.,
onclick="myFunction()") are acceptable for simple interactions
- ⚠️ EXCEPTION: Inline JS function calls in HTML attributes (e.g.,
- ❌ 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
- After compilation error: STOP, review
- ❌ 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 pushand wait for completion - Never use
&&to chain git commands together
- Run
- ✅ 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:
- STOP - Don't make more edits
- ANALYZE - Use
git diffto understand what was changed - RECOVER - Restore what was accidentally deleted/broken
- 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:
- Identify the required change
- Explain why you need it
- Provide impact analysis
- 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.sqlis 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
- When
- ✅ 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 buildfor affected packages immediately after each edit - Review
git diff filenameto verify only intended changes - Validate functionality still works as expected
- Never proceed to next file until current edit is verified
- Run
- ✅ 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
- Create a stash:
- ✅ 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:
- Identify the audience (end users, developers, API consumers)
- Choose appropriate location based on table above
- Update documentation before or with code changes
- Verify documentation renders at
/docsendpoint - Test search finds new/updated content
- For API changes: Update both
docs/developer/api/files AND Bruno OpenCollection YAML.ymlfiles - 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
- STOP - Don't make more edits
- ASSESS - What was deleted? Is it critical?
- REVIEW - Run
git diffto see exact changes - RESTORE - Choose appropriate recovery method:
- Recent mistake:
git checkout -- filename - Complex restoration: Use
git show HEAD:filenameto recover deleted code - Multiple files:
git reset HEAD~1(if safe)
- Recent mistake:
- VERIFY - Compile and test restored code
- 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
- User-facing feature →
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
.mdfile indocs/developer/api/ - API behavior → Update existing
docs/developer/api/files - Breaking changes → Both
README.md+ relevantdocs/ - Bruno OpenCollection YAML
.ymlfiles → Update/create alongside API changes
- 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"
- Option 1 - Recreate database (recommended, loses data):
- 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.ymlfiles - Setup/onboarding →
README.md - Development changes →
docs/contributing/
- User-facing changes →
- Verify docs render at
/docsendpoint - 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
- If recent mistake:
- 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.