Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
251 changes: 0 additions & 251 deletions .claude/PROGRESS.md

This file was deleted.

8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,14 @@ We welcome contributions! Whether it's fixing a bug, improving the UI, or adding

---

## 📚 Documentation

Comprehensive documentation is available in the [`/docs`](./docs) directory:
- **[Testing Guide](./docs/TestingGuide.md)** - Complete guide to unit and E2E testing
- **[Testing Plan](./docs/TestingPlan.md)** - Playwright E2E testing implementation strategy
- **[Coverage Plan](./docs/CoveragePlan.md)** - Detailed unit test coverage plan
- **[CLAUDE.md](./CLAUDE.md)** - Project context for AI assistants

## 📄 License

This project is currently unlicensed (Private).
Expand Down
File renamed without changes.
74 changes: 74 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# SonoLens Documentation

This directory contains comprehensive documentation for the SonoLens project.

## 📚 Documentation Index

### Testing Documentation
- **[TestingGuide.md](./TestingGuide.md)** - Complete guide to the testing infrastructure, including Vitest unit tests and Playwright E2E tests
- **[TestingPlan.md](./TestingPlan.md)** - Playwright E2E testing implementation plan and strategy
- **[CoveragePlan.md](./CoveragePlan.md)** - Comprehensive Vitest unit test coverage plan across all modules

## 🏗️ Project Structure

```
SonoLens/
├── src/
│ ├── routes/ # SvelteKit file-based routing
│ │ ├── api/ # Backend API endpoints
│ │ ├── create/ # Main playlist creation flow
│ │ ├── dashboard/ # User dashboard
│ │ └── auth/ # Spotify OAuth handlers
│ └── lib/
│ ├── components/ # Reusable Svelte components
│ ├── server/ # Server-only code (AI integration)
│ ├── utils/ # Client utilities (image, mood mapping)
│ └── types/ # TypeScript type definitions
└── tests/
├── unit/ # Vitest unit tests
│ ├── api/ # API endpoint tests
│ ├── lib/ # Library function tests
│ └── helpers/ # Test utilities and fixtures
└── e2e/ # Playwright E2E tests
└── fixtures/ # E2E test helpers and mock data
```

## 🧪 Testing Quick Reference

### Run Unit Tests
```bash
npm test # Run all unit tests
npm run test:watch # Watch mode for development
```

### Run E2E Tests
```bash
npm run test:e2e # Run all E2E tests
npm run test:e2e:ui # Run with Playwright UI
npm run test:e2e:headed # Run with browser visible
```

### Code Quality
```bash
npm run check # Type checking
npm run lint # ESLint + Prettier check
npm run format # Auto-format code
```

## 🔗 Related Documentation

- **[Root README.md](../README.md)** - Main project documentation with setup instructions
- **[CLAUDE.md](../CLAUDE.md)** - Project context and guidelines for AI assistants

## 📊 Test Coverage Status

**Current Coverage:**
- ✅ **203 unit tests** passing across all modules
- ✅ **17 E2E tests** covering critical user flows
- ✅ **High coverage** on utilities, API endpoints, and Spotify client

**Coverage by Area:**
- Utilities (image, mood-to-spotify): 95%+
- Spotify client functions: 90%+
- API endpoints: 80%+
- Server-side AI logic: Fully tested
File renamed without changes.
File renamed without changes.
15 changes: 10 additions & 5 deletions src/lib/components/PlaylistDisplay.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@
if (event.dataTransfer) {
event.dataTransfer.effectAllowed = 'move';
event.dataTransfer.setData('text/plain', index.toString());
// Create a custom drag image from the entire track row
const target = event.target as HTMLElement;
const trackRow = target.closest('[role="listitem"]') as HTMLElement;
if (trackRow) {
event.dataTransfer.setDragImage(trackRow, 0, 0);
}
}
}

Expand Down Expand Up @@ -195,12 +201,9 @@

<div
role="listitem"
draggable={isEditable && !!onReorderTracks}
ondragstart={(e) => handleDragStart(e, index)}
ondragover={(e) => handleDragOver(e, index)}
ondragleave={handleDragLeave}
ondrop={(e) => handleDrop(e, index)}
ondragend={handleDragEnd}
ondblclick={() => handlePlayTrack(index)}
ontouchstart={(e) => handleTouchStart(e, index)}
ontouchmove={handleTouchMove}
Expand All @@ -215,12 +218,14 @@
class:bg-blue-50={dragOverIndex === index && draggedIndex !== index}
class:border-blue-500={dragOverIndex === index && draggedIndex !== index}
class:border-dashed={dragOverIndex === index && draggedIndex !== index}
class:cursor-move={isEditable && !!onReorderTracks}
>
<!-- Drag Handle (only show if reordering is enabled) -->
{#if isEditable && onReorderTracks}
<div
class="hidden sm:block flex-shrink-0 cursor-move text-gray-400 hover:text-gray-600"
draggable="true"
ondragstart={(e) => handleDragStart(e, index)}
ondragend={handleDragEnd}
class="hidden sm:block flex-shrink-0 cursor-grab active:cursor-grabbing text-gray-400 hover:text-gray-600"
title="Drag to reorder"
>
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
Expand Down
Loading
Loading