Development guidelines for Go application syncing Audiobookshelf with Hardcover reading progress and book data
Instructions for developing and maintaining the AudiobookShelf-Hardcover sync application - a Go service that syncs reading progress and book data between AudiobookShelf and Hardcover platforms.
The codebase is organized into focused modules:
1. **Reference the schema**: Consult `hardcover-schema.graphql` for all available types, queries, and mutations
2. **Ownership handling**:
- Book ownership is stored in the `lists` table (via "Owned" list)
- The `user_books.owned` field is unreliable and always returns `false`
- Use `getOwnedBooks()` and `isBookOwnedDirect()` functions instead
3. **Rate limits**: 60 requests per minute maximum
4. **Query restrictions**:
- Disabled operators: `_like`, `_nlike`, `_ilike`, `_niregex`, `_nregex`, `_iregex`, `_regex`, `_nsimilar`, `_similar`
- Maximum query depth: 3 levels
- Query timeout: 30 seconds
5. **Token expiration**: API tokens expire after 1 year and reset on January 1st
1. **Consult the OpenAPI spec**: `audiobookshelf-openapi.json` documents all endpoints
2. **Source repository**: https://github.com/advplyr/audiobookshelf/tree/master
3. **Progress detection**: Use `/api/me` endpoint with `isFinished` flags for accurate finished book detection
4. **Re-read logic**: Always check `isBookFinished` status before treating books as re-read scenarios to prevent false positives
1. **Configuration**: Add environment variables in `config.go` with getter functions following the pattern `getSyncOwned()`
2. **Environment naming**: Use prefixes `SYNC_*`, `HARDCOVER_*`, or `AUDIOBOOKSHELF_*`
3. **API interactions**:
- Add GraphQL operations to `hardcover.go`
- Add REST calls to `audiobookshelf.go`
4. **Sync logic**: Implement core functionality in `sync.go` or create new focused modules
5. **Documentation**: Update `README.md` with configuration options and usage examples
1. **Follow Go conventions**: Consult https://go.dev/doc/effective_go
2. **Formatting**: Use `gofmt` or `goimports` to enforce standard formatting
3. **Function design**:
- Prefer named functions over long anonymous functions
- Keep functions small and composable
- Use interfaces for dependencies to enable mocking
4. **Simplicity**: Avoid unnecessary abstraction; prioritize readability
5. **Error handling**: Implement comprehensive error handling with proper logging
6. **Comments**: Add context comments to guide better suggestions
1. **Coverage requirement**: All new features must include comprehensive tests
2. **Test location**: Place `*_test.go` files in the root directory alongside source files
3. **Running tests**: `go test -v ./...`
4. **Existing test files**: `main_test.go`, `format_test.go`, `incremental_test.go`, `owned_test.go`, `owned_flag_test.go`, `want_to_read_test.go`, `reading_history_fix_test.go`
5. **Test patterns**: Use table-driven tests and subtests for thorough coverage
6. **Test types**: Include unit tests, integration tests, and configuration validation
```bash
make build # Build binary with version info
make run # Build and run locally
make test # Run all tests
make lint # Run linting tools
make docker-build # Build Docker image
make docker-run # Run in Docker container
```
1. **Update version**: Modify version string in `main.go`
2. **Update changelog**: Add release notes to `CHANGELOG.md`
3. **Commit changes**: `git commit -m "Release vX.Y.Z"`
4. **Create and push tag**:
```bash
git tag vX.Y.Z
git push origin vX.Y.Z
```
5. **Create GitHub release**: Use `gh` tool to create release with detailed notes
6. **Versioning**: Follow semantic versioning (vMAJOR.MINOR.PATCH)
7. **CI/CD**: Pipeline automatically builds and publishes releases from tags and beta versions from main branch
1. **Review generated code**: Always review Copilot suggestions before committing
2. **Refactor for clarity**: Ensure generated code is readable and testable
3. **Regenerate if needed**: If suggestions are unidiomatic or overly complex, regenerate with better context
4. **Document thoroughly**: Keep README.md, CHANGELOG.md, and inline comments up to date
5. **Use defaults wisely**: Provide sensible defaults for environment variables
6. **Follow existing patterns**: Maintain consistency with established code patterns for API interactions and data mapping
When adding new configuration options:
```go
// In config.go
func getSyncFeature() bool {
return os.Getenv("SYNC_FEATURE") == "true"
}
```
Environment variables should have sensible defaults and be documented in README.md with:
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/audiobookshelf-hardcover-sync-development/raw