Various improvements
This commit is contained in:
122
README.md
122
README.md
@@ -161,43 +161,75 @@ cd backend
|
||||
|
||||
## 📖 Documentation
|
||||
|
||||
- **[API Documentation](docs/API.md)**: Complete REST API reference with examples
|
||||
- **[Data Model](docs/DATA_MODEL.md)**: Detailed database schema and relationships
|
||||
- **[Technical Specification](storycove-spec.md)**: Comprehensive technical specification
|
||||
- **[Technical Specification](storycove-spec.md)**: Complete technical specification with API documentation, data models, and all feature specifications
|
||||
- **[Web Scraper Specification](storycove-scraper-spec.md)**: URL content grabbing functionality
|
||||
- **Environment Configuration**: Multi-environment deployment setup (see above)
|
||||
- **Development Setup**: Local development environment setup (see below)
|
||||
|
||||
> **Note**: All feature specifications (Collections, Tag Enhancements, EPUB Import/Export) have been consolidated into the main technical specification for easier maintenance and reference.
|
||||
|
||||
## 🗄️ Data Model
|
||||
|
||||
StoryCove uses a PostgreSQL database with the following core entities:
|
||||
|
||||
### **Stories**
|
||||
- **Primary Key**: UUID
|
||||
- **Fields**: title, summary, description, content_html, content_plain, source_url, word_count, rating, volume, cover_path, reading_position, last_read_at
|
||||
- **Relationships**: Many-to-One with Author, Many-to-One with Series, Many-to-Many with Tags
|
||||
- **Features**: Automatic word count calculation, HTML sanitization, plain text extraction, reading progress tracking
|
||||
- **Fields**: title, summary, description, content_html, content_plain, source_url, word_count, rating, volume, cover_path, is_read, reading_position, last_read_at, created_at, updated_at
|
||||
- **Relationships**: Many-to-One with Author, Many-to-One with Series, Many-to-Many with Tags, One-to-Many with ReadingPositions
|
||||
- **Features**: Automatic word count calculation, HTML sanitization, plain text extraction, reading progress tracking, duplicate detection
|
||||
|
||||
### **Authors**
|
||||
- **Primary Key**: UUID
|
||||
- **Fields**: name, notes, author_rating, avatar_image_path
|
||||
- **Relationships**: One-to-Many with Stories, One-to-Many with Author URLs
|
||||
- **Features**: URL collection storage, rating system, statistics calculation
|
||||
- **Fields**: name, notes, author_rating, avatar_image_path, created_at, updated_at
|
||||
- **Relationships**: One-to-Many with Stories, One-to-Many with Author URLs (via @ElementCollection)
|
||||
- **Features**: URL collection storage, rating system, statistics calculation, average story rating calculation
|
||||
|
||||
### **Collections**
|
||||
- **Primary Key**: UUID
|
||||
- **Fields**: name, description, rating, cover_image_path, is_archived, created_at, updated_at
|
||||
- **Relationships**: Many-to-Many with Tags, One-to-Many with CollectionStories
|
||||
- **Features**: Story ordering with gap-based positioning, statistics calculation, EPUB export, Typesense search
|
||||
|
||||
### **CollectionStories** (Junction Table)
|
||||
- **Composite Key**: collection_id, story_id
|
||||
- **Fields**: position, added_at
|
||||
- **Relationships**: Links Collections to Stories with ordering
|
||||
- **Features**: Gap-based positioning for efficient reordering
|
||||
|
||||
### **Series**
|
||||
- **Primary Key**: UUID
|
||||
- **Fields**: name, description
|
||||
- **Fields**: name, description, created_at
|
||||
- **Relationships**: One-to-Many with Stories (ordered by volume)
|
||||
- **Features**: Volume-based story ordering, navigation methods
|
||||
- **Features**: Volume-based story ordering, navigation methods (next/previous story)
|
||||
|
||||
### **Tags**
|
||||
- **Primary Key**: UUID
|
||||
- **Fields**: name (unique)
|
||||
- **Relationships**: Many-to-Many with Stories
|
||||
- **Features**: Autocomplete support, usage statistics
|
||||
- **Fields**: name (unique), color (hex), description, created_at
|
||||
- **Relationships**: Many-to-Many with Stories, Many-to-Many with Collections, One-to-Many with TagAliases
|
||||
- **Features**: Color coding, alias system, autocomplete support, usage statistics, AI-powered suggestions
|
||||
|
||||
### **Join Tables**
|
||||
- **story_tags**: Links stories to tags
|
||||
- **author_urls**: Stores multiple URLs per author
|
||||
### **TagAliases**
|
||||
- **Primary Key**: UUID
|
||||
- **Fields**: alias_name (unique), canonical_tag_id, created_from_merge, created_at
|
||||
- **Relationships**: Many-to-One with Tag (canonical)
|
||||
- **Features**: Transparent alias resolution, merge tracking, autocomplete integration
|
||||
|
||||
### **ReadingPositions**
|
||||
- **Primary Key**: UUID
|
||||
- **Fields**: story_id, chapter_index, chapter_title, word_position, character_position, percentage_complete, epub_cfi, context_before, context_after, created_at, updated_at
|
||||
- **Relationships**: Many-to-One with Story
|
||||
- **Features**: Advanced reading position tracking, EPUB CFI support, context preservation, percentage calculation
|
||||
|
||||
### **Libraries**
|
||||
- **Primary Key**: UUID
|
||||
- **Fields**: name, description, is_default, created_at, updated_at
|
||||
- **Features**: Multi-library support, library switching functionality
|
||||
|
||||
### **Core Join Tables**
|
||||
- **story_tags**: Links stories to tags (Many-to-Many)
|
||||
- **collection_tags**: Links collections to tags (Many-to-Many)
|
||||
- **collection_stories**: Links collections to stories with ordering
|
||||
- **author_urls**: Stores multiple URLs per author (@ElementCollection)
|
||||
|
||||
## 🔌 REST API Reference
|
||||
|
||||
@@ -209,6 +241,7 @@ StoryCove uses a PostgreSQL database with the following core entities:
|
||||
### **Stories** (`/api/stories`)
|
||||
- `GET /` - List stories (paginated)
|
||||
- `GET /{id}` - Get specific story
|
||||
- `GET /{id}/read` - Get story for reading interface
|
||||
- `POST /` - Create new story
|
||||
- `PUT /{id}` - Update story
|
||||
- `DELETE /{id}` - Delete story
|
||||
@@ -218,6 +251,10 @@ StoryCove uses a PostgreSQL database with the following core entities:
|
||||
- `POST /{id}/tags/{tagId}` - Add tag to story
|
||||
- `DELETE /{id}/tags/{tagId}` - Remove tag from story
|
||||
- `POST /{id}/reading-progress` - Update reading position
|
||||
- `POST /{id}/reading-status` - Mark story as read/unread
|
||||
- `GET /{id}/collections` - Get collections containing story
|
||||
- `GET /random` - Get random story with optional filters
|
||||
- `GET /check-duplicate` - Check for duplicate stories
|
||||
- `GET /search` - Search stories (Typesense with faceting)
|
||||
- `GET /search/suggestions` - Get search suggestions
|
||||
- `GET /author/{authorId}` - Stories by author
|
||||
@@ -225,6 +262,16 @@ StoryCove uses a PostgreSQL database with the following core entities:
|
||||
- `GET /tags/{tagName}` - Stories with tag
|
||||
- `GET /recent` - Recent stories
|
||||
- `GET /top-rated` - Top-rated stories
|
||||
- `POST /batch/add-to-collection` - Add multiple stories to collection
|
||||
- `POST /reindex` - Manual Typesense reindex
|
||||
- `POST /reindex-typesense` - Reindex stories in Typesense
|
||||
- `POST /recreate-typesense-collection` - Recreate Typesense collection
|
||||
|
||||
#### **EPUB Import/Export** (`/api/stories/epub`)
|
||||
- `POST /import` - Import story from EPUB file
|
||||
- `POST /export` - Export story as EPUB with options
|
||||
- `GET /{id}/epub` - Export story as EPUB (simple)
|
||||
- `POST /validate` - Validate EPUB file structure
|
||||
|
||||
### **Authors** (`/api/authors`)
|
||||
- `GET /` - List authors (paginated)
|
||||
@@ -244,14 +291,49 @@ StoryCove uses a PostgreSQL database with the following core entities:
|
||||
### **Tags** (`/api/tags`)
|
||||
- `GET /` - List tags (paginated)
|
||||
- `GET /{id}` - Get specific tag
|
||||
- `POST /` - Create new tag
|
||||
- `PUT /{id}` - Update tag
|
||||
- `POST /` - Create new tag (with color and description)
|
||||
- `PUT /{id}` - Update tag (name, color, description)
|
||||
- `DELETE /{id}` - Delete tag
|
||||
- `GET /search` - Search tags
|
||||
- `GET /autocomplete` - Tag autocomplete
|
||||
- `GET /autocomplete` - Tag autocomplete with alias resolution
|
||||
- `GET /popular` - Most used tags
|
||||
- `GET /unused` - Unused tags
|
||||
- `GET /stats` - Tag statistics
|
||||
- `GET /collections` - Tags used by collections
|
||||
- `GET /resolve/{name}` - Resolve tag name (handles aliases)
|
||||
|
||||
#### **Tag Aliases** (`/api/tags/{tagId}/aliases`)
|
||||
- `POST /` - Add alias to tag
|
||||
- `DELETE /{aliasId}` - Remove alias from tag
|
||||
|
||||
#### **Tag Management**
|
||||
- `POST /merge` - Merge multiple tags into one
|
||||
- `POST /merge/preview` - Preview tag merge operation
|
||||
- `POST /suggest` - AI-powered tag suggestions for content
|
||||
|
||||
### **Collections** (`/api/collections`)
|
||||
- `GET /` - Search and list collections (Typesense)
|
||||
- `GET /{id}` - Get collection details
|
||||
- `POST /` - Create new collection (JSON or multipart)
|
||||
- `PUT /{id}` - Update collection metadata
|
||||
- `DELETE /{id}` - Delete collection
|
||||
- `PUT /{id}/archive` - Archive/unarchive collection
|
||||
- `POST /{id}/cover` - Upload collection cover image
|
||||
- `DELETE /{id}/cover` - Remove collection cover image
|
||||
- `GET /{id}/stats` - Get collection statistics
|
||||
|
||||
#### **Collection Story Management**
|
||||
- `POST /{id}/stories` - Add stories to collection
|
||||
- `DELETE /{id}/stories/{storyId}` - Remove story from collection
|
||||
- `PUT /{id}/stories/order` - Reorder stories in collection
|
||||
- `GET /{id}/read/{storyId}` - Get story with collection context
|
||||
|
||||
#### **Collection EPUB Export**
|
||||
- `GET /{id}/epub` - Export collection as EPUB
|
||||
- `POST /{id}/epub` - Export collection as EPUB with options
|
||||
|
||||
#### **Collection Management**
|
||||
- `POST /reindex-typesense` - Reindex collections in Typesense
|
||||
|
||||
### **Series** (`/api/series`)
|
||||
- `GET /` - List series (paginated)
|
||||
|
||||
Reference in New Issue
Block a user