- Next.js 14+ with App Router and TypeScript - Tailwind CSS and ShadCN UI styling - Zustand state management - Dexie.js for IndexedDB (local-first data) - Auth.js v5 for authentication - BMAD framework integration Co-Authored-By: Claude <noreply@anthropic.com>
431 lines
13 KiB
JavaScript
431 lines
13 KiB
JavaScript
/**
|
|
* Browser Seed Script for Drafts
|
|
*
|
|
* This script runs in the browser console to populate the database with sample drafts.
|
|
*
|
|
* Usage:
|
|
* 1. Open your app in the browser
|
|
* 2. Open DevTools Console (F12)
|
|
* 3. Copy and paste this entire file
|
|
* 4. Press Enter
|
|
*/
|
|
|
|
(async function seedDrafts() {
|
|
// Import the database
|
|
const { db } = await import('/src/lib/db/index.ts');
|
|
const { v4: uuidv4 } = await import('uuid');
|
|
|
|
const sampleDrafts = [
|
|
// Week 5 - Current Week (3 drafts)
|
|
{
|
|
sessionId: uuidv4(),
|
|
title: 'Building a Scalable Microservices Architecture',
|
|
content: `# Building a Scalable Microservices Architecture
|
|
|
|
## Overview
|
|
In this article, we explore the key principles of designing and implementing a scalable microservices architecture that can handle millions of requests per day.
|
|
|
|
## Key Principles
|
|
1. **Service Independence**: Each microservice should be independently deployable
|
|
2. **Data Ownership**: Services own their data and expose it through APIs
|
|
3. **Resilience**: Build in circuit breakers and fallback mechanisms
|
|
4. **Observability**: Comprehensive logging and monitoring
|
|
|
|
## Implementation Strategy
|
|
- Start with a monolith and identify bounded contexts
|
|
- Extract services incrementally
|
|
- Use API gateways for routing and authentication
|
|
- Implement service mesh for inter-service communication
|
|
|
|
## Conclusion
|
|
Microservices aren't a silver bullet, but when done right, they provide the flexibility and scalability modern applications need.`,
|
|
tags: ['architecture', 'microservices', 'scalability'],
|
|
createdAt: new Date('2026-01-25T14:30:00').getTime(),
|
|
status: 'completed',
|
|
completedAt: new Date('2026-01-25T15:45:00').getTime(),
|
|
},
|
|
{
|
|
sessionId: uuidv4(),
|
|
title: 'The Future of AI in Software Development',
|
|
content: `# The Future of AI in Software Development
|
|
|
|
## Introduction
|
|
Artificial Intelligence is transforming how we write, test, and deploy code. This article examines the current state and future trends.
|
|
|
|
## Current Applications
|
|
- **Code Generation**: AI-powered IDEs and copilots
|
|
- **Bug Detection**: Automated code review and vulnerability scanning
|
|
- **Testing**: AI-generated test cases and test data
|
|
- **Documentation**: Automatic documentation generation
|
|
|
|
## Emerging Trends
|
|
1. Natural language to code conversion
|
|
2. Autonomous debugging and refactoring
|
|
3. Predictive performance optimization
|
|
4. AI-driven architecture recommendations
|
|
|
|
## Challenges
|
|
- Code quality and maintainability concerns
|
|
- Over-reliance on AI suggestions
|
|
- Security and privacy implications
|
|
- Need for human oversight and creativity
|
|
|
|
## Looking Ahead
|
|
The future isn't about replacing developers, but augmenting their capabilities with intelligent tools.`,
|
|
tags: ['ai', 'development', 'future-tech'],
|
|
createdAt: new Date('2026-01-23T10:15:00').getTime(),
|
|
status: 'completed',
|
|
completedAt: new Date('2026-01-23T11:30:00').getTime(),
|
|
},
|
|
{
|
|
sessionId: uuidv4(),
|
|
title: 'Mastering React Server Components',
|
|
content: `# Mastering React Server Components
|
|
|
|
## What Are Server Components?
|
|
React Server Components (RSC) represent a paradigm shift in how we build React applications, enabling server-side rendering with zero client-side JavaScript.
|
|
|
|
## Benefits
|
|
- **Performance**: Reduced bundle size and faster initial load
|
|
- **Data Fetching**: Direct database access without API layers
|
|
- **SEO**: Better search engine optimization
|
|
- **Security**: Sensitive logic stays on the server
|
|
|
|
## Key Concepts
|
|
\`\`\`jsx
|
|
// Server Component (default)
|
|
async function ProductList() {
|
|
const products = await db.products.findMany();
|
|
return <div>{products.map(p => <ProductCard key={p.id} {...p} />)}</div>;
|
|
}
|
|
|
|
// Client Component (opt-in)
|
|
'use client';
|
|
function InteractiveButton() {
|
|
const [count, setCount] = useState(0);
|
|
return <button onClick={() => setCount(count + 1)}>{count}</button>;
|
|
}
|
|
\`\`\`
|
|
|
|
## Best Practices
|
|
1. Use Server Components by default
|
|
2. Add 'use client' only when needed (interactivity, hooks)
|
|
3. Pass serializable props between server and client
|
|
4. Leverage streaming for better UX
|
|
|
|
## Conclusion
|
|
Server Components are the future of React development, offering better performance and developer experience.`,
|
|
tags: ['react', 'server-components', 'web-development'],
|
|
createdAt: new Date('2026-01-21T16:00:00').getTime(),
|
|
status: 'completed',
|
|
completedAt: new Date('2026-01-21T17:20:00').getTime(),
|
|
},
|
|
|
|
// Week 4 (1 draft)
|
|
{
|
|
sessionId: uuidv4(),
|
|
title: 'Database Indexing Strategies for High Performance',
|
|
content: `# Database Indexing Strategies for High Performance
|
|
|
|
## Introduction
|
|
Proper indexing is crucial for database performance. This guide covers essential indexing strategies for modern applications.
|
|
|
|
## Types of Indexes
|
|
1. **B-Tree Indexes**: Default for most databases, great for range queries
|
|
2. **Hash Indexes**: Fast equality lookups
|
|
3. **Full-Text Indexes**: Optimized for text search
|
|
4. **Partial Indexes**: Index only a subset of rows
|
|
5. **Covering Indexes**: Include all columns needed for a query
|
|
|
|
## When to Index
|
|
- Columns used in WHERE clauses
|
|
- Foreign key columns
|
|
- Columns used in JOIN operations
|
|
- Columns used in ORDER BY and GROUP BY
|
|
|
|
## When NOT to Index
|
|
- Small tables (full scan is faster)
|
|
- Columns with low cardinality
|
|
- Frequently updated columns
|
|
- Tables with heavy write operations
|
|
|
|
## Monitoring and Optimization
|
|
\`\`\`sql
|
|
-- Find unused indexes
|
|
SELECT * FROM pg_stat_user_indexes WHERE idx_scan = 0;
|
|
|
|
-- Analyze query performance
|
|
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';
|
|
\`\`\`
|
|
|
|
## Conclusion
|
|
Indexing is a balancing act between read and write performance. Monitor, measure, and optimize based on your actual workload.`,
|
|
tags: ['database', 'performance', 'indexing'],
|
|
createdAt: new Date('2026-01-18T09:45:00').getTime(),
|
|
status: 'completed',
|
|
completedAt: new Date('2026-01-18T10:30:00').getTime(),
|
|
},
|
|
|
|
// Week 3 (1 draft)
|
|
{
|
|
sessionId: uuidv4(),
|
|
title: 'Building Resilient Distributed Systems',
|
|
content: `# Building Resilient Distributed Systems
|
|
|
|
## The Challenge
|
|
Distributed systems introduce complexity: network failures, partial failures, eventual consistency, and more.
|
|
|
|
## Core Principles
|
|
|
|
### 1. Embrace Failure
|
|
- Assume everything will fail
|
|
- Design for graceful degradation
|
|
- Implement circuit breakers
|
|
|
|
### 2. Idempotency
|
|
Ensure operations can be safely retried:
|
|
\`\`\`typescript
|
|
// Bad: Not idempotent
|
|
function incrementCounter(userId: string) {
|
|
const count = getCount(userId);
|
|
setCount(userId, count + 1);
|
|
}
|
|
|
|
// Good: Idempotent
|
|
function setCounter(userId: string, value: number) {
|
|
setCount(userId, value);
|
|
}
|
|
\`\`\`
|
|
|
|
### 3. Timeouts and Retries
|
|
- Set aggressive timeouts
|
|
- Use exponential backoff
|
|
- Implement retry budgets
|
|
|
|
### 4. Observability
|
|
- Distributed tracing
|
|
- Structured logging
|
|
- Metrics and alerting
|
|
|
|
## Patterns
|
|
- **Saga Pattern**: Manage distributed transactions
|
|
- **CQRS**: Separate read and write models
|
|
- **Event Sourcing**: Store state changes as events
|
|
- **Bulkhead Pattern**: Isolate resources
|
|
|
|
## Conclusion
|
|
Building distributed systems is hard, but following these principles makes them manageable and reliable.`,
|
|
tags: ['distributed-systems', 'resilience', 'architecture'],
|
|
createdAt: new Date('2026-01-10T13:20:00').getTime(),
|
|
status: 'completed',
|
|
completedAt: new Date('2026-01-10T14:45:00').getTime(),
|
|
},
|
|
|
|
// Week 2 (1 draft)
|
|
{
|
|
sessionId: uuidv4(),
|
|
title: 'Modern CSS: From Flexbox to Container Queries',
|
|
content: `# Modern CSS: From Flexbox to Container Queries
|
|
|
|
## Evolution of CSS Layout
|
|
CSS has evolved dramatically. Let's explore modern layout techniques that make responsive design easier.
|
|
|
|
## Flexbox
|
|
Perfect for one-dimensional layouts:
|
|
\`\`\`css
|
|
.container {
|
|
display: flex;
|
|
gap: 1rem;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
\`\`\`
|
|
|
|
## Grid
|
|
Two-dimensional layouts made simple:
|
|
\`\`\`css
|
|
.grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
gap: 2rem;
|
|
}
|
|
\`\`\`
|
|
|
|
## Container Queries
|
|
The future of responsive design:
|
|
\`\`\`css
|
|
.card-container {
|
|
container-type: inline-size;
|
|
}
|
|
|
|
@container (min-width: 400px) {
|
|
.card {
|
|
display: grid;
|
|
grid-template-columns: 1fr 2fr;
|
|
}
|
|
}
|
|
\`\`\`
|
|
|
|
## Custom Properties
|
|
Dynamic theming:
|
|
\`\`\`css
|
|
:root {
|
|
--primary-color: #3b82f6;
|
|
--spacing-unit: 0.5rem;
|
|
}
|
|
|
|
.button {
|
|
background: var(--primary-color);
|
|
padding: calc(var(--spacing-unit) * 2);
|
|
}
|
|
\`\`\`
|
|
|
|
## Conclusion
|
|
Modern CSS provides powerful tools for creating responsive, maintainable designs without heavy JavaScript frameworks.`,
|
|
tags: ['css', 'web-design', 'responsive'],
|
|
createdAt: new Date('2026-01-03T11:00:00').getTime(),
|
|
status: 'completed',
|
|
completedAt: new Date('2026-01-03T12:15:00').getTime(),
|
|
},
|
|
|
|
// Week 1 (1 draft)
|
|
{
|
|
sessionId: uuidv4(),
|
|
title: 'TypeScript Best Practices for Large Codebases',
|
|
content: `# TypeScript Best Practices for Large Codebases
|
|
|
|
## Introduction
|
|
TypeScript shines in large projects. Here are battle-tested practices for maintaining type safety at scale.
|
|
|
|
## Strict Mode
|
|
Always enable strict mode:
|
|
\`\`\`json
|
|
{
|
|
"compilerOptions": {
|
|
"strict": true,
|
|
"noUncheckedIndexedAccess": true,
|
|
"noImplicitOverride": true
|
|
}
|
|
}
|
|
\`\`\`
|
|
|
|
## Type Organization
|
|
\`\`\`typescript
|
|
// ✅ Good: Centralized types
|
|
// types/user.ts
|
|
export interface User {
|
|
id: string;
|
|
email: string;
|
|
profile: UserProfile;
|
|
}
|
|
|
|
export type UserRole = 'admin' | 'user' | 'guest';
|
|
|
|
// ❌ Bad: Scattered inline types
|
|
function getUser(): { id: string; email: string } { }
|
|
\`\`\`
|
|
|
|
## Utility Types
|
|
Leverage built-in utilities:
|
|
\`\`\`typescript
|
|
type PartialUser = Partial<User>;
|
|
type ReadonlyUser = Readonly<User>;
|
|
type UserKeys = keyof User;
|
|
type UserEmail = Pick<User, 'email'>;
|
|
type UserWithoutId = Omit<User, 'id'>;
|
|
\`\`\`
|
|
|
|
## Discriminated Unions
|
|
Type-safe state management:
|
|
\`\`\`typescript
|
|
type AsyncState<T> =
|
|
| { status: 'idle' }
|
|
| { status: 'loading' }
|
|
| { status: 'success'; data: T }
|
|
| { status: 'error'; error: Error };
|
|
|
|
function handleState<T>(state: AsyncState<T>) {
|
|
switch (state.status) {
|
|
case 'success':
|
|
return state.data; // TypeScript knows data exists
|
|
case 'error':
|
|
return state.error; // TypeScript knows error exists
|
|
}
|
|
}
|
|
\`\`\`
|
|
|
|
## Avoid Type Assertions
|
|
\`\`\`typescript
|
|
// ❌ Bad
|
|
const user = data as User;
|
|
|
|
// ✅ Good: Use type guards
|
|
function isUser(data: unknown): data is User {
|
|
return typeof data === 'object' && data !== null && 'id' in data;
|
|
}
|
|
|
|
if (isUser(data)) {
|
|
console.log(data.id); // Type-safe
|
|
}
|
|
\`\`\`
|
|
|
|
## Conclusion
|
|
TypeScript's type system is powerful. Use it properly to catch bugs at compile time, not runtime.`,
|
|
tags: ['typescript', 'best-practices', 'programming'],
|
|
createdAt: new Date('2025-12-27T15:30:00').getTime(),
|
|
status: 'completed',
|
|
completedAt: new Date('2025-12-27T16:45:00').getTime(),
|
|
},
|
|
];
|
|
|
|
try {
|
|
console.log('🌱 Starting database seed...');
|
|
|
|
// Clear existing drafts (optional)
|
|
const existingCount = await db.drafts.count();
|
|
if (existingCount > 0) {
|
|
console.log(`⚠️ Found ${existingCount} existing drafts. Clearing...`);
|
|
await db.drafts.clear();
|
|
}
|
|
|
|
// Insert sample drafts
|
|
console.log(`📝 Inserting ${sampleDrafts.length} sample drafts...`);
|
|
for (const draft of sampleDrafts) {
|
|
await db.drafts.add(draft);
|
|
}
|
|
|
|
// Verify insertion
|
|
const totalDrafts = await db.drafts.count();
|
|
console.log(`✅ Successfully seeded ${totalDrafts} drafts!`);
|
|
|
|
// Show distribution by week
|
|
console.log('\n📊 Distribution by week:');
|
|
const allDrafts = await db.drafts.orderBy('createdAt').reverse().toArray();
|
|
|
|
const weekGroups = new Map();
|
|
allDrafts.forEach(draft => {
|
|
const date = new Date(draft.createdAt);
|
|
const weekStart = getWeekStart(date);
|
|
const weekKey = weekStart.toISOString().split('T')[0];
|
|
weekGroups.set(weekKey, (weekGroups.get(weekKey) || 0) + 1);
|
|
});
|
|
|
|
weekGroups.forEach((count, weekStart) => {
|
|
console.log(` Week of ${weekStart}: ${count} draft(s)`);
|
|
});
|
|
|
|
console.log('\n🎉 Seed completed successfully!');
|
|
console.log('💡 Refresh your app to see the new drafts!');
|
|
} catch (error) {
|
|
console.error('❌ Error seeding database:', error);
|
|
}
|
|
|
|
// Helper function to get the start of the week (Monday)
|
|
function getWeekStart(date) {
|
|
const d = new Date(date);
|
|
const day = d.getDay();
|
|
const diff = d.getDate() - day + (day === 0 ? -6 : 1);
|
|
return new Date(d.setDate(diff));
|
|
}
|
|
})();
|