generated from nhcarrigan/template
238 lines
6.8 KiB
Markdown
238 lines
6.8 KiB
Markdown
# Library App Planning Document 📚🎮🎵
|
|
|
|
## Overview
|
|
A personal library tracking website where Naomi can catalogue and display her games, music, and books across different status categories.
|
|
|
|
## Core Features
|
|
|
|
### 1. Multi-Media Library Support
|
|
- **Games**: Currently Playing, Completed, Backlog
|
|
- **Music**: Currently Listening, Completed Albums, Want to Listen
|
|
- **Books**: Currently Reading, Finished, To Read
|
|
|
|
### 2. Authentication & Permissions
|
|
- Public viewing for everyone (read-only)
|
|
- Admin authentication for Naomi only (full CRUD operations)
|
|
- OAuth integration (GitHub? Discord? Both?)
|
|
|
|
### 3. User Interface
|
|
- Clean, responsive design
|
|
- Easy navigation between media types
|
|
- Search and filter functionality
|
|
- Statistics/summary view
|
|
|
|
## Technical Stack Considerations
|
|
|
|
### Frontend
|
|
- **Framework**: Angular
|
|
- Excellent TypeScript support (built with TS in mind!)
|
|
- Powerful CLI and tooling
|
|
- Great for building robust SPAs
|
|
- Built-in RxJS for reactive programming
|
|
- Standalone components in newer versions
|
|
|
|
### Backend
|
|
- **Framework**: Fastify
|
|
- Extremely fast Node.js framework
|
|
- First-class TypeScript support
|
|
- Built-in schema validation
|
|
- Great plugin ecosystem
|
|
- Excellent error handling
|
|
|
|
### Database
|
|
- **Database**: MongoDB (Atlas - existing instance)
|
|
- Perfect for flexible schema (games, books, music have different fields)
|
|
- Easy to add new fields without migrations
|
|
- Great performance for document queries
|
|
- **ORM**: Prisma
|
|
- Excellent TypeScript support
|
|
- Type-safe database queries
|
|
- Great MongoDB support
|
|
- Auto-generated types from schema
|
|
|
|
### Authentication
|
|
- **OAuth Provider**: Discord only
|
|
- Single OAuth provider for simplicity
|
|
- You already have Discord OAuth experience with Hikari bot
|
|
- JWT for session management
|
|
|
|
### Project Structure
|
|
- **Monorepo Tool**: Nx
|
|
- Excellent TypeScript support
|
|
- Great caching and build optimization
|
|
- Powerful generators
|
|
- Shared dependencies
|
|
- Integrated testing and linting
|
|
- **Linting**: @nhcarrigan/eslint-config
|
|
- Your custom ESLint configuration
|
|
- ESLint 9 flat config
|
|
- No Prettier needed!
|
|
|
|
### Hosting
|
|
- **Options**:
|
|
- Self-hosted on your infrastructure (full control!)
|
|
- Netlify (Good alternative, better ethics)
|
|
- Railway (Developer-friendly, good values)
|
|
- Fly.io (Great for full-stack apps)
|
|
- DigitalOcean App Platform
|
|
|
|
## Data Models (Initial Thoughts)
|
|
|
|
### MongoDB Collections Structure
|
|
We'll have three main collections: `games`, `books`, and `music`, each with their specific schema.
|
|
|
|
### Game
|
|
```typescript
|
|
interface Game {
|
|
id: string;
|
|
title: string;
|
|
platform?: string;
|
|
status: 'playing' | 'completed' | 'backlog';
|
|
dateAdded: Date;
|
|
dateCompleted?: Date;
|
|
rating?: number;
|
|
notes?: string;
|
|
coverImage?: string;
|
|
}
|
|
```
|
|
|
|
### Book
|
|
```typescript
|
|
interface Book {
|
|
id: string;
|
|
title: string;
|
|
author: string;
|
|
isbn?: string;
|
|
status: 'reading' | 'finished' | 'toRead';
|
|
dateAdded: Date;
|
|
dateFinished?: Date;
|
|
rating?: number;
|
|
notes?: string;
|
|
coverImage?: string;
|
|
}
|
|
```
|
|
|
|
### Music
|
|
```typescript
|
|
interface Music {
|
|
id: string;
|
|
title: string;
|
|
artist: string;
|
|
type: 'album' | 'single' | 'ep';
|
|
status: 'listening' | 'completed' | 'wantToListen';
|
|
dateAdded: Date;
|
|
dateCompleted?: Date;
|
|
rating?: number;
|
|
notes?: string;
|
|
coverArt?: string;
|
|
}
|
|
```
|
|
|
|
## Feature Roadmap
|
|
|
|
### Phase 1: MVP
|
|
- [ ] Basic CRUD for all three media types
|
|
- [ ] Simple authentication (single admin user)
|
|
- [ ] Public read-only view
|
|
- [ ] Basic responsive UI
|
|
|
|
### Phase 2: Enhancements
|
|
- [ ] Search and filtering
|
|
- [ ] Statistics dashboard
|
|
- [ ] Cover image fetching from APIs
|
|
- [ ] Import/export functionality
|
|
|
|
### Phase 3: Advanced Features
|
|
- [ ] Recommendations system
|
|
- [ ] Progress tracking (% complete for books/games)
|
|
- [ ] Tags/categories
|
|
- [ ] Public API for integrations
|
|
|
|
## Questions to Consider
|
|
|
|
1. **Design Aesthetic**: What vibe are you going for? Minimalist? Colourful? Dark theme?
|
|
|
|
2. **API Integrations**: Should we fetch metadata from external APIs?
|
|
- Games: IGDB, Steam API
|
|
- Books: Open Library, Google Books
|
|
- Music: Spotify, Last.fm, MusicBrainz
|
|
|
|
3. **URL Structure**: How should we organize routes?
|
|
- `/games`, `/books`, `/music`?
|
|
- `/library/games`, `/library/books`?
|
|
- Something else?
|
|
|
|
4. **Data Entry**: Manual entry only, or barcode scanning/search integration?
|
|
|
|
5. **Privacy**: Any items you'd want to keep private even from public view?
|
|
|
|
## Current Sprint: Edit, Filters & Comments
|
|
|
|
### Feature 1: Edit Existing Library Entries (Admin Only)
|
|
**Backend:**
|
|
- Add PUT `/api/games/:id`, `/api/books/:id`, `/api/music/:id` endpoints
|
|
- Reuse existing admin authentication middleware
|
|
- Validate input against existing schemas
|
|
|
|
**Frontend:**
|
|
- Add edit button to entry cards (visible for admins)
|
|
- Reuse existing "Add" modal/form components with pre-filled data
|
|
- Update state after successful edit
|
|
|
|
### Feature 2: Fix Filter Tab State Updates
|
|
**Investigation needed:**
|
|
- Check how tab counts are calculated (likely not re-fetching after add)
|
|
- Ensure Angular state updates reactively when items are added/modified
|
|
- May need to refresh counts after mutations or use observables properly
|
|
|
|
### Feature 3: Comments System
|
|
**Database Schema:**
|
|
```prisma
|
|
model Comment {
|
|
id String @id @default(auto()) @map("_id") @db.ObjectId
|
|
content String // Markdown content - sanitised on render
|
|
userId String @db.ObjectId
|
|
user User @relation(fields: [userId], references: [id])
|
|
// Polymorphic relation - one of these will be set
|
|
gameId String? @db.ObjectId
|
|
game Game? @relation(fields: [gameId], references: [id])
|
|
bookId String? @db.ObjectId
|
|
book Book? @relation(fields: [bookId], references: [id])
|
|
musicId String? @db.ObjectId
|
|
music Music? @relation(fields: [musicId], references: [id])
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
```
|
|
|
|
**Backend:**
|
|
- POST `/api/games/:id/comments` (authenticated users)
|
|
- GET `/api/games/:id/comments` (public)
|
|
- DELETE `/api/games/:id/comments/:commentId` (admin only)
|
|
- Same for books and music
|
|
- Use a markdown sanitisation library (e.g., `sanitize-html` or `DOMPurify` on render)
|
|
|
|
**Frontend:**
|
|
- Expandable comments section on each entry card
|
|
- Markdown rendering with sanitisation (use `marked` + `DOMPurify`)
|
|
- Add comment form for authenticated users
|
|
- Delete button for admins
|
|
- Show commenter's Discord username/avatar
|
|
|
|
### Implementation Order
|
|
1. Fix filter tab bug (quick win)
|
|
2. Add edit functionality (builds on existing patterns)
|
|
3. Add comments system (new feature, more complex)
|
|
|
|
## Next Steps
|
|
|
|
1. Choose technical stack
|
|
2. Set up project structure
|
|
3. Design database schema
|
|
4. Create authentication flow
|
|
5. Build first media type (games?) as proof of concept
|
|
6. Iterate and add remaining media types
|
|
|
|
---
|
|
|
|
*✨ This planning document was created with love by Hikari and Naomi! 🌸* |