This commit is contained in:
@@ -3,5 +3,6 @@
|
||||
"imports": {
|
||||
"@openai/openai": "jsr:@openai/openai@^6.16.0",
|
||||
"@zod/zod": "jsr:@zod/zod@^4.3.5"
|
||||
"@david/dax": "jsr:@david/dax@^0.44.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
{
|
||||
"version": "5",
|
||||
"specifiers": {
|
||||
"jsr:@david/console-static-text@0.3": "0.3.0",
|
||||
"jsr:@david/dax@~0.44.2": "0.44.2",
|
||||
"jsr:@david/path@0.2": "0.2.0",
|
||||
"jsr:@david/which@~0.4.1": "0.4.1",
|
||||
"jsr:@openai/openai@*": "6.9.0",
|
||||
"jsr:@openai/openai@^6.16.0": "6.16.0",
|
||||
"jsr:@std/assert@1": "1.0.16",
|
||||
"jsr:@std/bytes@^1.0.5": "1.0.6",
|
||||
"jsr:@std/dotenv@*": "0.225.6",
|
||||
"jsr:@std/fmt@1": "1.0.9",
|
||||
"jsr:@std/fs@1": "1.0.22",
|
||||
"jsr:@std/fs@^1.0.20": "1.0.22",
|
||||
"jsr:@std/internal@^1.0.12": "1.0.12",
|
||||
"jsr:@std/io@0.225": "0.225.2",
|
||||
"jsr:@std/path@1": "1.1.4",
|
||||
"jsr:@std/path@^1.1.4": "1.1.4",
|
||||
"jsr:@supabase/functions-js@*": "2.90.1",
|
||||
"jsr:@zod/zod@^4.3.5": "4.3.5",
|
||||
"npm:@supabase/supabase-js@^2.90.1": "2.90.1",
|
||||
@@ -17,6 +28,31 @@
|
||||
"npm:zod@3": "3.25.76"
|
||||
},
|
||||
"jsr": {
|
||||
"@david/console-static-text@0.3.0": {
|
||||
"integrity": "2dfb46ecee525755f7989f94ece30bba85bd8ffe3e8666abc1bf926e1ee0698d"
|
||||
},
|
||||
"@david/dax@0.44.2": {
|
||||
"integrity": "26f5985f66a4340d55fb05ca90a0063bb5f0d670a326e14cb33a974aafcbb8d9",
|
||||
"dependencies": [
|
||||
"jsr:@david/console-static-text",
|
||||
"jsr:@david/path",
|
||||
"jsr:@david/which",
|
||||
"jsr:@std/fmt",
|
||||
"jsr:@std/fs@^1.0.20",
|
||||
"jsr:@std/io",
|
||||
"jsr:@std/path@1"
|
||||
]
|
||||
},
|
||||
"@david/path@0.2.0": {
|
||||
"integrity": "f2d7aa7f02ce5a55e27c09f9f1381794acb09d328f8d3c8a2e3ab3ffc294dccd",
|
||||
"dependencies": [
|
||||
"jsr:@std/fs@1",
|
||||
"jsr:@std/path@1"
|
||||
]
|
||||
},
|
||||
"@david/which@0.4.1": {
|
||||
"integrity": "896a682b111f92ab866cc70c5b4afab2f5899d2f9bde31ed00203b9c250f225e"
|
||||
},
|
||||
"@openai/openai@6.9.0": {
|
||||
"integrity": "d1828101f5a782a75c25805c4e06c1316d9c19f422d84755fb908046184c3ef6"
|
||||
},
|
||||
@@ -32,12 +68,37 @@
|
||||
"jsr:@std/internal"
|
||||
]
|
||||
},
|
||||
"@std/bytes@1.0.6": {
|
||||
"integrity": "f6ac6adbd8ccd99314045f5703e23af0a68d7f7e58364b47d2c7f408aeb5820a"
|
||||
},
|
||||
"@std/dotenv@0.225.6": {
|
||||
"integrity": "1d6f9db72f565bd26790fa034c26e45ecb260b5245417be76c2279e5734c421b"
|
||||
},
|
||||
"@std/fmt@1.0.9": {
|
||||
"integrity": "2487343e8899fb2be5d0e3d35013e54477ada198854e52dd05ed0422eddcabe0"
|
||||
},
|
||||
"@std/fs@1.0.22": {
|
||||
"integrity": "de0f277a58a867147a8a01bc1b181d0dfa80bfddba8c9cf2bacd6747bcec9308",
|
||||
"dependencies": [
|
||||
"jsr:@std/internal",
|
||||
"jsr:@std/path@^1.1.4"
|
||||
]
|
||||
},
|
||||
"@std/internal@1.0.12": {
|
||||
"integrity": "972a634fd5bc34b242024402972cd5143eac68d8dffaca5eaa4dba30ce17b027"
|
||||
},
|
||||
"@std/io@0.225.2": {
|
||||
"integrity": "3c740cd4ee4c082e6cfc86458f47e2ab7cb353dc6234d5e9b1f91a2de5f4d6c7",
|
||||
"dependencies": [
|
||||
"jsr:@std/bytes"
|
||||
]
|
||||
},
|
||||
"@std/path@1.1.4": {
|
||||
"integrity": "1d2d43f39efb1b42f0b1882a25486647cb851481862dc7313390b2bb044314b5",
|
||||
"dependencies": [
|
||||
"jsr:@std/internal"
|
||||
]
|
||||
},
|
||||
"@supabase/functions-js@2.90.1": {
|
||||
"integrity": "9a077ecf42aa84594ef3aac621d643e15ffaa9506a4c051e35c93f127ffdb035"
|
||||
},
|
||||
@@ -260,10 +321,6 @@
|
||||
"signal-exit@4.1.0": {
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="
|
||||
},
|
||||
"supabase-js@1.0.4": {
|
||||
"integrity": "sha512-b9Pxxl3ACEUhY/qTyF7WG9yUQTQQ/5Qm/0KnqbBOQdMaKi13glxs0SzqB1LSJnk2mZvufm6FF8Pyv5ZMc5YVqw==",
|
||||
"scripts": true
|
||||
},
|
||||
"supabase@2.72.6": {
|
||||
"integrity": "sha512-axO1MkZgwMIxj78vKiGosnuXwzOaQq0Kz0I8jheNMwJH9dKGf3q/arivYT44z8u3t5FjGUxQWOuQoJetzcmm/A==",
|
||||
"dependencies": [
|
||||
@@ -283,7 +340,8 @@
|
||||
"minipass",
|
||||
"minizlib",
|
||||
"yallist"
|
||||
]
|
||||
],
|
||||
"deprecated": true
|
||||
},
|
||||
"tslib@2.8.1": {
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||
@@ -315,6 +373,7 @@
|
||||
"dependencies": [
|
||||
"jsr:@openai/openai@^6.16.0",
|
||||
"jsr:@zod/zod@^4.3.5"
|
||||
"jsr:@david/dax@~0.44.2"
|
||||
],
|
||||
"packageJson": {
|
||||
"dependencies": [
|
||||
@@ -322,7 +381,6 @@
|
||||
"npm:@types/bun@^1.3.5",
|
||||
"npm:deno@^2.6.4",
|
||||
"npm:openai@^6.16.0",
|
||||
"npm:supabase-js@^1.0.4",
|
||||
"npm:supabase@^2.72.6"
|
||||
]
|
||||
}
|
||||
|
||||
Binary file not shown.
+1
-2
@@ -3,8 +3,7 @@
|
||||
"@supabase/supabase-js": "^2.90.1",
|
||||
"deno": "^2.6.4",
|
||||
"openai": "^6.16.0",
|
||||
"supabase": "^2.72.6",
|
||||
"supabase-js": "^1.0.4"
|
||||
"supabase": "^2.72.6"
|
||||
},
|
||||
"name": "genesis-2",
|
||||
"module": "index.ts",
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
|
||||
create table "public"."tabla_prueba" (
|
||||
"id" bigint generated by default as identity not null,
|
||||
"created_at" timestamp with time zone not null default now(),
|
||||
"columna_prueba" text
|
||||
);
|
||||
|
||||
|
||||
alter table "public"."tabla_prueba" enable row level security;
|
||||
|
||||
CREATE UNIQUE INDEX tabla_prueba_pkey ON public.tabla_prueba USING btree (id);
|
||||
|
||||
alter table "public"."tabla_prueba" add constraint "tabla_prueba_pkey" PRIMARY KEY using index "tabla_prueba_pkey";
|
||||
|
||||
set check_function_bodies = off;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.set_actualizado_en()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
new.actualizado_en = now();
|
||||
return new;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.unaccent_immutable(text)
|
||||
RETURNS text
|
||||
LANGUAGE sql
|
||||
IMMUTABLE PARALLEL SAFE STRICT
|
||||
AS $function$
|
||||
SELECT public.unaccent('public.unaccent', $1);
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.validar_numero_ciclo_asignatura()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
declare
|
||||
v_numero_ciclos int;
|
||||
begin
|
||||
if new.numero_ciclo is null then
|
||||
return new;
|
||||
end if;
|
||||
|
||||
select pe.numero_ciclos into v_numero_ciclos
|
||||
from planes_estudio pe
|
||||
where pe.id = new.plan_estudio_id;
|
||||
|
||||
if v_numero_ciclos is null then
|
||||
raise exception 'plan_estudio_id inválido %, plan no encontrado', new.plan_estudio_id;
|
||||
end if;
|
||||
|
||||
if new.numero_ciclo < 1 then
|
||||
raise exception 'numero_ciclo debe ser >= 1 (recibido %)', new.numero_ciclo;
|
||||
end if;
|
||||
|
||||
if new.numero_ciclo > v_numero_ciclos then
|
||||
raise exception 'numero_ciclo % excede planes_estudio.numero_ciclos % para plan_estudio_id %',
|
||||
new.numero_ciclo, v_numero_ciclos, new.plan_estudio_id;
|
||||
end if;
|
||||
|
||||
return new;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
grant delete on table "public"."tabla_prueba" to "anon";
|
||||
|
||||
grant insert on table "public"."tabla_prueba" to "anon";
|
||||
|
||||
grant references on table "public"."tabla_prueba" to "anon";
|
||||
|
||||
grant select on table "public"."tabla_prueba" to "anon";
|
||||
|
||||
grant trigger on table "public"."tabla_prueba" to "anon";
|
||||
|
||||
grant truncate on table "public"."tabla_prueba" to "anon";
|
||||
|
||||
grant update on table "public"."tabla_prueba" to "anon";
|
||||
|
||||
grant delete on table "public"."tabla_prueba" to "authenticated";
|
||||
|
||||
grant insert on table "public"."tabla_prueba" to "authenticated";
|
||||
|
||||
grant references on table "public"."tabla_prueba" to "authenticated";
|
||||
|
||||
grant select on table "public"."tabla_prueba" to "authenticated";
|
||||
|
||||
grant trigger on table "public"."tabla_prueba" to "authenticated";
|
||||
|
||||
grant truncate on table "public"."tabla_prueba" to "authenticated";
|
||||
|
||||
grant update on table "public"."tabla_prueba" to "authenticated";
|
||||
|
||||
grant delete on table "public"."tabla_prueba" to "postgres";
|
||||
|
||||
grant insert on table "public"."tabla_prueba" to "postgres";
|
||||
|
||||
grant references on table "public"."tabla_prueba" to "postgres";
|
||||
|
||||
grant select on table "public"."tabla_prueba" to "postgres";
|
||||
|
||||
grant trigger on table "public"."tabla_prueba" to "postgres";
|
||||
|
||||
grant truncate on table "public"."tabla_prueba" to "postgres";
|
||||
|
||||
grant update on table "public"."tabla_prueba" to "postgres";
|
||||
|
||||
grant delete on table "public"."tabla_prueba" to "service_role";
|
||||
|
||||
grant insert on table "public"."tabla_prueba" to "service_role";
|
||||
|
||||
grant references on table "public"."tabla_prueba" to "service_role";
|
||||
|
||||
grant select on table "public"."tabla_prueba" to "service_role";
|
||||
|
||||
grant trigger on table "public"."tabla_prueba" to "service_role";
|
||||
|
||||
grant truncate on table "public"."tabla_prueba" to "service_role";
|
||||
|
||||
grant update on table "public"."tabla_prueba" to "service_role";
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// scripts/db-diff.ts
|
||||
/* Uso:
|
||||
deno run -A scripts/sql_para_local_como_remoto.ts
|
||||
*/
|
||||
import { $ } from "@david/dax";
|
||||
|
||||
const OUT_FILE = "supabase/diffs/sql_para_remoto_como_local.sql";
|
||||
|
||||
console.log("🔍 Comparando base de datos local vs. remota...");
|
||||
|
||||
try {
|
||||
// 1. Ejecutamos el comando y capturamos la salida como texto
|
||||
// Esto evita que la terminal de Windows/Mac corrompa los acentos
|
||||
const output = await $`dx supabase db diff --linked`.text();
|
||||
|
||||
if (!output.trim()) {
|
||||
console.log(
|
||||
"✅ No hay diferencias. Tu base de datos local está sincronizada.",
|
||||
);
|
||||
} else {
|
||||
// 2. Escribimos el archivo usando Deno (UTF-8 garantizado)
|
||||
await Deno.writeTextFile(OUT_FILE, output);
|
||||
|
||||
console.log(`⚠️ Diferencias encontradas.`);
|
||||
console.log(`📄 Guardadas en: ${OUT_FILE}`);
|
||||
console.log(`👉 Abre ese archivo en VS Code para revisar los cambios.`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ Error al ejecutar db diff:", error);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// scripts/db-diff.ts
|
||||
/* Uso:
|
||||
deno run -A scripts/sql_para_remoto_como_local.ts
|
||||
*/
|
||||
import { $ } from "@david/dax";
|
||||
|
||||
const OUT_FILE = "supabase/diffs/sql_para_remoto_como_local.sql";
|
||||
|
||||
console.log("🔍 Comparando base de datos local vs. remota...");
|
||||
|
||||
try {
|
||||
// 1. Ejecutamos el comando y capturamos la salida como texto
|
||||
// Esto evita que la terminal de Windows/Mac corrompa los acentos
|
||||
const output = await $`dx supabase db diff`.text();
|
||||
|
||||
if (!output.trim()) {
|
||||
console.log(
|
||||
"✅ No hay diferencias. Tu base de datos local está sincronizada.",
|
||||
);
|
||||
} else {
|
||||
// 2. Escribimos el archivo usando Deno (UTF-8 garantizado)
|
||||
await Deno.writeTextFile(OUT_FILE, output);
|
||||
|
||||
console.log(`⚠️ Diferencias encontradas.`);
|
||||
console.log(`📄 Guardadas en: ${OUT_FILE}`);
|
||||
console.log(`👉 Abre ese archivo en VS Code para revisar los cambios.`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ Error al ejecutar db diff:", error);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
set check_function_bodies = off;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.set_actualizado_en()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
new.actualizado_en = now();
|
||||
return new;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.unaccent_immutable(text)
|
||||
RETURNS text
|
||||
LANGUAGE sql
|
||||
IMMUTABLE PARALLEL SAFE STRICT
|
||||
AS $function$
|
||||
SELECT public.unaccent('public.unaccent', $1);
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.validar_numero_ciclo_asignatura()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
declare
|
||||
v_numero_ciclos int;
|
||||
begin
|
||||
if new.numero_ciclo is null then
|
||||
return new;
|
||||
end if;
|
||||
|
||||
select pe.numero_ciclos into v_numero_ciclos
|
||||
from planes_estudio pe
|
||||
where pe.id = new.plan_estudio_id;
|
||||
|
||||
if v_numero_ciclos is null then
|
||||
raise exception 'plan_estudio_id inválido %, plan no encontrado', new.plan_estudio_id;
|
||||
end if;
|
||||
|
||||
if new.numero_ciclo < 1 then
|
||||
raise exception 'numero_ciclo debe ser >= 1 (recibido %)', new.numero_ciclo;
|
||||
end if;
|
||||
|
||||
if new.numero_ciclo > v_numero_ciclos then
|
||||
raise exception 'numero_ciclo % excede planes_estudio.numero_ciclos % para plan_estudio_id %',
|
||||
new.numero_ciclo, v_numero_ciclos, new.plan_estudio_id;
|
||||
end if;
|
||||
|
||||
return new;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
|
||||
@@ -19,12 +19,16 @@ type TipoCicloType =
|
||||
Database["public"]["Tables"]["planes_estudio"]["Insert"]["tipo_ciclo"];
|
||||
|
||||
Deno.serve(async (req) => {
|
||||
const url = new URL(req.url);
|
||||
const functionName = url.pathname.split("/").pop();
|
||||
console.log(
|
||||
`[${new Date().toISOString()}][${functionName}]: Request received`,
|
||||
);
|
||||
|
||||
if (req.method === "OPTIONS") {
|
||||
return new Response(null, { status: 204, headers: corsHeaders });
|
||||
}
|
||||
|
||||
const url = new URL(req.url);
|
||||
const functionName = url.pathname.split("/").pop();
|
||||
try {
|
||||
const method = req.method;
|
||||
if (method !== "POST") {
|
||||
@@ -143,7 +147,7 @@ Deno.serve(async (req) => {
|
||||
: {};
|
||||
|
||||
const aiStructuredPayload: StructuredResponseOptions = {
|
||||
model: "gpt-5-mini",
|
||||
model: "gpt-5-nano",
|
||||
input: [
|
||||
{ role: "system", content: systemPrompt },
|
||||
{ role: "user", content: userPrompt },
|
||||
@@ -241,6 +245,8 @@ Deno.serve(async (req) => {
|
||||
)
|
||||
.single();
|
||||
|
||||
// TODO: interaccion con IA y cambio de estado
|
||||
|
||||
if (planError) {
|
||||
throw new Error("Error inserting plan: " + planError.message);
|
||||
}
|
||||
@@ -251,6 +257,11 @@ Deno.serve(async (req) => {
|
||||
plan,
|
||||
};
|
||||
|
||||
console.log(
|
||||
`[${
|
||||
new Date().toISOString()
|
||||
}][${functionName}]: Request processed successfully`,
|
||||
);
|
||||
return new Response(
|
||||
JSON.stringify(jsonResponse),
|
||||
{
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
alter type "public"."tipo_cambio" rename to "tipo_cambio__old_version_to_be_dropped";
|
||||
|
||||
create type "public"."tipo_cambio" as enum ('ACTUALIZACION_CAMPO', 'ACTUALIZACION_MAPA', 'TRANSICION_ESTADO', 'OTRO', 'CREACION');
|
||||
|
||||
alter table "public"."cambios_asignatura" alter column tipo type "public"."tipo_cambio" using tipo::text::"public"."tipo_cambio";
|
||||
|
||||
alter table "public"."cambios_plan" alter column tipo type "public"."tipo_cambio" using tipo::text::"public"."tipo_cambio";
|
||||
|
||||
drop type "public"."tipo_cambio__old_version_to_be_dropped";
|
||||
|
||||
set check_function_bodies = off;
|
||||
|
||||
create or replace view "public"."plantilla_plan" as SELECT plan.id AS plan_estudio_id,
|
||||
struct.id AS estructura_id,
|
||||
struct.template_id
|
||||
FROM (public.planes_estudio plan
|
||||
JOIN public.estructuras_plan struct ON ((plan.estructura_id = struct.id)));
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.set_actualizado_en()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
new.actualizado_en = now();
|
||||
return new;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.unaccent_immutable(text)
|
||||
RETURNS text
|
||||
LANGUAGE sql
|
||||
IMMUTABLE PARALLEL SAFE STRICT
|
||||
AS $function$
|
||||
SELECT public.unaccent('public.unaccent', $1);
|
||||
$function$
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.validar_numero_ciclo_asignatura()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
declare
|
||||
v_numero_ciclos int;
|
||||
begin
|
||||
if new.numero_ciclo is null then
|
||||
return new;
|
||||
end if;
|
||||
|
||||
select pe.numero_ciclos into v_numero_ciclos
|
||||
from planes_estudio pe
|
||||
where pe.id = new.plan_estudio_id;
|
||||
|
||||
if v_numero_ciclos is null then
|
||||
raise exception 'plan_estudio_id inválido %, plan no encontrado', new.plan_estudio_id;
|
||||
end if;
|
||||
|
||||
if new.numero_ciclo < 1 then
|
||||
raise exception 'numero_ciclo debe ser >= 1 (recibido %)', new.numero_ciclo;
|
||||
end if;
|
||||
|
||||
if new.numero_ciclo > v_numero_ciclos then
|
||||
raise exception 'numero_ciclo % excede planes_estudio.numero_ciclos % para plan_estudio_id %',
|
||||
new.numero_ciclo, v_numero_ciclos, new.plan_estudio_id;
|
||||
end if;
|
||||
|
||||
return new;
|
||||
end;
|
||||
$function$
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user