/** * Seed script con 50 ejemplos para probar búsquedas * Usage: npx tsx prisma/seed-examples.ts */ import { PrismaClient } from '@prisma/client' const prisma = new PrismaClient() const examples = [ // Commands { type: 'command', title: 'Git commit with message', content: '## Comando\n\ngit commit -m "fix: resolve bug"\n\n## Qué hace\n\nCreates a commit with a message\n\n## Ejemplo\n\n```bash\ngit commit -m "feat: add new feature"\n```', tags: ['git', 'version-control'] }, { type: 'command', title: 'Docker remove all containers', content: '## Comando\n\ndocker rm -f $(docker ps -aq)\n\n## Qué hace\n\nForce removes all containers\n\n## Ejemplo\n\n```bash\ndocker rm -f $(docker ps -aq)\n```', tags: ['docker', 'devops'] }, { type: 'command', title: 'Find files modified today', content: '## Comando\n\nfind . -type f -mtime 0\n\n## Qué hace\n\nFinds files modified in the last 24 hours\n\n## Ejemplo\n\n```bash\nfind . -type f -mtime -1\n```', tags: ['bash', 'shell'] }, { type: 'command', title: 'Kill process on port', content: '## Comando\n\nlsof -ti: | xargs kill -9\n\n## Qué hace\n\nKills process running on specified port\n\n## Ejemplo\n\n```bash\nlsof -ti:3000 | xargs kill -9\n```', tags: ['bash', 'network'] }, { type: 'command', title: 'Git undo last commit', content: '## Comando\n\ngit reset --soft HEAD~1\n\n## Qué hace\n\nUndoes the last commit keeping changes staged\n\n## Ejemplo\n\n```bash\ngit reset --soft HEAD~1\n```', tags: ['git'] }, { type: 'command', title: 'NPM install specific version', content: '## Comando\n\nnpm install @\n\n## Qué hace\n\nInstalls a specific version of a package\n\n## Ejemplo\n\n```bash\nnpm install lodash@4.17.21\n```', tags: ['npm', 'node'] }, { type: 'command', title: 'Rsync with ssh', content: '## Comando\n\nrsync -avz -e ssh source/ user@host:dest/\n\n## Qué hace\n\nSyncs files via SSH\n\n## Ejemplo\n\n```bash\nrsync -avz -e ssh ./data/ user@server:/backup/\n```', tags: ['bash', 'network'] }, // Snippets { type: 'snippet', title: 'React useState hook', content: '## Snippet\n\n## Lenguaje\n\ntypescript\n\n## Código\n\n```typescript\nconst [state, setState] = useState(initialValue)\n```\n\n## Descripción\n\nBasic React state hook usage', tags: ['react', 'hooks'] }, { type: 'snippet', title: 'Python list comprehension', content: '## Snippet\n\n## Lenguaje\n\npython\n\n## Código\n\n```python\nsquares = [x**2 for x in range(10)]\n```\n\n## Descripción\n\nCreate list of squares using comprehension', tags: ['python'] }, { type: 'snippet', title: 'CSS flexbox centering', content: '## Snippet\n\n## Lenguaje\n\ncss\n\n## Código\n\n```css\ndisplay: flex;\njustify-content: center;\nalign-items: center;\n```\n\n## Descripción\n\nCenter element horizontally and vertically', tags: ['css', 'flexbox'] }, { type: 'snippet', title: 'JavaScript async await', content: '## Snippet\n\n## Lenguaje\n\njavascript\n\n## Código\n\n```javascript\nconst result = await fetchData()\nconsole.log(result)\n```\n\n## Descripción\n\nAsync/await pattern for Promises', tags: ['javascript', 'async'] }, { type: 'snippet', title: 'SQL SELECT with JOIN', content: '## Snippet\n\n## Lenguaje\n\nsql\n\n## Código\n\n```sql\nSELECT n.*, t.name as tag\nFROM notes n\nJOIN note_tags nt ON n.id = nt.note_id\nJOIN tags t ON nt.tag_id = t.id\n```\n\n## Descripción\n\nJoin notes with tags', tags: ['sql', 'database'] }, { type: 'snippet', title: 'Go error handling', content: '## Snippet\n\n## Lenguaje\n\ngo\n\n## Código\n\n```go\nif err != nil {\n return fmt.Errorf("failed: %w", err)\n}\n```\n\n## Descripción\n\nStandard Go error handling with wrapping', tags: ['go'] }, { type: 'snippet', title: 'Bash function', content: '## Snippet\n\n## Lenguaje\n\nbash\n\n## Código\n\n```bash\nfunction greet() {\n echo "Hello, $1!"\n}\n```\n\n## Descripción\n\nBasic bash function with parameter', tags: ['bash', 'shell'] }, // Decisions { type: 'decision', title: 'Use PostgreSQL over MySQL', content: '## Contexto\n\nNeed a relational database for the backend API\n\n## Decisión\n\nChose PostgreSQL for its advanced features\n\n## Alternativas consideradas\n\nMySQL - simpler but less features\nSQLite - embedded, not for production\n\n## Consecuencias\n\nBetter data integrity, JSON support, Full-text search built-in', tags: ['database', 'backend', 'postgresql'] }, { type: 'decision', title: 'Use Next.js App Router', content: '## Contexto\n\nStarting a new full-stack project\n\n## Decisión\n\nNext.js with App Router for server components\n\n## Alternativas consideradas\n\nExpress - more control but manual setup\nRemix - good but smaller ecosystem\n\n## Consecuencias\n\nBetter SEO, easier deployment, React Server Components', tags: ['frontend', 'react', 'architecture'] }, { type: 'decision', title: 'Use TypeScript strict mode', content: '## Contexto\n\nSetting up a new TypeScript project\n\n## Decisión\n\nEnable strict mode from the start\n\n## Alternativas consideradas\n\nDisable strict initially - leads to tech debt\n\n## Consecuencias\n\nCatches errors early, better code quality', tags: ['typescript', 'code-quality'] }, { type: 'decision', title: 'Use Tailwind CSS', content: '## Contexto\n\nNeed a styling solution for React project\n\n## Decisión\n\nTailwind CSS for rapid development\n\n## Alternativas consideradas\n\nStyled Components - runtime overhead\nCSS Modules - more setup\n\n## Consecuencias\n\nFaster development, consistent design, smaller bundle', tags: ['css', 'frontend'] }, // Recipes { type: 'recipe', title: 'Pasta carbonara', content: '## Ingredientes\n\n- 400g spaghetti\n- 200g guanciale\n- 4 egg yolks\n- 100g pecorino romano\n- Black pepper\n\n## Pasos\n\n1. Cook pasta in salted water\n2. Cut guanciale into cubes\n3. Fry guanciale until crispy\n4. Mix egg yolks with cheese\n5. Combine hot pasta with guanciale\n6. Add egg mixture off heat\n7. Toss until creamy\n\n## Tiempo\n\n20 minutes', tags: ['cocina', 'italiana', 'pasta'] }, { type: 'recipe', title: 'Guacamole', content: '## Ingredientes\n\n- 3 avocados\n- 1 lime\n- 1 onion\n- 2 tomatoes\n- Cilantro\n- Salt\n\n## Pasos\n\n1. Cut avocados and mash\n2. Dice onion and tomatoes finely\n3. Add lime juice\n4. Chop cilantro\n5. Mix all ingredients\n6. Season to taste\n\n## Tiempo\n\n10 minutes', tags: ['cocina', 'mexicana'] }, { type: 'recipe', title: 'Chicken stir fry', content: '## Ingredientes\n\n- 500g chicken breast\n- 2 bell peppers\n- 1 broccoli\n- Soy sauce\n- Ginger\n- Garlic\n\n## Pasos\n\n1. Cut chicken into strips\n2. Chop vegetables\n3. Stir fry chicken until cooked\n4. Add vegetables\n5. Add soy sauce and spices\n6. Serve with rice\n\n## Tiempo\n\n25 minutes', tags: ['cocina', 'asiatica'] }, // Procedures { type: 'procedure', title: 'Deploy to Vercel', content: '## Objetivo\n\nDeploy Next.js app to Vercel production\n\n## Pasos\n\n1. Push changes to main branch\n2. Wait for CI to pass\n3. Go to Vercel dashboard\n4. Click Deployments\n5. Select latest deployment\n6. Click Promote to Production\n7. Verify with production URL\n\n## Requisitos\n\n- Vercel account connected\n- GitHub repository linked\n- Production branch protected', tags: ['devops', 'deployment', 'vercel'] }, { type: 'procedure', title: 'Setup Git hooks', content: '## Objetivo\n\nConfigure pre-commit hooks with husky\n\n## Pasos\n\n1. Install husky: npm install husky\n2. Init: npx husky install\n3. Add pre-commit: npx husky add .husky/pre-commit "npx lint-staged"\n4. Configure lint-staged in package.json\n5. Test by committing\n\n## Requisitos\n\n- Git repository initialized\n- Package.json configured', tags: ['git', 'devops'] }, { type: 'procedure', title: 'Database backup', content: '## Objetivo\n\nCreate a backup of the production database\n\n## Pasos\n\n1. Connect to production server\n2. Run pg_dump command\n3. Save to timestamped file\n4. Copy to backup storage\n5. Verify backup integrity\n6. Delete backups older than 30 days\n\n## Requisitos\n\n- SSH access to server\n- Sufficient disk space\n- Backup storage configured', tags: ['database', 'devops', 'backup'] }, { type: 'procedure', title: 'Code review process', content: '## Objetivo\n\nStandardize code review workflow\n\n## Pasos\n\n1. Create feature branch\n2. Write code and tests\n3. Open PR with description\n4. Request review from teammate\n5. Address feedback\n6. Get approval\n7. Squash and merge\n\n## Requisitos\n\n- GitHub configured\n- CI passing\n- At least 1 approval', tags: ['git', 'process'] }, // Inventory { type: 'inventory', title: 'Laptop specs', content: '## Item\n\nMacBook Pro 16" 2023\n\n## Cantidad\n\n1\n\n## Ubicación\n\nHome office desk\n\n## Notas\n\n- M3 Pro chip\n- 18GB RAM\n- 512GB SSD\n- Serial: ABC123XYZ', tags: ['laptop', 'hardware'] }, { type: 'inventory', title: 'Cable management', content: '## Item\n\nUSB-C cables\n\n## Cantidad\n\n5\n\n## Ubicación\n\nDesk drawer\n\n## Notas\n\n3x 1m, 2x 2m braided', tags: ['cables', 'hardware'] }, { type: 'inventory', title: 'Office supplies', content: '## Item\n\nNotebooks\n\n## Cantidad\n\n8\n\n## Ubicación\n\nBookshelf\n\n## Notas\n\nVarious sizes, mostly unused', tags: ['office'] }, // Notes with various topics { type: 'note', title: 'Project ideas', content: '## Notas\n\n- Build a weather app with geolocation\n- Create a recipe manager\n- Design a habit tracker\n- Develop a markdown editor', tags: ['ideas', 'projects'] }, { type: 'note', title: 'Books to read', content: '## Notas\n\n1. Clean Code - Robert Martin\n2. Design Patterns - Gang of Four\n3. The Pragmatic Programmer\n4. Domain-Driven Design', tags: ['reading', 'books'] }, { type: 'note', title: 'Conference notes', content: '## Notas\n\nKey takeaways from React Conf:\n- Server Components are the future\n- Suspense for streaming\n- Better error boundaries', tags: ['conference', 'react'] }, { type: 'note', title: 'Docker compose template', content: '## Notas\n\nBasic docker-compose.yml structure for web apps:\n- App service\n- Database service\n- Redis service\n- Nginx reverse proxy', tags: ['docker', 'devops'] }, { type: 'note', title: 'API design principles', content: '## Notas\n\n- RESTful conventions\n- Use nouns, not verbs\n- Version your APIs\n- Return proper status codes\n- Pagination for lists', tags: ['api', 'backend'] }, { type: 'note', title: 'Git branching strategy', content: '## Notas\n\n- main: production\n- develop: staging\n- feature/*: new features\n- bugfix/*: fixes\n- hotfix/*: urgent production fixes', tags: ['git', 'process'] }, { type: 'note', title: 'Keyboard shortcuts VSCode', content: '## Notas\n\n- Cmd+D: Select next occurrence\n- Cmd+Shift+L: Select all occurrences\n- Cmd+P: Quick open file\n- Cmd+Shift+P: Command palette', tags: ['vscode', 'productivity'] }, { type: 'note', title: 'CSS Grid cheatsheet', content: '## Notas\n\ngrid-template-columns: repeat(3, 1fr)\ngrid-gap: 1rem\nplace-items: center\ngrid-area: header / sidebar / content / footer', tags: ['css', 'grid'] }, { type: 'note', title: 'React hooks cheatsheet', content: '## Notas\n\n- useState: local state\n- useEffect: side effects\n- useCallback: memoize function\n- useMemo: memoize value\n- useRef: mutable ref', tags: ['react', 'hooks'] }, { type: 'note', title: 'Linux commands cheatsheet', content: '## Notas\n\n- chmod +x: make executable\n- chown user:group: change owner\n- grep -r: recursive search\n- tar -czvf: compress\n- ssh -i key: connect with key', tags: ['bash', 'linux'] }, { type: 'note', title: 'SQL joins explained', content: '## Notas\n\n- INNER: matching in both\n- LEFT: all from left + matching from right\n- RIGHT: all from right + matching from left\n- FULL: all from both\n- CROSS: Cartesian product', tags: ['sql', 'database'] }, { type: 'note', title: 'TypeScript utility types', content: '## Notas\n\n- Partial: all optional\n- Required: all required\n- Pick: select fields\n- Omit: exclude fields\n- Record: key-value object\n- Exclude: remove from union', tags: ['typescript'] }, { type: 'note', title: 'Testing pyramid', content: '## Notas\n\n- Unit tests: base, many\n- Integration tests: some\n- E2E tests: few, slow, expensive', tags: ['testing', 'quality'] }, { type: 'note', title: 'Markdown syntax', content: '## Notas\n\n# Heading\n## Subheading\n**bold** *italic*\n- list\n1. numbered\n[link](url)\n```code block```', tags: ['markdown'] }, { type: 'note', title: 'Docker vs Kubernetes', content: '## Notas\n\nDocker: containerize apps\nKubernetes: orchestrate containers at scale\n\nDocker Compose: local multi-container\nK8s: production container orchestration', tags: ['docker', 'kubernetes', 'devops'] }, { type: 'note', title: 'JWT structure', content: '## Notas\n\nHeader: algorithm, type\nPayload: claims, exp, iss\nSignature: verify authenticity\n\nNever store sensitive data in JWT payload', tags: ['auth', 'security', 'jwt'] }, { type: 'note', title: 'Web security headers', content: '## Notas\n\n- Content-Security-Policy\n- X-Frame-Options\n- X-Content-Type-Options\n- Strict-Transport-Security\n- CORS', tags: ['security', 'web'] }, { type: 'note', title: 'Redis use cases', content: '## Notas\n\n- Session storage\n- Caching\n- Rate limiting\n- Pub/Sub\n- Leaderboards', tags: ['redis', 'database'] }, { type: 'note', title: 'Git squash commits', content: '## Notas\n\n```bash\ngit rebase -i HEAD~3\n```\n\nChange pick to squash for commits to combine', tags: ['git'] }, ] async function main() { console.log('Seeding database with examples...') // Clear existing notes await prisma.noteTag.deleteMany() await prisma.note.deleteMany() await prisma.tag.deleteMany() for (const note of examples) { // Create or get tags const tagRecords = await Promise.all( note.tags.map(async (tagName) => { return prisma.tag.upsert({ where: { name: tagName }, create: { name: tagName }, update: {}, }) }) ) // Create note await prisma.note.create({ data: { title: note.title, content: note.content, type: note.type, tags: { create: tagRecords.map((tag) => ({ tagId: tag.id })), }, }, }) console.log(` Created: ${note.title}`) } console.log(`\nSeeded ${examples.length} notes successfully!`) } main() .catch((e) => { console.error(e) process.exit(1) }) .finally(async () => { await prisma.$disconnect() })