Initial commit: Brachnha Insight project setup
- 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>
This commit is contained in:
430
scripts/seed-drafts-browser.js
Normal file
430
scripts/seed-drafts-browser.js
Normal file
@@ -0,0 +1,430 @@
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user