This commit is contained in:
2026-03-22 13:01:46 -03:00
parent af0910f428
commit 6694bce736
52 changed files with 4949 additions and 102 deletions

BIN
prisma/dev.db Normal file

Binary file not shown.

View File

@@ -0,0 +1,30 @@
-- CreateTable
CREATE TABLE "Note" (
"id" TEXT NOT NULL PRIMARY KEY,
"title" TEXT NOT NULL,
"content" TEXT NOT NULL,
"type" TEXT NOT NULL DEFAULT 'note',
"isFavorite" BOOLEAN NOT NULL DEFAULT false,
"isPinned" BOOLEAN NOT NULL DEFAULT false,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL
);
-- CreateTable
CREATE TABLE "Tag" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL
);
-- CreateTable
CREATE TABLE "NoteTag" (
"noteId" TEXT NOT NULL,
"tagId" TEXT NOT NULL,
PRIMARY KEY ("noteId", "tagId"),
CONSTRAINT "NoteTag_noteId_fkey" FOREIGN KEY ("noteId") REFERENCES "Note" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "NoteTag_tagId_fkey" FOREIGN KEY ("tagId") REFERENCES "Tag" ("id") ON DELETE CASCADE ON UPDATE CASCADE
);
-- CreateIndex
CREATE UNIQUE INDEX "Tag_name_key" ON "Tag"("name");

View File

@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "sqlite"

35
prisma/schema.prisma Normal file
View File

@@ -0,0 +1,35 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model Note {
id String @id @default(cuid())
title String
content String
type String @default("note")
isFavorite Boolean @default(false)
isPinned Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tags NoteTag[]
}
model Tag {
id String @id @default(cuid())
name String @unique
notes NoteTag[]
}
model NoteTag {
noteId String
tagId String
note Note @relation(fields: [noteId], references: [id], onDelete: Cascade)
tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade)
@@id([noteId, tagId])
}

87
prisma/seed.ts Normal file
View File

@@ -0,0 +1,87 @@
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
await prisma.noteTag.deleteMany()
await prisma.note.deleteMany()
await prisma.tag.deleteMany()
const notes = [
{
title: 'Install Node.js with nvm',
content: '## Comando\n\n```bash\nnvm install node\nnvm use node\n```\n\n## Qué hace\nInstala la última versión de Node.js usando nvm.\n\n## Cuándo usarlo\nCuando necesitas instalar Node.js en un sistema nuevo.',
type: 'command',
tags: ['bash', 'node', 'devops'],
},
{
title: 'React useEffect cleanup pattern',
content: '## Snippet\n\n## Lenguaje\nTypeScript/React\n\n## Qué resuelve\nLimpieza correcta de suscripciones en useEffect.\n\n## Código\n```typescript\nuseEffect(() => {\n const controller = new AbortController()\n return () => controller.abort()\n}, [])\n```',
type: 'snippet',
tags: ['code', 'react', 'frontend'],
},
{
title: 'Usar PostgreSQL para producción',
content: '## Contexto\nEl MVP usa SQLite pero en producción necesitamos más capacidad.\n\n## Decisión\nMigrar a PostgreSQL manteniendo el mismo Prisma ORM.\n\n## Alternativas consideradas\n- MySQL: mejor soporte JSON pero menos popular\n- MongoDB: demasiado flexible\n\n## Consecuencias\n- Mejor concurrencia\n- Migración transparente con Prisma',
type: 'decision',
tags: ['arquitectura', 'backend'],
},
{
title: 'Pollo al horno con hierbas',
content: '## Ingredientes\n- 1 pollo entero (~1.5kg)\n- 4 dientes de ajo\n- Romero fresco\n- Tomillo\n- Aceite de oliva\n- Sal y pimienta\n\n## Pasos\n1. Precalentar horno a 200°C\n2. Limpiar y secar el pollo\n3. Untar con aceite y especias\n4. Hornear 1 hora\n5. Descansar 10 min antes de cortar\n\n## Tiempo\n1h 15min total\n\n## Notas\nQueda muy jugoso si lo vuelves a bañar con sus jugos a mitad de cocción.',
type: 'recipe',
tags: ['cocina'],
},
{
title: 'Renovar pasaporte argentino',
content: '## Objetivo\nRenovar el pasaporte argentino vencido.\n\n## Pasos\n1. Sacar turno online en turno.gob.ar\n2. Llevar DNI original\n3. Llevar pasaporte anterior\n4. Pagar tasa de renovación\n5. Esperar ~15 días hábiles\n\n## Requisitos\n- DNI vigente\n- Pasaporte anterior\n\n## Problemas comunes\n- Los turnos se agotan rápido',
type: 'procedure',
tags: ['trámite', 'hogar'],
},
{
title: 'Inventario cocina',
content: '## Item | Cantidad | Ubicación\nArroz | 2kg | Alacena\nFideos | 5 paquetes | Alacena\nLentejas | 1kg | Alacena\nAceite | 2L | Bajo mesada\nSal | 3 paquetes | Mesa\n\n## Notas\nRevisar fechas de vencimiento cada 6 meses.',
type: 'inventory',
tags: ['hogar', 'inventario'],
},
{
title: 'Ideas para vacaciones 2026',
content: '## Opciones\n1. Costa atlántica argentina\n2. Bariloche (invierno)\n3. Viaje a Europa\n\n## Presupuesto estimado\n- Argentina: $500-800 USD\n- Europa: $2000-3000 USD\n\n## Preferencias\n- Prefiero naturaleza sobre ciudades',
type: 'note',
tags: ['viajes', 'planificación'],
},
{
title: 'Resumen libro: Atomic Habits',
content: '## Ideas principales\n- Hábitos compound: pequeños cambios dan grandes resultados\n- No importa si eres mejor o peor, importa tu sistema\n- 1% mejor cada día = 37x mejor al año\n\n## Aplicar\n- Crear morning routine\n- Eliminar malos hábitos con diseño ambiental\n- No perder rachas',
type: 'note',
tags: ['lectura', 'productividad'],
},
]
for (const note of notes) {
const { tags, ...noteData } = note
await prisma.note.create({
data: {
...noteData,
tags: {
create: await Promise.all(
tags.map(async (tagName) => {
const tag = await prisma.tag.upsert({
where: { name: tagName },
create: { name: tagName },
update: {},
})
return { tagId: tag.id }
})
),
},
},
})
}
console.log('Seed completed')
}
main()
.catch(console.error)
.finally(() => prisma.$disconnect())