diff --git a/.env.example b/.env.example index 609ded0..43b7b0c 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,6 @@ # --- Base de datos ----------------------------------------------------------- # En local basta un archivo SQLite. En producción, la URL de Turso (libsql://…). -DATABASE_URL=file:local.db +DATABASE_URL=postgresql://senza_paura_web:CLAVE@192.168.18.171:5432/senzapaura # --- Audio ------------------------------------------------------------------- # Directorio privado con los archivos completos. NO debe servirse como estático: diff --git a/README.md b/README.md index 0033491..69fd476 100644 --- a/README.md +++ b/README.md @@ -904,6 +904,25 @@ enlace a nuestra propia pantalla de acceso con `?volverA=` apuntando fuera para que alguien escriba su correo aquí y acabe en una página ajena creyendo que sigue en esta. +## La base de datos + +**PostgreSQL 16**, con Drizzle por delante. Aquí no vive el catálogo —estilos, +discos, temas y capítulos siguen siendo Markdown del repositorio—: la base +guarda solo lo que generan las personas que visitan la web, que es lo que no +puede estar en el código. Cuentas, códigos de acceso, sesiones, límites de +envío, carritos, pedidos, compras, favoritos y valoraciones. + +Dos diferencias con SQLite que costaron un fallo cada una, por si aparecen otra +vez: + +- **`integer` en Postgres son cuatro bytes**, no ocho. El limitador guarda su + vencimiento en milisegundos desde 1970 —trece dígitos— y en `integer` no + cabe: va en `bigint`. +- **`avg()` y `count()` llegan como cadena.** El driver no las convierte para + no perder precisión, así que `cuantas === 0` nunca se cumpliría y «1 voto» + saldría siempre en plural. Se convierten en la propia consulta con + `::float8` y `::int`. + ## Variables de entorno Copia `.env.example` a `.env`. Todas son opcionales en desarrollo: diff --git a/drizzle.config.ts b/drizzle.config.ts index 317f310..d57e081 100644 --- a/drizzle.config.ts +++ b/drizzle.config.ts @@ -4,7 +4,7 @@ if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set'); export default defineConfig({ schema: './src/lib/server/db/schema.ts', - dialect: 'sqlite', + dialect: 'postgresql', dbCredentials: { url: process.env.DATABASE_URL }, verbose: true, strict: true diff --git a/drizzle/0000_aromatic_bug.sql b/drizzle/0000_aromatic_bug.sql new file mode 100644 index 0000000..e0f276c --- /dev/null +++ b/drizzle/0000_aromatic_bug.sql @@ -0,0 +1,106 @@ +CREATE TABLE "carrito" ( + "id" text PRIMARY KEY NOT NULL, + "usuario_id" text, + "creado_en" timestamp with time zone NOT NULL, + "actualizado_en" timestamp with time zone NOT NULL +); +--> statement-breakpoint +CREATE TABLE "carrito_item" ( + "carrito_id" text NOT NULL, + "cancion_slug" text NOT NULL, + "anadido_en" timestamp with time zone NOT NULL, + CONSTRAINT "carrito_item_carrito_id_cancion_slug_pk" PRIMARY KEY("carrito_id","cancion_slug") +); +--> statement-breakpoint +CREATE TABLE "codigo_acceso" ( + "id" text PRIMARY KEY NOT NULL, + "email" text NOT NULL, + "hash" text NOT NULL, + "expira_en" timestamp with time zone NOT NULL, + "intentos" integer DEFAULT 0 NOT NULL, + "usado_en" timestamp with time zone, + "creado_en" timestamp with time zone NOT NULL +); +--> statement-breakpoint +CREATE TABLE "compra" ( + "usuario_id" text NOT NULL, + "cancion_slug" text NOT NULL, + "pedido_id" text NOT NULL, + "comprado_en" timestamp with time zone NOT NULL, + CONSTRAINT "compra_usuario_id_cancion_slug_pk" PRIMARY KEY("usuario_id","cancion_slug") +); +--> statement-breakpoint +CREATE TABLE "favorito" ( + "usuario_id" text NOT NULL, + "cancion_slug" text NOT NULL, + "marcado_en" timestamp with time zone NOT NULL, + CONSTRAINT "favorito_usuario_id_cancion_slug_pk" PRIMARY KEY("usuario_id","cancion_slug") +); +--> statement-breakpoint +CREATE TABLE "limite" ( + "clave" text PRIMARY KEY NOT NULL, + "intentos" integer NOT NULL, + "expira_en" bigint NOT NULL +); +--> statement-breakpoint +CREATE TABLE "pedido" ( + "id" text PRIMARY KEY NOT NULL, + "usuario_id" text NOT NULL, + "sesion_pago_id" text NOT NULL, + "estado" text DEFAULT 'pendiente' NOT NULL, + "packs" integer NOT NULL, + "total_centimos" integer NOT NULL, + "moneda" text DEFAULT 'eur' NOT NULL, + "creado_en" timestamp with time zone NOT NULL, + "pagado_en" timestamp with time zone, + CONSTRAINT "pedido_sesion_pago_id_unique" UNIQUE("sesion_pago_id") +); +--> statement-breakpoint +CREATE TABLE "pedido_item" ( + "pedido_id" text NOT NULL, + "cancion_slug" text NOT NULL, + "titulo" text NOT NULL, + CONSTRAINT "pedido_item_pedido_id_cancion_slug_pk" PRIMARY KEY("pedido_id","cancion_slug") +); +--> statement-breakpoint +CREATE TABLE "sesion" ( + "id" text PRIMARY KEY NOT NULL, + "usuario_id" text NOT NULL, + "expira_en" timestamp with time zone NOT NULL, + "creada_en" timestamp with time zone NOT NULL +); +--> statement-breakpoint +CREATE TABLE "usuario" ( + "id" text PRIMARY KEY NOT NULL, + "email" text NOT NULL, + "nombre" text, + "creado_en" timestamp with time zone NOT NULL, + "ultimo_acceso_en" timestamp with time zone, + CONSTRAINT "usuario_email_unique" UNIQUE("email") +); +--> statement-breakpoint +CREATE TABLE "valoracion" ( + "usuario_id" text NOT NULL, + "cancion_slug" text NOT NULL, + "puntuacion" integer NOT NULL, + "creada_en" timestamp with time zone NOT NULL, + "actualizada_en" timestamp with time zone NOT NULL, + CONSTRAINT "valoracion_usuario_id_cancion_slug_pk" PRIMARY KEY("usuario_id","cancion_slug") +); +--> statement-breakpoint +ALTER TABLE "carrito" ADD CONSTRAINT "carrito_usuario_id_usuario_id_fk" FOREIGN KEY ("usuario_id") REFERENCES "public"."usuario"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "carrito_item" ADD CONSTRAINT "carrito_item_carrito_id_carrito_id_fk" FOREIGN KEY ("carrito_id") REFERENCES "public"."carrito"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "compra" ADD CONSTRAINT "compra_usuario_id_usuario_id_fk" FOREIGN KEY ("usuario_id") REFERENCES "public"."usuario"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "compra" ADD CONSTRAINT "compra_pedido_id_pedido_id_fk" FOREIGN KEY ("pedido_id") REFERENCES "public"."pedido"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "favorito" ADD CONSTRAINT "favorito_usuario_id_usuario_id_fk" FOREIGN KEY ("usuario_id") REFERENCES "public"."usuario"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "pedido" ADD CONSTRAINT "pedido_usuario_id_usuario_id_fk" FOREIGN KEY ("usuario_id") REFERENCES "public"."usuario"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "pedido_item" ADD CONSTRAINT "pedido_item_pedido_id_pedido_id_fk" FOREIGN KEY ("pedido_id") REFERENCES "public"."pedido"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "sesion" ADD CONSTRAINT "sesion_usuario_id_usuario_id_fk" FOREIGN KEY ("usuario_id") REFERENCES "public"."usuario"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "valoracion" ADD CONSTRAINT "valoracion_usuario_id_usuario_id_fk" FOREIGN KEY ("usuario_id") REFERENCES "public"."usuario"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint +CREATE INDEX "carrito_usuario" ON "carrito" USING btree ("usuario_id");--> statement-breakpoint +CREATE INDEX "codigo_acceso_email" ON "codigo_acceso" USING btree ("email");--> statement-breakpoint +CREATE INDEX "idx_favorito_usuario" ON "favorito" USING btree ("usuario_id");--> statement-breakpoint +CREATE INDEX "limite_expira" ON "limite" USING btree ("expira_en");--> statement-breakpoint +CREATE INDEX "pedido_usuario" ON "pedido" USING btree ("usuario_id");--> statement-breakpoint +CREATE INDEX "sesion_usuario" ON "sesion" USING btree ("usuario_id");--> statement-breakpoint +CREATE INDEX "idx_valoracion_cancion" ON "valoracion" USING btree ("cancion_slug"); \ No newline at end of file diff --git a/drizzle/0000_good_magma.sql b/drizzle/0000_good_magma.sql deleted file mode 100644 index b8cc8ba..0000000 --- a/drizzle/0000_good_magma.sql +++ /dev/null @@ -1,79 +0,0 @@ -CREATE TABLE `carrito` ( - `id` text PRIMARY KEY NOT NULL, - `usuario_id` text, - `creado_en` integer NOT NULL, - `actualizado_en` integer NOT NULL, - FOREIGN KEY (`usuario_id`) REFERENCES `usuario`(`id`) ON UPDATE no action ON DELETE cascade -); ---> statement-breakpoint -CREATE INDEX `carrito_usuario` ON `carrito` (`usuario_id`);--> statement-breakpoint -CREATE TABLE `carrito_item` ( - `carrito_id` text NOT NULL, - `cancion_slug` text NOT NULL, - `anadido_en` integer NOT NULL, - PRIMARY KEY(`carrito_id`, `cancion_slug`), - FOREIGN KEY (`carrito_id`) REFERENCES `carrito`(`id`) ON UPDATE no action ON DELETE cascade -); ---> statement-breakpoint -CREATE TABLE `codigo_acceso` ( - `id` text PRIMARY KEY NOT NULL, - `email` text NOT NULL, - `hash` text NOT NULL, - `expira_en` integer NOT NULL, - `intentos` integer DEFAULT 0 NOT NULL, - `usado_en` integer, - `creado_en` integer NOT NULL -); ---> statement-breakpoint -CREATE INDEX `codigo_acceso_email` ON `codigo_acceso` (`email`);--> statement-breakpoint -CREATE TABLE `compra` ( - `usuario_id` text NOT NULL, - `cancion_slug` text NOT NULL, - `pedido_id` text NOT NULL, - `comprado_en` integer NOT NULL, - PRIMARY KEY(`usuario_id`, `cancion_slug`), - FOREIGN KEY (`usuario_id`) REFERENCES `usuario`(`id`) ON UPDATE no action ON DELETE cascade, - FOREIGN KEY (`pedido_id`) REFERENCES `pedido`(`id`) ON UPDATE no action ON DELETE cascade -); ---> statement-breakpoint -CREATE TABLE `pedido` ( - `id` text PRIMARY KEY NOT NULL, - `usuario_id` text NOT NULL, - `sesion_pago_id` text NOT NULL, - `estado` text DEFAULT 'pendiente' NOT NULL, - `packs` integer NOT NULL, - `total_centimos` integer NOT NULL, - `moneda` text DEFAULT 'eur' NOT NULL, - `creado_en` integer NOT NULL, - `pagado_en` integer, - FOREIGN KEY (`usuario_id`) REFERENCES `usuario`(`id`) ON UPDATE no action ON DELETE cascade -); ---> statement-breakpoint -CREATE UNIQUE INDEX `pedido_sesion_pago_id_unique` ON `pedido` (`sesion_pago_id`);--> statement-breakpoint -CREATE INDEX `pedido_usuario` ON `pedido` (`usuario_id`);--> statement-breakpoint -CREATE TABLE `pedido_item` ( - `pedido_id` text NOT NULL, - `cancion_slug` text NOT NULL, - `titulo` text NOT NULL, - PRIMARY KEY(`pedido_id`, `cancion_slug`), - FOREIGN KEY (`pedido_id`) REFERENCES `pedido`(`id`) ON UPDATE no action ON DELETE cascade -); ---> statement-breakpoint -CREATE TABLE `sesion` ( - `id` text PRIMARY KEY NOT NULL, - `usuario_id` text NOT NULL, - `expira_en` integer NOT NULL, - `creada_en` integer NOT NULL, - FOREIGN KEY (`usuario_id`) REFERENCES `usuario`(`id`) ON UPDATE no action ON DELETE cascade -); ---> statement-breakpoint -CREATE INDEX `sesion_usuario` ON `sesion` (`usuario_id`);--> statement-breakpoint -CREATE TABLE `usuario` ( - `id` text PRIMARY KEY NOT NULL, - `email` text NOT NULL, - `nombre` text, - `creado_en` integer NOT NULL, - `ultimo_acceso_en` integer -); ---> statement-breakpoint -CREATE UNIQUE INDEX `usuario_email_unique` ON `usuario` (`email`); \ No newline at end of file diff --git a/drizzle/0001_ancient_goblin_queen.sql b/drizzle/0001_ancient_goblin_queen.sql deleted file mode 100644 index af583c3..0000000 --- a/drizzle/0001_ancient_goblin_queen.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE TABLE `limite` ( - `clave` text PRIMARY KEY NOT NULL, - `intentos` integer NOT NULL, - `expira_en` integer NOT NULL -); ---> statement-breakpoint -CREATE INDEX `limite_expira` ON `limite` (`expira_en`); \ No newline at end of file diff --git a/drizzle/0002_common_jean_grey.sql b/drizzle/0002_common_jean_grey.sql deleted file mode 100644 index 1a9deb8..0000000 --- a/drizzle/0002_common_jean_grey.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE `valoracion` ( - `usuario_id` text NOT NULL, - `cancion_slug` text NOT NULL, - `puntuacion` integer NOT NULL, - `creada_en` integer NOT NULL, - `actualizada_en` integer NOT NULL, - PRIMARY KEY(`usuario_id`, `cancion_slug`), - FOREIGN KEY (`usuario_id`) REFERENCES `usuario`(`id`) ON UPDATE no action ON DELETE cascade -); ---> statement-breakpoint -CREATE INDEX `idx_valoracion_cancion` ON `valoracion` (`cancion_slug`); \ No newline at end of file diff --git a/drizzle/0003_dark_mad_thinker.sql b/drizzle/0003_dark_mad_thinker.sql deleted file mode 100644 index 1ef914f..0000000 --- a/drizzle/0003_dark_mad_thinker.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE `favorito` ( - `usuario_id` text NOT NULL, - `cancion_slug` text NOT NULL, - `marcado_en` integer NOT NULL, - PRIMARY KEY(`usuario_id`, `cancion_slug`), - FOREIGN KEY (`usuario_id`) REFERENCES `usuario`(`id`) ON UPDATE no action ON DELETE cascade -); ---> statement-breakpoint -CREATE INDEX `idx_favorito_usuario` ON `favorito` (`usuario_id`); \ No newline at end of file diff --git a/drizzle/meta/0000_snapshot.json b/drizzle/meta/0000_snapshot.json index 7906db2..5b4d1e5 100644 --- a/drizzle/meta/0000_snapshot.json +++ b/drizzle/meta/0000_snapshot.json @@ -1,48 +1,53 @@ { - "version": "6", - "dialect": "sqlite", - "id": "375db306-e08d-48ac-910e-912f1c38c7e5", + "id": "de6718aa-a69c-4f5b-8cfa-5a4a7b3a470b", "prevId": "00000000-0000-0000-0000-000000000000", + "version": "7", + "dialect": "postgresql", "tables": { - "carrito": { + "public.carrito": { "name": "carrito", + "schema": "", "columns": { "id": { "name": "id", "type": "text", "primaryKey": true, - "notNull": true, - "autoincrement": false + "notNull": true }, "usuario_id": { "name": "usuario_id", "type": "text", "primaryKey": false, - "notNull": false, - "autoincrement": false + "notNull": false }, "creado_en": { "name": "creado_en", - "type": "integer", + "type": "timestamp with time zone", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "actualizado_en": { "name": "actualizado_en", - "type": "integer", + "type": "timestamp with time zone", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true } }, "indexes": { "carrito_usuario": { "name": "carrito_usuario", "columns": [ - "usuario_id" + { + "expression": "usuario_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } ], - "isUnique": false + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} } }, "foreignKeys": { @@ -62,31 +67,31 @@ }, "compositePrimaryKeys": {}, "uniqueConstraints": {}, - "checkConstraints": {} + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false }, - "carrito_item": { + "public.carrito_item": { "name": "carrito_item", + "schema": "", "columns": { "carrito_id": { "name": "carrito_id", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "cancion_slug": { "name": "cancion_slug", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "anadido_en": { "name": "anadido_en", - "type": "integer", + "type": "timestamp with time zone", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true } }, "indexes": {}, @@ -107,114 +112,117 @@ }, "compositePrimaryKeys": { "carrito_item_carrito_id_cancion_slug_pk": { + "name": "carrito_item_carrito_id_cancion_slug_pk", "columns": [ "carrito_id", "cancion_slug" - ], - "name": "carrito_item_carrito_id_cancion_slug_pk" + ] } }, "uniqueConstraints": {}, - "checkConstraints": {} + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false }, - "codigo_acceso": { + "public.codigo_acceso": { "name": "codigo_acceso", + "schema": "", "columns": { "id": { "name": "id", "type": "text", "primaryKey": true, - "notNull": true, - "autoincrement": false + "notNull": true }, "email": { "name": "email", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "hash": { "name": "hash", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "expira_en": { "name": "expira_en", - "type": "integer", + "type": "timestamp with time zone", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "intentos": { "name": "intentos", "type": "integer", "primaryKey": false, "notNull": true, - "autoincrement": false, "default": 0 }, "usado_en": { "name": "usado_en", - "type": "integer", + "type": "timestamp with time zone", "primaryKey": false, - "notNull": false, - "autoincrement": false + "notNull": false }, "creado_en": { "name": "creado_en", - "type": "integer", + "type": "timestamp with time zone", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true } }, "indexes": { "codigo_acceso_email": { "name": "codigo_acceso_email", "columns": [ - "email" + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } ], - "isUnique": false + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} } }, "foreignKeys": {}, "compositePrimaryKeys": {}, "uniqueConstraints": {}, - "checkConstraints": {} + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false }, - "compra": { + "public.compra": { "name": "compra", + "schema": "", "columns": { "usuario_id": { "name": "usuario_id", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "cancion_slug": { "name": "cancion_slug", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "pedido_id": { "name": "pedido_id", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "comprado_en": { "name": "comprado_en", - "type": "integer", + "type": "timestamp with time zone", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true } }, "indexes": {}, @@ -248,99 +256,210 @@ }, "compositePrimaryKeys": { "compra_usuario_id_cancion_slug_pk": { + "name": "compra_usuario_id_cancion_slug_pk", "columns": [ "usuario_id", "cancion_slug" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.favorito": { + "name": "favorito", + "schema": "", + "columns": { + "usuario_id": { + "name": "usuario_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cancion_slug": { + "name": "cancion_slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "marcado_en": { + "name": "marcado_en", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "idx_favorito_usuario": { + "name": "idx_favorito_usuario", + "columns": [ + { + "expression": "usuario_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } ], - "name": "compra_usuario_id_cancion_slug_pk" + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} } }, + "foreignKeys": { + "favorito_usuario_id_usuario_id_fk": { + "name": "favorito_usuario_id_usuario_id_fk", + "tableFrom": "favorito", + "tableTo": "usuario", + "columnsFrom": [ + "usuario_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "favorito_usuario_id_cancion_slug_pk": { + "name": "favorito_usuario_id_cancion_slug_pk", + "columns": [ + "usuario_id", + "cancion_slug" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.limite": { + "name": "limite", + "schema": "", + "columns": { + "clave": { + "name": "clave", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "intentos": { + "name": "intentos", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "expira_en": { + "name": "expira_en", + "type": "bigint", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "limite_expira": { + "name": "limite_expira", + "columns": [ + { + "expression": "expira_en", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, "uniqueConstraints": {}, - "checkConstraints": {} + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false }, - "pedido": { + "public.pedido": { "name": "pedido", + "schema": "", "columns": { "id": { "name": "id", "type": "text", "primaryKey": true, - "notNull": true, - "autoincrement": false + "notNull": true }, "usuario_id": { "name": "usuario_id", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "sesion_pago_id": { "name": "sesion_pago_id", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "estado": { "name": "estado", "type": "text", "primaryKey": false, "notNull": true, - "autoincrement": false, "default": "'pendiente'" }, "packs": { "name": "packs", "type": "integer", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "total_centimos": { "name": "total_centimos", "type": "integer", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "moneda": { "name": "moneda", "type": "text", "primaryKey": false, "notNull": true, - "autoincrement": false, "default": "'eur'" }, "creado_en": { "name": "creado_en", - "type": "integer", + "type": "timestamp with time zone", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "pagado_en": { "name": "pagado_en", - "type": "integer", + "type": "timestamp with time zone", "primaryKey": false, - "notNull": false, - "autoincrement": false + "notNull": false } }, "indexes": { - "pedido_sesion_pago_id_unique": { - "name": "pedido_sesion_pago_id_unique", - "columns": [ - "sesion_pago_id" - ], - "isUnique": true - }, "pedido_usuario": { "name": "pedido_usuario", "columns": [ - "usuario_id" + { + "expression": "usuario_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } ], - "isUnique": false + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} } }, "foreignKeys": { @@ -359,32 +478,40 @@ } }, "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} + "uniqueConstraints": { + "pedido_sesion_pago_id_unique": { + "name": "pedido_sesion_pago_id_unique", + "nullsNotDistinct": false, + "columns": [ + "sesion_pago_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false }, - "pedido_item": { + "public.pedido_item": { "name": "pedido_item", + "schema": "", "columns": { "pedido_id": { "name": "pedido_id", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "cancion_slug": { "name": "cancion_slug", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "titulo": { "name": "titulo", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true } }, "indexes": {}, @@ -405,55 +532,62 @@ }, "compositePrimaryKeys": { "pedido_item_pedido_id_cancion_slug_pk": { + "name": "pedido_item_pedido_id_cancion_slug_pk", "columns": [ "pedido_id", "cancion_slug" - ], - "name": "pedido_item_pedido_id_cancion_slug_pk" + ] } }, "uniqueConstraints": {}, - "checkConstraints": {} + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false }, - "sesion": { + "public.sesion": { "name": "sesion", + "schema": "", "columns": { "id": { "name": "id", "type": "text", "primaryKey": true, - "notNull": true, - "autoincrement": false + "notNull": true }, "usuario_id": { "name": "usuario_id", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "expira_en": { "name": "expira_en", - "type": "integer", + "type": "timestamp with time zone", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "creada_en": { "name": "creada_en", - "type": "integer", + "type": "timestamp with time zone", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true } }, "indexes": { "sesion_usuario": { "name": "sesion_usuario", "columns": [ - "usuario_id" + { + "expression": "usuario_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } ], - "isUnique": false + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} } }, "foreignKeys": { @@ -473,70 +607,152 @@ }, "compositePrimaryKeys": {}, "uniqueConstraints": {}, - "checkConstraints": {} + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false }, - "usuario": { + "public.usuario": { "name": "usuario", + "schema": "", "columns": { "id": { "name": "id", "type": "text", "primaryKey": true, - "notNull": true, - "autoincrement": false + "notNull": true }, "email": { "name": "email", "type": "text", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "nombre": { "name": "nombre", "type": "text", "primaryKey": false, - "notNull": false, - "autoincrement": false + "notNull": false }, "creado_en": { "name": "creado_en", - "type": "integer", + "type": "timestamp with time zone", "primaryKey": false, - "notNull": true, - "autoincrement": false + "notNull": true }, "ultimo_acceso_en": { "name": "ultimo_acceso_en", - "type": "integer", + "type": "timestamp with time zone", "primaryKey": false, - "notNull": false, - "autoincrement": false + "notNull": false } }, - "indexes": { + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { "usuario_email_unique": { "name": "usuario_email_unique", + "nullsNotDistinct": false, "columns": [ "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.valoracion": { + "name": "valoracion", + "schema": "", + "columns": { + "usuario_id": { + "name": "usuario_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cancion_slug": { + "name": "cancion_slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "puntuacion": { + "name": "puntuacion", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "creada_en": { + "name": "creada_en", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "actualizada_en": { + "name": "actualizada_en", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "idx_valoracion_cancion": { + "name": "idx_valoracion_cancion", + "columns": [ + { + "expression": "cancion_slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } ], - "isUnique": true + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "valoracion_usuario_id_usuario_id_fk": { + "name": "valoracion_usuario_id_usuario_id_fk", + "tableFrom": "valoracion", + "tableTo": "usuario", + "columnsFrom": [ + "usuario_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "valoracion_usuario_id_cancion_slug_pk": { + "name": "valoracion_usuario_id_cancion_slug_pk", + "columns": [ + "usuario_id", + "cancion_slug" + ] } }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, "uniqueConstraints": {}, - "checkConstraints": {} + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false } }, - "views": {}, "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, "_meta": { + "columns": {}, "schemas": {}, - "tables": {}, - "columns": {} - }, - "internal": { - "indexes": {} + "tables": {} } } \ No newline at end of file diff --git a/drizzle/meta/0001_snapshot.json b/drizzle/meta/0001_snapshot.json deleted file mode 100644 index 8b979c8..0000000 --- a/drizzle/meta/0001_snapshot.json +++ /dev/null @@ -1,581 +0,0 @@ -{ - "version": "6", - "dialect": "sqlite", - "id": "7662184c-1b15-413a-8519-dc445f9e1d9d", - "prevId": "375db306-e08d-48ac-910e-912f1c38c7e5", - "tables": { - "carrito": { - "name": "carrito", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "creado_en": { - "name": "creado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "actualizado_en": { - "name": "actualizado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "carrito_usuario": { - "name": "carrito_usuario", - "columns": [ - "usuario_id" - ], - "isUnique": false - } - }, - "foreignKeys": { - "carrito_usuario_id_usuario_id_fk": { - "name": "carrito_usuario_id_usuario_id_fk", - "tableFrom": "carrito", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "carrito_item": { - "name": "carrito_item", - "columns": { - "carrito_id": { - "name": "carrito_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "cancion_slug": { - "name": "cancion_slug", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "anadido_en": { - "name": "anadido_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "carrito_item_carrito_id_carrito_id_fk": { - "name": "carrito_item_carrito_id_carrito_id_fk", - "tableFrom": "carrito_item", - "tableTo": "carrito", - "columnsFrom": [ - "carrito_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "carrito_item_carrito_id_cancion_slug_pk": { - "columns": [ - "carrito_id", - "cancion_slug" - ], - "name": "carrito_item_carrito_id_cancion_slug_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "codigo_acceso": { - "name": "codigo_acceso", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "hash": { - "name": "hash", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expira_en": { - "name": "expira_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "intentos": { - "name": "intentos", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": 0 - }, - "usado_en": { - "name": "usado_en", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "creado_en": { - "name": "creado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "codigo_acceso_email": { - "name": "codigo_acceso_email", - "columns": [ - "email" - ], - "isUnique": false - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "compra": { - "name": "compra", - "columns": { - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "cancion_slug": { - "name": "cancion_slug", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "pedido_id": { - "name": "pedido_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "comprado_en": { - "name": "comprado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "compra_usuario_id_usuario_id_fk": { - "name": "compra_usuario_id_usuario_id_fk", - "tableFrom": "compra", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "compra_pedido_id_pedido_id_fk": { - "name": "compra_pedido_id_pedido_id_fk", - "tableFrom": "compra", - "tableTo": "pedido", - "columnsFrom": [ - "pedido_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "compra_usuario_id_cancion_slug_pk": { - "columns": [ - "usuario_id", - "cancion_slug" - ], - "name": "compra_usuario_id_cancion_slug_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "limite": { - "name": "limite", - "columns": { - "clave": { - "name": "clave", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "intentos": { - "name": "intentos", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expira_en": { - "name": "expira_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "limite_expira": { - "name": "limite_expira", - "columns": [ - "expira_en" - ], - "isUnique": false - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "pedido": { - "name": "pedido", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "sesion_pago_id": { - "name": "sesion_pago_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "estado": { - "name": "estado", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'pendiente'" - }, - "packs": { - "name": "packs", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "total_centimos": { - "name": "total_centimos", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "moneda": { - "name": "moneda", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'eur'" - }, - "creado_en": { - "name": "creado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "pagado_en": { - "name": "pagado_en", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "pedido_sesion_pago_id_unique": { - "name": "pedido_sesion_pago_id_unique", - "columns": [ - "sesion_pago_id" - ], - "isUnique": true - }, - "pedido_usuario": { - "name": "pedido_usuario", - "columns": [ - "usuario_id" - ], - "isUnique": false - } - }, - "foreignKeys": { - "pedido_usuario_id_usuario_id_fk": { - "name": "pedido_usuario_id_usuario_id_fk", - "tableFrom": "pedido", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "pedido_item": { - "name": "pedido_item", - "columns": { - "pedido_id": { - "name": "pedido_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "cancion_slug": { - "name": "cancion_slug", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "titulo": { - "name": "titulo", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "pedido_item_pedido_id_pedido_id_fk": { - "name": "pedido_item_pedido_id_pedido_id_fk", - "tableFrom": "pedido_item", - "tableTo": "pedido", - "columnsFrom": [ - "pedido_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "pedido_item_pedido_id_cancion_slug_pk": { - "columns": [ - "pedido_id", - "cancion_slug" - ], - "name": "pedido_item_pedido_id_cancion_slug_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "sesion": { - "name": "sesion", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expira_en": { - "name": "expira_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "creada_en": { - "name": "creada_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "sesion_usuario": { - "name": "sesion_usuario", - "columns": [ - "usuario_id" - ], - "isUnique": false - } - }, - "foreignKeys": { - "sesion_usuario_id_usuario_id_fk": { - "name": "sesion_usuario_id_usuario_id_fk", - "tableFrom": "sesion", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "usuario": { - "name": "usuario", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "nombre": { - "name": "nombre", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "creado_en": { - "name": "creado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "ultimo_acceso_en": { - "name": "ultimo_acceso_en", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "usuario_email_unique": { - "name": "usuario_email_unique", - "columns": [ - "email" - ], - "isUnique": true - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - } - }, - "views": {}, - "enums": {}, - "_meta": { - "schemas": {}, - "tables": {}, - "columns": {} - }, - "internal": { - "indexes": {} - } -} \ No newline at end of file diff --git a/drizzle/meta/0002_snapshot.json b/drizzle/meta/0002_snapshot.json deleted file mode 100644 index 082346c..0000000 --- a/drizzle/meta/0002_snapshot.json +++ /dev/null @@ -1,656 +0,0 @@ -{ - "version": "6", - "dialect": "sqlite", - "id": "451fba36-e77b-45fd-894c-a02c708cdcbf", - "prevId": "7662184c-1b15-413a-8519-dc445f9e1d9d", - "tables": { - "carrito": { - "name": "carrito", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "creado_en": { - "name": "creado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "actualizado_en": { - "name": "actualizado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "carrito_usuario": { - "name": "carrito_usuario", - "columns": [ - "usuario_id" - ], - "isUnique": false - } - }, - "foreignKeys": { - "carrito_usuario_id_usuario_id_fk": { - "name": "carrito_usuario_id_usuario_id_fk", - "tableFrom": "carrito", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "carrito_item": { - "name": "carrito_item", - "columns": { - "carrito_id": { - "name": "carrito_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "cancion_slug": { - "name": "cancion_slug", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "anadido_en": { - "name": "anadido_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "carrito_item_carrito_id_carrito_id_fk": { - "name": "carrito_item_carrito_id_carrito_id_fk", - "tableFrom": "carrito_item", - "tableTo": "carrito", - "columnsFrom": [ - "carrito_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "carrito_item_carrito_id_cancion_slug_pk": { - "columns": [ - "carrito_id", - "cancion_slug" - ], - "name": "carrito_item_carrito_id_cancion_slug_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "codigo_acceso": { - "name": "codigo_acceso", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "hash": { - "name": "hash", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expira_en": { - "name": "expira_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "intentos": { - "name": "intentos", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": 0 - }, - "usado_en": { - "name": "usado_en", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "creado_en": { - "name": "creado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "codigo_acceso_email": { - "name": "codigo_acceso_email", - "columns": [ - "email" - ], - "isUnique": false - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "compra": { - "name": "compra", - "columns": { - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "cancion_slug": { - "name": "cancion_slug", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "pedido_id": { - "name": "pedido_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "comprado_en": { - "name": "comprado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "compra_usuario_id_usuario_id_fk": { - "name": "compra_usuario_id_usuario_id_fk", - "tableFrom": "compra", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "compra_pedido_id_pedido_id_fk": { - "name": "compra_pedido_id_pedido_id_fk", - "tableFrom": "compra", - "tableTo": "pedido", - "columnsFrom": [ - "pedido_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "compra_usuario_id_cancion_slug_pk": { - "columns": [ - "usuario_id", - "cancion_slug" - ], - "name": "compra_usuario_id_cancion_slug_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "limite": { - "name": "limite", - "columns": { - "clave": { - "name": "clave", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "intentos": { - "name": "intentos", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expira_en": { - "name": "expira_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "limite_expira": { - "name": "limite_expira", - "columns": [ - "expira_en" - ], - "isUnique": false - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "pedido": { - "name": "pedido", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "sesion_pago_id": { - "name": "sesion_pago_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "estado": { - "name": "estado", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'pendiente'" - }, - "packs": { - "name": "packs", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "total_centimos": { - "name": "total_centimos", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "moneda": { - "name": "moneda", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'eur'" - }, - "creado_en": { - "name": "creado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "pagado_en": { - "name": "pagado_en", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "pedido_sesion_pago_id_unique": { - "name": "pedido_sesion_pago_id_unique", - "columns": [ - "sesion_pago_id" - ], - "isUnique": true - }, - "pedido_usuario": { - "name": "pedido_usuario", - "columns": [ - "usuario_id" - ], - "isUnique": false - } - }, - "foreignKeys": { - "pedido_usuario_id_usuario_id_fk": { - "name": "pedido_usuario_id_usuario_id_fk", - "tableFrom": "pedido", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "pedido_item": { - "name": "pedido_item", - "columns": { - "pedido_id": { - "name": "pedido_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "cancion_slug": { - "name": "cancion_slug", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "titulo": { - "name": "titulo", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "pedido_item_pedido_id_pedido_id_fk": { - "name": "pedido_item_pedido_id_pedido_id_fk", - "tableFrom": "pedido_item", - "tableTo": "pedido", - "columnsFrom": [ - "pedido_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "pedido_item_pedido_id_cancion_slug_pk": { - "columns": [ - "pedido_id", - "cancion_slug" - ], - "name": "pedido_item_pedido_id_cancion_slug_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "sesion": { - "name": "sesion", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expira_en": { - "name": "expira_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "creada_en": { - "name": "creada_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "sesion_usuario": { - "name": "sesion_usuario", - "columns": [ - "usuario_id" - ], - "isUnique": false - } - }, - "foreignKeys": { - "sesion_usuario_id_usuario_id_fk": { - "name": "sesion_usuario_id_usuario_id_fk", - "tableFrom": "sesion", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "usuario": { - "name": "usuario", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "nombre": { - "name": "nombre", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "creado_en": { - "name": "creado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "ultimo_acceso_en": { - "name": "ultimo_acceso_en", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "usuario_email_unique": { - "name": "usuario_email_unique", - "columns": [ - "email" - ], - "isUnique": true - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "valoracion": { - "name": "valoracion", - "columns": { - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "cancion_slug": { - "name": "cancion_slug", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "puntuacion": { - "name": "puntuacion", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "creada_en": { - "name": "creada_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "actualizada_en": { - "name": "actualizada_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "idx_valoracion_cancion": { - "name": "idx_valoracion_cancion", - "columns": [ - "cancion_slug" - ], - "isUnique": false - } - }, - "foreignKeys": { - "valoracion_usuario_id_usuario_id_fk": { - "name": "valoracion_usuario_id_usuario_id_fk", - "tableFrom": "valoracion", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "valoracion_usuario_id_cancion_slug_pk": { - "columns": [ - "usuario_id", - "cancion_slug" - ], - "name": "valoracion_usuario_id_cancion_slug_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - } - }, - "views": {}, - "enums": {}, - "_meta": { - "schemas": {}, - "tables": {}, - "columns": {} - }, - "internal": { - "indexes": {} - } -} \ No newline at end of file diff --git a/drizzle/meta/0003_snapshot.json b/drizzle/meta/0003_snapshot.json deleted file mode 100644 index 44c47d2..0000000 --- a/drizzle/meta/0003_snapshot.json +++ /dev/null @@ -1,717 +0,0 @@ -{ - "version": "6", - "dialect": "sqlite", - "id": "49a154bc-fef2-4fec-9138-9a9d3ae97f42", - "prevId": "451fba36-e77b-45fd-894c-a02c708cdcbf", - "tables": { - "carrito": { - "name": "carrito", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "creado_en": { - "name": "creado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "actualizado_en": { - "name": "actualizado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "carrito_usuario": { - "name": "carrito_usuario", - "columns": [ - "usuario_id" - ], - "isUnique": false - } - }, - "foreignKeys": { - "carrito_usuario_id_usuario_id_fk": { - "name": "carrito_usuario_id_usuario_id_fk", - "tableFrom": "carrito", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "carrito_item": { - "name": "carrito_item", - "columns": { - "carrito_id": { - "name": "carrito_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "cancion_slug": { - "name": "cancion_slug", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "anadido_en": { - "name": "anadido_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "carrito_item_carrito_id_carrito_id_fk": { - "name": "carrito_item_carrito_id_carrito_id_fk", - "tableFrom": "carrito_item", - "tableTo": "carrito", - "columnsFrom": [ - "carrito_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "carrito_item_carrito_id_cancion_slug_pk": { - "columns": [ - "carrito_id", - "cancion_slug" - ], - "name": "carrito_item_carrito_id_cancion_slug_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "codigo_acceso": { - "name": "codigo_acceso", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "hash": { - "name": "hash", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expira_en": { - "name": "expira_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "intentos": { - "name": "intentos", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": 0 - }, - "usado_en": { - "name": "usado_en", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "creado_en": { - "name": "creado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "codigo_acceso_email": { - "name": "codigo_acceso_email", - "columns": [ - "email" - ], - "isUnique": false - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "compra": { - "name": "compra", - "columns": { - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "cancion_slug": { - "name": "cancion_slug", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "pedido_id": { - "name": "pedido_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "comprado_en": { - "name": "comprado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "compra_usuario_id_usuario_id_fk": { - "name": "compra_usuario_id_usuario_id_fk", - "tableFrom": "compra", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "compra_pedido_id_pedido_id_fk": { - "name": "compra_pedido_id_pedido_id_fk", - "tableFrom": "compra", - "tableTo": "pedido", - "columnsFrom": [ - "pedido_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "compra_usuario_id_cancion_slug_pk": { - "columns": [ - "usuario_id", - "cancion_slug" - ], - "name": "compra_usuario_id_cancion_slug_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "favorito": { - "name": "favorito", - "columns": { - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "cancion_slug": { - "name": "cancion_slug", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "marcado_en": { - "name": "marcado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "idx_favorito_usuario": { - "name": "idx_favorito_usuario", - "columns": [ - "usuario_id" - ], - "isUnique": false - } - }, - "foreignKeys": { - "favorito_usuario_id_usuario_id_fk": { - "name": "favorito_usuario_id_usuario_id_fk", - "tableFrom": "favorito", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "favorito_usuario_id_cancion_slug_pk": { - "columns": [ - "usuario_id", - "cancion_slug" - ], - "name": "favorito_usuario_id_cancion_slug_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "limite": { - "name": "limite", - "columns": { - "clave": { - "name": "clave", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "intentos": { - "name": "intentos", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expira_en": { - "name": "expira_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "limite_expira": { - "name": "limite_expira", - "columns": [ - "expira_en" - ], - "isUnique": false - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "pedido": { - "name": "pedido", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "sesion_pago_id": { - "name": "sesion_pago_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "estado": { - "name": "estado", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'pendiente'" - }, - "packs": { - "name": "packs", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "total_centimos": { - "name": "total_centimos", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "moneda": { - "name": "moneda", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'eur'" - }, - "creado_en": { - "name": "creado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "pagado_en": { - "name": "pagado_en", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "pedido_sesion_pago_id_unique": { - "name": "pedido_sesion_pago_id_unique", - "columns": [ - "sesion_pago_id" - ], - "isUnique": true - }, - "pedido_usuario": { - "name": "pedido_usuario", - "columns": [ - "usuario_id" - ], - "isUnique": false - } - }, - "foreignKeys": { - "pedido_usuario_id_usuario_id_fk": { - "name": "pedido_usuario_id_usuario_id_fk", - "tableFrom": "pedido", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "pedido_item": { - "name": "pedido_item", - "columns": { - "pedido_id": { - "name": "pedido_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "cancion_slug": { - "name": "cancion_slug", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "titulo": { - "name": "titulo", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "pedido_item_pedido_id_pedido_id_fk": { - "name": "pedido_item_pedido_id_pedido_id_fk", - "tableFrom": "pedido_item", - "tableTo": "pedido", - "columnsFrom": [ - "pedido_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "pedido_item_pedido_id_cancion_slug_pk": { - "columns": [ - "pedido_id", - "cancion_slug" - ], - "name": "pedido_item_pedido_id_cancion_slug_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "sesion": { - "name": "sesion", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expira_en": { - "name": "expira_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "creada_en": { - "name": "creada_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "sesion_usuario": { - "name": "sesion_usuario", - "columns": [ - "usuario_id" - ], - "isUnique": false - } - }, - "foreignKeys": { - "sesion_usuario_id_usuario_id_fk": { - "name": "sesion_usuario_id_usuario_id_fk", - "tableFrom": "sesion", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "usuario": { - "name": "usuario", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "nombre": { - "name": "nombre", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "creado_en": { - "name": "creado_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "ultimo_acceso_en": { - "name": "ultimo_acceso_en", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "usuario_email_unique": { - "name": "usuario_email_unique", - "columns": [ - "email" - ], - "isUnique": true - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "checkConstraints": {} - }, - "valoracion": { - "name": "valoracion", - "columns": { - "usuario_id": { - "name": "usuario_id", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "cancion_slug": { - "name": "cancion_slug", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "puntuacion": { - "name": "puntuacion", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "creada_en": { - "name": "creada_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "actualizada_en": { - "name": "actualizada_en", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "idx_valoracion_cancion": { - "name": "idx_valoracion_cancion", - "columns": [ - "cancion_slug" - ], - "isUnique": false - } - }, - "foreignKeys": { - "valoracion_usuario_id_usuario_id_fk": { - "name": "valoracion_usuario_id_usuario_id_fk", - "tableFrom": "valoracion", - "tableTo": "usuario", - "columnsFrom": [ - "usuario_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "valoracion_usuario_id_cancion_slug_pk": { - "columns": [ - "usuario_id", - "cancion_slug" - ], - "name": "valoracion_usuario_id_cancion_slug_pk" - } - }, - "uniqueConstraints": {}, - "checkConstraints": {} - } - }, - "views": {}, - "enums": {}, - "_meta": { - "schemas": {}, - "tables": {}, - "columns": {} - }, - "internal": { - "indexes": {} - } -} \ No newline at end of file diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index c6fbfcc..5f33e3c 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -1,33 +1,12 @@ { "version": "7", - "dialect": "sqlite", + "dialect": "postgresql", "entries": [ { "idx": 0, - "version": "6", - "when": 1788645291369, - "tag": "0000_good_magma", - "breakpoints": true - }, - { - "idx": 1, - "version": "6", - "when": 1788708006540, - "tag": "0001_ancient_goblin_queen", - "breakpoints": true - }, - { - "idx": 2, - "version": "6", - "when": 1788727806327, - "tag": "0002_common_jean_grey", - "breakpoints": true - }, - { - "idx": 3, - "version": "6", - "when": 1788730784535, - "tag": "0003_dark_mad_thinker", + "version": "7", + "when": 1788780351154, + "tag": "0000_aromatic_bug", "breakpoints": true } ] diff --git a/package-lock.json b/package-lock.json index 526e673..4db3120 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,23 +8,25 @@ "name": "senzapaura", "version": "0.0.1", "dependencies": { + "drizzle-orm": "^0.45.2", + "pg": "^8.23.0", "stripe": "^22.6.1" }, "devDependencies": { "@eslint/js": "^10.0.1", - "@libsql/client": "^0.17.3", "@playwright/test": "^1.60.0", "@sveltejs/adapter-node": "^5.5.4", "@sveltejs/kit": "^2.63.0", "@sveltejs/vite-plugin-svelte": "^7.1.2", "@types/node": "^22", + "@types/pg": "^8.23.1", "@vitest/browser-playwright": "^4.1.8", "drizzle-kit": "^0.31.10", - "drizzle-orm": "^0.45.2", "eslint": "^10.4.1", "eslint-config-prettier": "^10.1.8", "eslint-plugin-svelte": "^3.19.0", "globals": "^17.6.0", + "js-yaml": "^5.4.1", "mdsvex": "^0.12.7", "playwright": "^1.60.0", "prettier": "^3.8.3", @@ -1223,178 +1225,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@libsql/client": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@libsql/client/-/client-0.17.4.tgz", - "integrity": "sha512-lYayFWasDV78A+TjlEhr6ubb3odBV6OHjb+wdp8VQcyWWAEIjuwbCHaraEUS4m4yWoo0BvZo96It4VdzZRmRWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@libsql/core": "^0.17.4", - "@libsql/hrana-client": "^0.10.0", - "js-base64": "^3.7.5", - "libsql": "^0.5.28", - "promise-limit": "^2.7.0" - } - }, - "node_modules/@libsql/core": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@libsql/core/-/core-0.17.4.tgz", - "integrity": "sha512-LqF9gIvnJ38nmAH1y/ChizHqDO/MO1wLgA96XrraulEEbqXxLjleSH92YWTolbuJKgPUmGu4aJk9W3UnAcxLOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "js-base64": "^3.7.5" - } - }, - "node_modules/@libsql/darwin-arm64": { - "version": "0.5.29", - "resolved": "https://registry.npmjs.org/@libsql/darwin-arm64/-/darwin-arm64-0.5.29.tgz", - "integrity": "sha512-K+2RIB1OGFPYQbfay48GakLhqf3ArcbHqPFu7EZiaUcRgFcdw8RoltsMyvbj5ix2fY0HV3Q3Ioa/ByvQdaSM0A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@libsql/darwin-x64": { - "version": "0.5.29", - "resolved": "https://registry.npmjs.org/@libsql/darwin-x64/-/darwin-x64-0.5.29.tgz", - "integrity": "sha512-OtT+KFHsKFy1R5FVadr8FJ2Bb1mghtXTyJkxv0trocq7NuHntSki1eUbxpO5ezJesDvBlqFjnWaYYY516QNLhQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@libsql/hrana-client": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@libsql/hrana-client/-/hrana-client-0.10.0.tgz", - "integrity": "sha512-OoA4EMqRAC7kn7V2P6EQqRcpZf2W+AjsNIyCizBg339Tq/aMC7sRnzs3SklderhmQWAqEzvv8A2vhxVmWpkVvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@libsql/isomorphic-ws": "^0.1.5", - "js-base64": "^3.7.5" - } - }, - "node_modules/@libsql/isomorphic-ws": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@libsql/isomorphic-ws/-/isomorphic-ws-0.1.5.tgz", - "integrity": "sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/ws": "^8.5.4", - "ws": "^8.13.0" - } - }, - "node_modules/@libsql/linux-arm-gnueabihf": { - "version": "0.5.29", - "resolved": "https://registry.npmjs.org/@libsql/linux-arm-gnueabihf/-/linux-arm-gnueabihf-0.5.29.tgz", - "integrity": "sha512-CD4n4zj7SJTHso4nf5cuMoWoMSS7asn5hHygsDuhRl8jjjCTT3yE+xdUvI4J7zsyb53VO5ISh4cwwOtf6k2UhQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@libsql/linux-arm-musleabihf": { - "version": "0.5.29", - "resolved": "https://registry.npmjs.org/@libsql/linux-arm-musleabihf/-/linux-arm-musleabihf-0.5.29.tgz", - "integrity": "sha512-2Z9qBVpEJV7OeflzIR3+l5yAd4uTOLxklScYTwpZnkm2vDSGlC1PRlueLaufc4EFITkLKXK2MWBpexuNJfMVcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@libsql/linux-arm64-gnu": { - "version": "0.5.29", - "resolved": "https://registry.npmjs.org/@libsql/linux-arm64-gnu/-/linux-arm64-gnu-0.5.29.tgz", - "integrity": "sha512-gURBqaiXIGGwFNEaUj8Ldk7Hps4STtG+31aEidCk5evMMdtsdfL3HPCpvys+ZF/tkOs2MWlRWoSq7SOuCE9k3w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@libsql/linux-arm64-musl": { - "version": "0.5.29", - "resolved": "https://registry.npmjs.org/@libsql/linux-arm64-musl/-/linux-arm64-musl-0.5.29.tgz", - "integrity": "sha512-fwgYZ0H8mUkyVqXZHF3mT/92iIh1N94Owi/f66cPVNsk9BdGKq5gVpoKO+7UxaNzuEH1roJp2QEwsCZMvBLpqg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@libsql/linux-x64-gnu": { - "version": "0.5.29", - "resolved": "https://registry.npmjs.org/@libsql/linux-x64-gnu/-/linux-x64-gnu-0.5.29.tgz", - "integrity": "sha512-y14V0vY0nmMC6G0pHeJcEarcnGU2H6cm21ZceRkacWHvQAEhAG0latQkCtoS2njFOXiYIg+JYPfAoWKbi82rkg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@libsql/linux-x64-musl": { - "version": "0.5.29", - "resolved": "https://registry.npmjs.org/@libsql/linux-x64-musl/-/linux-x64-musl-0.5.29.tgz", - "integrity": "sha512-gquqwA/39tH4pFl+J9n3SOMSymjX+6kZ3kWgY3b94nXFTwac9bnFNMffIomgvlFaC4ArVqMnOZD3nuJ3H3VO1w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@libsql/win32-x64-msvc": { - "version": "0.5.29", - "resolved": "https://registry.npmjs.org/@libsql/win32-x64-msvc/-/win32-x64-msvc-0.5.29.tgz", - "integrity": "sha512-4/0CvEdhi6+KjMxMaVbFM2n2Z44escBRoEYpR+gZg64DdetzGnYm8mcNLcoySaDJZNaBd6wz5DNdgRmcI4hXcg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@napi-rs/lzma-linux-x64-gnu": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", @@ -1412,13 +1242,6 @@ "node": "^22.20 || ^24.12 || >=25" } }, - "node_modules/@neon-rs/load": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/@neon-rs/load/-/load-0.0.4.tgz", - "integrity": "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==", - "dev": true, - "license": "MIT" - }, "node_modules/@oxc-project/types": { "version": "0.148.0", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.148.0.tgz", @@ -2401,6 +2224,18 @@ "undici-types": "~6.21.0" } }, + "node_modules/@types/pg": { + "version": "8.23.1", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.23.1.tgz", + "integrity": "sha512-fKVHpikPdg4GKks3JuLEhvwSyvwzF23hnabPy6DD8ljVbC7+6J5dQzdv4arV6jqq57djnMgs1HKBxX4P8aBI3A==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", @@ -2415,16 +2250,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.69.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.69.0.tgz", @@ -2855,6 +2680,13 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/aria-query": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", @@ -3608,7 +3440,6 @@ "version": "0.45.2", "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.45.2.tgz", "integrity": "sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q==", - "dev": true, "license": "Apache-2.0", "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", @@ -4350,12 +4181,28 @@ "dev": true, "license": "ISC" }, - "node_modules/js-base64": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.9.3.tgz", - "integrity": "sha512-uwYQp+VJ38FVvtim6qNbit6e9uT6dwWQ4Y1+H9TxhW5hcHjpHwoxlR0nMpqUmIFOmu4VqMxwdJA88gIVuZJQ/g==", + "node_modules/js-yaml": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.1.tgz", + "integrity": "sha512-28R/k+NAjeuf7+CKlTxWZVExJGwVVLwY06DgEnOMz2gEpfNkDcD7QvyiVPT0xy0XXhU8vHsd4Ot42OOPdJG7dQ==", "dev": true, - "license": "BSD-3-Clause" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.mjs" + } }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -4412,49 +4259,6 @@ "node": ">= 0.8.0" } }, - "node_modules/libsql": { - "version": "0.5.29", - "resolved": "https://registry.npmjs.org/libsql/-/libsql-0.5.29.tgz", - "integrity": "sha512-8lMP8iMgiBzzoNbAPQ59qdVcj6UaE/Vnm+fiwX4doX4Narook0a4GPKWBEv+CR8a1OwbfkgL18uBfBjWdF0Fzg==", - "cpu": [ - "x64", - "arm64", - "wasm32", - "arm" - ], - "dev": true, - "license": "MIT", - "os": [ - "darwin", - "linux", - "win32" - ], - "dependencies": { - "@neon-rs/load": "^0.0.4", - "detect-libc": "2.0.2" - }, - "optionalDependencies": { - "@libsql/darwin-arm64": "0.5.29", - "@libsql/darwin-x64": "0.5.29", - "@libsql/linux-arm-gnueabihf": "0.5.29", - "@libsql/linux-arm-musleabihf": "0.5.29", - "@libsql/linux-arm64-gnu": "0.5.29", - "@libsql/linux-arm64-musl": "0.5.29", - "@libsql/linux-x64-gnu": "0.5.29", - "@libsql/linux-x64-musl": "0.5.29", - "@libsql/win32-x64-msvc": "0.5.29" - } - }, - "node_modules/libsql/node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, "node_modules/lightningcss": { "version": "1.33.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", @@ -5025,6 +4829,95 @@ "dev": true, "license": "MIT" }, + "node_modules/pg": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.23.0.tgz", + "integrity": "sha512-Ip2EQCngowJLGOfCwkFhPXU7/ljlhn6Rxlmy4XYfL2Y+vyRM59+8uR2xqRWKdYmbXmxCFOAmKxBuSUCdF34qLg==", + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.14.0", + "pg-pool": "^3.14.0", + "pg-protocol": "^1.16.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.4.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.4.0.tgz", + "integrity": "sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.14.0.tgz", + "integrity": "sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.14.0.tgz", + "integrity": "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.16.0.tgz", + "integrity": "sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -5221,6 +5114,45 @@ "node": ">=4" } }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5278,13 +5210,6 @@ "node": ">=6" } }, - "node_modules/promise-limit": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/promise-limit/-/promise-limit-2.7.0.tgz", - "integrity": "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==", - "dev": true, - "license": "ISC" - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -5566,6 +5491,15 @@ "source-map": "^0.6.0" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -6314,7 +6248,7 @@ "version": "8.21.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10.0.0" @@ -6332,6 +6266,15 @@ } } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index f5497d3..b84498a 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@sveltejs/kit": "^2.63.0", "@sveltejs/vite-plugin-svelte": "^7.1.2", "@types/node": "^22", + "@types/pg": "^8.23.1", "@vitest/browser-playwright": "^4.1.8", "drizzle-kit": "^0.31.10", "eslint": "^10.4.1", @@ -51,8 +52,8 @@ "vitest-browser-svelte": "^2.1.1" }, "dependencies": { - "@libsql/client": "^0.17.3", "drizzle-orm": "^0.45.2", + "pg": "^8.23.0", "stripe": "^22.6.1" } } diff --git a/src/lib/server/db/index.ts b/src/lib/server/db/index.ts index 662fc2d..943a4de 100644 --- a/src/lib/server/db/index.ts +++ b/src/lib/server/db/index.ts @@ -1,10 +1,25 @@ -import { drizzle } from 'drizzle-orm/libsql'; -import { createClient } from '@libsql/client'; +import { drizzle } from 'drizzle-orm/node-postgres'; +import pg from 'pg'; import * as schema from './schema'; import { env } from '$env/dynamic/private'; if (!env.DATABASE_URL) throw new Error('DATABASE_URL is not set'); -const client = createClient({ url: env.DATABASE_URL }); +/** + * Un pool, no una conexion suelta. + * + * El servidor atiende varias peticiones a la vez y cada una consulta lo suyo; + * con una sola conexion se pondrian en fila. El pool las reparte y reutiliza, + * que es lo que hace que abrir una pagina no espere a la anterior. + * + * `max` deliberadamente bajo: Postgres cobra caro cada conexion —cada una es un + * proceso— y este sitio no necesita mas. Subirlo sin medir suele empeorar. + */ +const pool = new pg.Pool({ + connectionString: env.DATABASE_URL, + max: 10, + idleTimeoutMillis: 30_000, + connectionTimeoutMillis: 10_000 +}); -export const db = drizzle(client, { schema }); +export const db = drizzle(pool, { schema }); diff --git a/src/lib/server/db/schema.ts b/src/lib/server/db/schema.ts index ad5896e..bc8bd5c 100644 --- a/src/lib/server/db/schema.ts +++ b/src/lib/server/db/schema.ts @@ -12,30 +12,40 @@ */ import { relations } from 'drizzle-orm'; -import { index, integer, primaryKey, sqliteTable, text } from 'drizzle-orm/sqlite-core'; +import { bigint, index, integer, pgTable, primaryKey, text, timestamp } from 'drizzle-orm/pg-core'; const id = () => text('id') .primaryKey() .$defaultFn(() => crypto.randomUUID()); -/** Marca de tiempo obligatoria que se rellena sola al insertar. */ +/** + * Marca de tiempo obligatoria que se rellena sola al insertar. + * + * Con zona horaria siempre: el servidor puede estar en una y quien mira en + * otra, y un instante sin zona es un instante que no se sabe cual es. Y en + * modo `date` porque el codigo trabaja con `Date`; el modo por defecto de + * Postgres en Drizzle devuelve cadenas. + */ const ahora = (columna: string) => - integer(columna, { mode: 'timestamp' }) + timestamp(columna, { withTimezone: true, mode: 'date' }) .notNull() .$defaultFn(() => new Date()); +/** Instante opcional, con el mismo criterio. */ +const instante = (columna: string) => timestamp(columna, { withTimezone: true, mode: 'date' }); + /* ------------------------------------------------------------------------- * Cuentas * ---------------------------------------------------------------------- */ -export const usuario = sqliteTable('usuario', { +export const usuario = pgTable('usuario', { id: id(), /** Siempre normalizado en minusculas y sin espacios. */ email: text('email').notNull().unique(), nombre: text('nombre'), creadoEn: ahora('creado_en'), - ultimoAccesoEn: integer('ultimo_acceso_en', { mode: 'timestamp' }) + ultimoAccesoEn: instante('ultimo_acceso_en') }); /** @@ -45,21 +55,21 @@ export const usuario = sqliteTable('usuario', { * entrar en una cuenta ajena. Es la misma razon por la que las sesiones * guardan el hash del token. */ -export const codigoAcceso = sqliteTable( +export const codigoAcceso = pgTable( 'codigo_acceso', { id: id(), email: text('email').notNull(), hash: text('hash').notNull(), - expiraEn: integer('expira_en', { mode: 'timestamp' }).notNull(), + expiraEn: instante('expira_en').notNull(), intentos: integer('intentos').notNull().default(0), - usadoEn: integer('usado_en', { mode: 'timestamp' }), + usadoEn: instante('usado_en'), creadoEn: ahora('creado_en') }, (t) => [index('codigo_acceso_email').on(t.email)] ); -export const sesion = sqliteTable( +export const sesion = pgTable( 'sesion', { /** Hash del token que viaja en la cookie. */ @@ -67,7 +77,7 @@ export const sesion = sqliteTable( usuarioId: text('usuario_id') .notNull() .references(() => usuario.id, { onDelete: 'cascade' }), - expiraEn: integer('expira_en', { mode: 'timestamp' }).notNull(), + expiraEn: instante('expira_en').notNull(), creadaEn: ahora('creada_en') }, (t) => [index('sesion_usuario').on(t.usuarioId)] @@ -83,14 +93,19 @@ export const sesion = sqliteTable( * * `expiraEn` va en milisegundos y no como fecha porque las ventanas son * aritmetica pura, y algunas duran menos de un minuto. + * + * Y va en `bigint`, no en `integer`: en SQLite un entero son ocho bytes, pero + * en Postgres son cuatro y el maximo se queda en 2.147.483.647. Un instante en + * milisegundos ronda el billon y siete, asi que en `integer` desbordaria y el + * limitador dejaria de limitar. */ -export const limite = sqliteTable( +export const limite = pgTable( 'limite', { /** Que se esta limitando: "acceso:ip:1.2.3.4", "acceso:correo:..." */ clave: text('clave').primaryKey(), intentos: integer('intentos').notNull(), - expiraEn: integer('expira_en').notNull() + expiraEn: bigint('expira_en', { mode: 'number' }).notNull() }, (t) => [index('limite_expira').on(t.expiraEn)] ); @@ -104,7 +119,7 @@ export const limite = sqliteTable( * entrado, identificado por una cookie, y al iniciar sesion se fusiona con el * del usuario. */ -export const carrito = sqliteTable( +export const carrito = pgTable( 'carrito', { id: id(), @@ -115,7 +130,7 @@ export const carrito = sqliteTable( (t) => [index('carrito_usuario').on(t.usuarioId)] ); -export const carritoItem = sqliteTable( +export const carritoItem = pgTable( 'carrito_item', { carritoId: text('carrito_id') @@ -131,7 +146,7 @@ export const carritoItem = sqliteTable( * Pedidos y compras * ---------------------------------------------------------------------- */ -export const pedido = sqliteTable( +export const pedido = pgTable( 'pedido', { id: id(), @@ -149,12 +164,12 @@ export const pedido = sqliteTable( totalCentimos: integer('total_centimos').notNull(), moneda: text('moneda').notNull().default('eur'), creadoEn: ahora('creado_en'), - pagadoEn: integer('pagado_en', { mode: 'timestamp' }) + pagadoEn: instante('pagado_en') }, (t) => [index('pedido_usuario').on(t.usuarioId)] ); -export const pedidoItem = sqliteTable( +export const pedidoItem = pgTable( 'pedido_item', { pedidoId: text('pedido_id') @@ -172,7 +187,7 @@ export const pedidoItem = sqliteTable( * proposito: responde a "puede esta persona descargar este tema" en una sola * consulta, sin recorrer pedidos. */ -export const compra = sqliteTable( +export const compra = pgTable( 'compra', { usuarioId: text('usuario_id') @@ -202,7 +217,7 @@ export const compra = sqliteTable( * duplica nada. El indice por cuenta es para pintar la lista, que es la * consulta que se hace de verdad. */ -export const favorito = sqliteTable( +export const favorito = pgTable( 'favorito', { usuarioId: text('usuario_id') @@ -231,7 +246,7 @@ export const favorito = sqliteTable( * El indice por `cancion_slug` es para la media: se calcula por tema, y sin el * habria que recorrer la tabla entera en cada ficha. */ -export const valoracion = sqliteTable( +export const valoracion = pgTable( 'valoracion', { usuarioId: text('usuario_id') diff --git a/src/lib/server/valoraciones.ts b/src/lib/server/valoraciones.ts index 0ab8b11..e5a70fc 100644 --- a/src/lib/server/valoraciones.ts +++ b/src/lib/server/valoraciones.ts @@ -50,10 +50,17 @@ export function aPuntuacion(valor: FormDataEntryValue | null): number | undefine /** Media y número de votos de un tema. */ export async function resumenDeCancion(cancionSlug: string): Promise { + /* + * Los moldes no son decoración. En Postgres `avg()` devuelve `numeric` y + * `count()` devuelve `bigint`, y el driver entrega las dos como **cadena** + * para no perder precisión. Sin convertirlas, `cuantas === 0` nunca se + * cumpliría —es `"0"`— y el singular de «1 voto» tampoco, porque `"1" === 1` + * es falso. Se convierten aquí, que es donde se sabe qué son. + */ const [fila] = await db .select({ - media: sql`avg(${valoracion.puntuacion})`, - cuantas: sql`count(*)` + media: sql`avg(${valoracion.puntuacion})::float8`, + cuantas: sql`count(*)::int` }) .from(valoracion) .where(eq(valoracion.cancionSlug, cancionSlug));