Josh Bruce Online

Authors: Collaborative Storytelling Platform Documentation

Overview

The Authors platform is a sophisticated real-time collaborative storytelling application where multiple users contribute words to create shared narratives. Built with Firebase for real-time synchronization and featuring time-based rounds, golden opportunities, and user streak tracking.

Architecture

File Structure

authors/
├── index.html                 # Main application file
├── firestore.rules           # Production Firestore security rules
├── firestore-dev.rules       # Development Firestore security rules
└── authors-docs.md           # This documentation

Technology Stack

Core Concepts

Time-Based Rounds

The application operates on precise time slots:

Golden Rounds

Special rounds with enhanced word limits:

Story Display Modes

  1. Normal Mode (before 11:30 PM):
    • Shows last 15 words with “…” continuation
    • Active input and timer
    • Real-time collaboration
  2. Full Story Mode (after 11:30 PM):
    • Displays complete day’s story
    • Read-only mode with disabled input
    • Full-screen scrollable text view

Technical Implementation

Firebase Integration

Configuration

const firebaseConfig = {
    apiKey: "AIzaSyDj2rrUF-sL0rptPcGeBpTV336SHKvabwo",
    authDomain: "authors-fd830.firebaseapp.com",
    projectId: "authors-fd830",
    storageBucket: "authors-fd830.firebasestorage.app",
    messagingSenderId: "1020775470059",
    appId: "1:1020775470059:web:46cdd53ca979167dfc3fae"
};

Database Structure

rounds/
├── {roundIndex}/
│   ├── round: number
│   ├── words: string[]
│   ├── author: string
│   ├── createdAt: timestamp
│   └── golden: boolean

users/
├── {userUID}/
│   ├── displayName: string
│   ├── lastRound: number
│   ├── streak: number
│   └── hotQuillAwardedAt?: timestamp

meta/
└── timeSync/
    └── ts: timestamp

Real-time Synchronization

Server Time Sync

async function syncServerTime() {
    const syncDoc = doc(db, 'meta', 'timeSync');
    await setDoc(syncDoc, { ts: serverTimestamp() });
    const snapshot = await getDoc(syncDoc);
    const serverTime = snapshot.data().ts.toMillis();
    const networkDelay = (Date.now() - clientTimeBefore) / 2;
    serverTimeOffset = serverTime - (clientTimeBefore + networkDelay);
}

Atomic Transactions

Word submissions use Firestore transactions to prevent race conditions:

await runTransaction(db, async (transaction) => {
    const roundDoc = doc(db, 'rounds', String(roundIndex));
    const roundSnapshot = await transaction.get(roundDoc);
    
    if (roundSnapshot.exists()) {
        throw new Error('Slot taken - try next round');
    }
    
    transaction.set(roundDoc, {
        round: roundIndex,
        words: validatedWords,
        author: username,
        createdAt: serverTimestamp(),
        golden: golden
    });
});

User Interface

Responsive Typography System

Advanced fluid typography using CSS custom properties:

:root {
    --bp-sm: 640; --bp-md: 768; --bp-lg: 1024; --bp-xl: 1366;
    --font-sm: 6; --font-md: 4.5; --font-lg: 3.5; --font-xl: 2.8;
}

@media (min-width: 640px) {
    :root {
        --font-size-1: calc(
            calc(var(--min-f-d) * 1px) + 
            var(--f-range-d) * ((100vw - calc(var(--breakpoint) * 1px)) / var(--b-range-d))
        );
    }
}

Organic Background Animation

Consistent with homepage design:

Interactive Elements

  1. Timer Display: Shows countdown to next round
  2. Typing Interface: Hidden input with visual cursor
  3. Story Display: Masked text with gradient fade-out
  4. System Messages: Toast notifications for user feedback

Input Validation

Word Validation Pipeline

function validateWords(input, maxWords) {
    if (!input || !input.trim()) {
        throw new Error('Please enter some words');
    }
    
    const cleaned = input.trim().replace(/\s+/g, ' ');
    const words = cleaned.split(' ').filter(w => w.length > 0);
    
    if (words.length > maxWords) {
        throw new Error(`Too many words! Maximum ${maxWords} allowed`);
    }
    
    for (const word of words) {
        if (word.length > MAX_WORD_LENGTH) {
            throw new Error(`Word "${word}" is too long`);
        }
    }
    
    return words;
}

Security Measures

User Experience Features

Streak System

Midnight Reset

Automatic daily story reset:

async function checkMidnightReset() {
    const now = new Date();
    const currentHour = now.getHours();
    const currentMinute = now.getMinutes();
    
    if (currentHour === 0 && currentMinute <= 5 && lastResetDate !== today) {
        // Clear database and reset state
        const roundsQuery = query(collection(db, 'rounds'));
        const snapshot = await getDocs(roundsQuery);
        
        const batch = writeBatch(db);
        snapshot.docs.forEach((doc) => {
            batch.delete(doc.ref);
        });
        await batch.commit();
    }
}

Connection Status

Real-time connection monitoring:

Development Features

Debug Panel

Developer tools accessible via ?dev=1 URL parameter:

Local Development

Automatic test user creation:

if (window.location.hostname === 'localhost') {
    if (!localStorage.getItem('authors_username')) {
        localStorage.setItem('authors_username', 'TestUser_' + Math.floor(Math.random() * 1000));
    }
}

Security Considerations

Firestore Rules

Production rules enforce data integrity:

// Only authenticated users can write
allow write: if request.auth != null;

// Validate round data structure
allow create: if resource.data.keys().hasAll(['round', 'words', 'author', 'createdAt', 'golden'])
    && resource.data.words is list
    && resource.data.words.size() <= 7;

Input Sanitization

Privacy Protection

Performance Optimizations

Efficient Data Loading

Client-Side Optimizations

Network Efficiency

Browser Compatibility

Modern Features Used

Progressive Enhancement

Accessibility Features

Keyboard Navigation

Screen Reader Support

Mobile Accessibility

Monitoring and Analytics

Error Handling

// Firebase listener error handling
}, (error) => {
    console.error('Rounds listener error:', error);
    updateConnectionStatus(false);
});

Performance Monitoring

Future Enhancement Opportunities

Feature Additions

  1. Story Themes: Daily or weekly themes
  2. User Profiles: Optional enhanced profiles
  3. Story Export: PDF/ePub generation
  4. Moderation Tools: Community moderation
  5. Mobile App: Native iOS/Android apps

Technical Improvements

  1. Service Worker: Offline functionality
  2. WebRTC: Peer-to-peer communication
  3. Machine Learning: Content suggestions
  4. Advanced Analytics: User behavior insights
  5. Multi-language: Internationalization support

Scalability Considerations

  1. Database Sharding: Regional story instances
  2. CDN Integration: Global content delivery
  3. Load Balancing: Multiple Firebase projects
  4. Caching Strategy: Redis for hot data
  5. Microservices: Modular backend architecture

Code Quality Assessment

Strengths

Areas for Improvement

Overall Rating: 9.0/10

The Authors platform demonstrates exceptional technical sophistication with real-time collaboration, robust data handling, and thoughtful user experience design. Minor improvements in code organization and testing would elevate it to production-enterprise standards.