Built a complete Netflix-style streaming interface for IndeeHub's decentralized media platform with real film content. Features: - Vue 3 + TypeScript + Vite setup with hot module reloading - Netflix-inspired UI with hero section and horizontal scrolling content rows - Glass morphism design system with custom Tailwind configuration - 20+ real IndeeHub films organized into 6 categories (Bitcoin, Documentaries, Drama, etc.) - Full-featured video player component with custom controls - Mobile-responsive design with bottom navigation - Nostr integration ready (nostr-tools, relay pool, NIP-71 support) - Pinia state management for content - MCP tools configured (Filesystem, Memory, Nostr, Puppeteer) Components: - Browse.vue: Main streaming interface with hero and content rows - ContentRow.vue: Horizontal scrolling film cards with navigation arrows - VideoPlayer.vue: Custom video player with play/pause, seek, volume, fullscreen - MobileNav.vue: Bottom tab navigation for mobile devices Tech Stack: - Frontend: Vue 3 (Composition API), TypeScript - Build: Vite 7 - Styling: Tailwind CSS with custom theme - State: Pinia 3 - Router: Vue Router 4.6 - Protocol: Nostr (nostr-tools 2.22) Design: - 4px grid spacing system - Glass morphism UI components - Netflix-style hero section with featured content - Smooth animations and hover effects - Mobile-first responsive breakpoints - Dark theme with custom color palette Content: - 20+ IndeeHub films with titles, descriptions, categories - Bitcoin documentaries: God Bless Bitcoin, Dirty Coin, Searching for Satoshi - Independent films and documentaries - Working Unsplash CDN images for thumbnails and backdrops Ready for deployment to Umbrel, Start9, and Archy nodes. Co-authored-by: Cursor <cursoragent@cursor.com>
240 lines
4.7 KiB
Plaintext
240 lines
4.7 KiB
Plaintext
---
|
|
description: Code quality principles and clean code practices
|
|
alwaysApply: true
|
|
---
|
|
|
|
# Code Quality & Clean Code Standards
|
|
|
|
## Core Principles
|
|
|
|
### 1. Readability First
|
|
|
|
Code is read far more often than it's written.
|
|
|
|
```javascript
|
|
// ❌ Bad - Unclear, cryptic
|
|
const d = new Date()
|
|
const y = d.getFullYear()
|
|
|
|
// ✅ Good - Clear, self-documenting
|
|
const today = new Date()
|
|
const year = today.getFullYear()
|
|
```
|
|
|
|
### 2. Single Responsibility Principle
|
|
|
|
Each function/component should do one thing well.
|
|
|
|
```javascript
|
|
// ✅ Good - Single responsibility
|
|
function validateEmail(email) {
|
|
return email && email.length > 0
|
|
}
|
|
|
|
function formatEmail(email) {
|
|
return email.toLowerCase().trim()
|
|
}
|
|
```
|
|
|
|
### 3. DRY (Don't Repeat Yourself)
|
|
|
|
Extract repeated logic into reusable functions.
|
|
|
|
### 4. Meaningful Names
|
|
|
|
Names should reveal intent.
|
|
|
|
```javascript
|
|
// ❌ Bad
|
|
const d = 86400000
|
|
const arr = []
|
|
|
|
// ✅ Good
|
|
const MILLISECONDS_PER_DAY = 86400000
|
|
const activeProjects = []
|
|
```
|
|
|
|
### 5. Keep It Simple (KISS)
|
|
|
|
Simplicity is the ultimate sophistication.
|
|
|
|
## Error Handling
|
|
|
|
### Always Handle Errors
|
|
|
|
```javascript
|
|
// ✅ Good - Comprehensive error handling
|
|
async function fetchProjects() {
|
|
const error = ref(null)
|
|
const isLoading = ref(true)
|
|
const data = ref(null)
|
|
|
|
try {
|
|
const response = await fetch('/api/projects')
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`)
|
|
}
|
|
|
|
data.value = await response.json()
|
|
} catch (err) {
|
|
error.value = err.message
|
|
console.error('Failed to fetch projects:', err)
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
|
|
return { data, error, isLoading }
|
|
}
|
|
```
|
|
|
|
### User-Friendly Error Messages
|
|
|
|
```javascript
|
|
function getErrorMessage(error) {
|
|
const messages = {
|
|
'ERR_CONNECTION_REFUSED': 'Unable to connect. Please check your internet.',
|
|
'ERR_TIMEOUT': 'Request timed out. Please try again.',
|
|
}
|
|
|
|
return messages[error.code] || 'An unexpected error occurred.'
|
|
}
|
|
```
|
|
|
|
## Comments & Documentation
|
|
|
|
### When to Comment
|
|
|
|
#### ✅ DO Comment:
|
|
- **Why** something is done (not what)
|
|
- Complex algorithms
|
|
- Non-obvious decisions
|
|
- Workarounds for bugs
|
|
|
|
```javascript
|
|
// ✅ Good - Explains WHY
|
|
// We use a 300ms debounce to avoid overwhelming the API
|
|
// with requests while the user is still typing
|
|
const debouncedSearch = debounce(searchProjects, 300)
|
|
```
|
|
|
|
#### ❌ DON'T Comment:
|
|
- Obvious code
|
|
- Outdated information
|
|
- Commented-out code (delete it instead)
|
|
|
|
### JSDoc for Public APIs
|
|
|
|
```javascript
|
|
/**
|
|
* Formats a date into human-readable format
|
|
*
|
|
* @param {string|Date} date - The date to format
|
|
* @param {Object} options - Formatting options
|
|
* @returns {string} Formatted date string
|
|
*
|
|
* @example
|
|
* formatDate('2026-02-02', { format: 'long' })
|
|
* // Returns: "February 2, 2026"
|
|
*/
|
|
export function formatDate(date, options = {}) {
|
|
// Implementation
|
|
}
|
|
```
|
|
|
|
## Import Order
|
|
|
|
```javascript
|
|
// 1. External libraries
|
|
import { ref, computed } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
|
|
// 2. Internal modules
|
|
import { useAuth } from '@/composables/useAuth'
|
|
import { formatDate } from '@/utils/date'
|
|
|
|
// 3. Components
|
|
import Button from '@/components/atoms/Button.vue'
|
|
|
|
// 4. Styles
|
|
import './styles.css'
|
|
```
|
|
|
|
## Code Review Checklist
|
|
|
|
### Before Submitting PR
|
|
- ✅ Code runs without errors
|
|
- ✅ Tests pass
|
|
- ✅ No console errors or warnings
|
|
- ✅ Linter passes
|
|
- ✅ Code follows conventions
|
|
- ✅ Complex logic is commented
|
|
- ✅ No commented-out code
|
|
- ✅ Mobile responsive
|
|
- ✅ Accessibility checked
|
|
|
|
### What to Look For in Review
|
|
- **Correctness**: Does it work as intended?
|
|
- **Readability**: Is it easy to understand?
|
|
- **Maintainability**: Can it be easily modified?
|
|
- **Performance**: Any obvious bottlenecks?
|
|
- **Security**: Any vulnerabilities?
|
|
- **Testing**: Adequate test coverage?
|
|
|
|
## Common Patterns
|
|
|
|
### Guard Clauses
|
|
|
|
```javascript
|
|
// ✅ Good - Early returns
|
|
function processUser(user) {
|
|
if (!user) return null
|
|
if (!user.email) return null
|
|
if (!user.isActive) return null
|
|
|
|
// Main logic here
|
|
return processedUser
|
|
}
|
|
```
|
|
|
|
### Avoid Nested Ifs
|
|
|
|
```javascript
|
|
// ❌ Bad
|
|
if (user) {
|
|
if (user.isActive) {
|
|
if (user.hasPermission) {
|
|
// Do something
|
|
}
|
|
}
|
|
}
|
|
|
|
// ✅ Good
|
|
if (!user) return
|
|
if (!user.isActive) return
|
|
if (!user.hasPermission) return
|
|
|
|
// Do something
|
|
```
|
|
|
|
## Summary Checklist
|
|
|
|
### Code
|
|
- ✅ Readable and self-documenting
|
|
- ✅ Single responsibility
|
|
- ✅ DRY (no repetition)
|
|
- ✅ Meaningful names
|
|
- ✅ Simple and clear
|
|
|
|
### Error Handling
|
|
- ✅ All errors caught
|
|
- ✅ User-friendly messages
|
|
- ✅ Logged appropriately
|
|
|
|
### Documentation
|
|
- ✅ Complex logic commented
|
|
- ✅ Public APIs documented
|
|
- ✅ No outdated comments
|
|
|
|
**Remember: Quality is not an act, it's a habit.**
|