feat: Introduce structured table definitions in convex/tables for various entities and remove the todos example table.

This commit is contained in:
2025-12-02 09:55:07 -03:00
parent 1c0bd219b2
commit 05e7f1181d
30 changed files with 2700 additions and 2535 deletions

View File

@@ -1,188 +1,190 @@
import { v } from "convex/values";
import { query, mutation } from "./_generated/server";
import { simboloTipo } from "./schema";
import { v } from 'convex/values';
import { query, mutation } from './_generated/server';
import { simboloTipo } from './tables/funcionarios';
export const getAll = query({
args: {},
returns: v.array(
v.object({
_id: v.id("simbolos"),
_creationTime: v.number(),
nome: v.string(),
tipo: simboloTipo,
descricao: v.string(),
vencValor: v.string(),
repValor: v.string(),
valor: v.string(),
})
),
handler: async (ctx) => {
return await ctx.db.query("simbolos").collect();
},
args: {},
returns: v.array(
v.object({
_id: v.id('simbolos'),
_creationTime: v.number(),
nome: v.string(),
tipo: simboloTipo,
descricao: v.string(),
vencValor: v.string(),
repValor: v.string(),
valor: v.string()
})
),
handler: async (ctx) => {
return await ctx.db.query('simbolos').collect();
}
});
export const getById = query({
args: {
id: v.id("simbolos"),
},
returns: v.union(
v.object({
_id: v.id("simbolos"),
_creationTime: v.number(),
nome: v.string(),
tipo: simboloTipo,
descricao: v.string(),
vencValor: v.string(),
repValor: v.string(),
valor: v.string(),
}),
v.null()
),
handler: async (ctx, args) => {
return await ctx.db.get(args.id);
},
args: {
id: v.id('simbolos')
},
returns: v.union(
v.object({
_id: v.id('simbolos'),
_creationTime: v.number(),
nome: v.string(),
tipo: simboloTipo,
descricao: v.string(),
vencValor: v.string(),
repValor: v.string(),
valor: v.string()
}),
v.null()
),
handler: async (ctx, args) => {
return await ctx.db.get(args.id);
}
});
export const create = mutation({
args: {
nome: v.string(),
tipo: simboloTipo,
refValor: v.string(),
vencValor: v.string(),
descricao: v.string(),
valor: v.optional(v.string()),
},
handler: async (ctx, args) => {
let refValor = args.refValor;
let vencValor = args.vencValor;
let valor = args.valor ?? "";
args: {
nome: v.string(),
tipo: simboloTipo,
refValor: v.string(),
vencValor: v.string(),
descricao: v.string(),
valor: v.optional(v.string())
},
handler: async (ctx, args) => {
let refValor = args.refValor;
let vencValor = args.vencValor;
let valor = args.valor ?? '';
if (args.tipo === "cargo_comissionado") {
if (!refValor || !vencValor) {
throw new Error(
"Valor de referência e valor de vencimento são obrigatórios para cargo comissionado"
);
}
valor = (Number(refValor) + Number(vencValor)).toFixed(2);
} else {
if (!args.valor) {
throw new Error("Valor é obrigatório para função gratificada");
}
refValor = "";
vencValor = "";
valor = args.valor;
}
const novoSimboloId = await ctx.db.insert("simbolos", {
nome: args.nome,
descricao: args.descricao,
repValor: refValor,
vencValor: vencValor,
tipo: args.tipo,
valor,
});
return await ctx.db.get(novoSimboloId);
},
if (args.tipo === 'cargo_comissionado') {
if (!refValor || !vencValor) {
throw new Error(
'Valor de referência e valor de vencimento são obrigatórios para cargo comissionado'
);
}
valor = (Number(refValor) + Number(vencValor)).toFixed(2);
} else {
if (!args.valor) {
throw new Error('Valor é obrigatório para função gratificada');
}
refValor = '';
vencValor = '';
valor = args.valor;
}
const novoSimboloId = await ctx.db.insert('simbolos', {
nome: args.nome,
descricao: args.descricao,
repValor: refValor,
vencValor: vencValor,
tipo: args.tipo,
valor
});
return await ctx.db.get(novoSimboloId);
}
});
export const remove = mutation({
args: {
id: v.id("simbolos"),
},
returns: v.null(),
handler: async (ctx, args) => {
await ctx.db.delete(args.id);
return null;
},
args: {
id: v.id('simbolos')
},
returns: v.null(),
handler: async (ctx, args) => {
await ctx.db.delete(args.id);
return null;
}
});
export const update = mutation({
args: {
id: v.id("simbolos"),
nome: v.string(),
tipo: simboloTipo,
refValor: v.string(),
vencValor: v.string(),
descricao: v.string(),
valor: v.optional(v.string()),
},
returns: v.null(),
handler: async (ctx, args) => {
let refValor = args.refValor;
let vencValor = args.vencValor;
let valor = args.valor ?? "";
args: {
id: v.id('simbolos'),
nome: v.string(),
tipo: simboloTipo,
refValor: v.string(),
vencValor: v.string(),
descricao: v.string(),
valor: v.optional(v.string())
},
returns: v.null(),
handler: async (ctx, args) => {
let refValor = args.refValor;
let vencValor = args.vencValor;
let valor = args.valor ?? '';
if (args.tipo === "cargo_comissionado") {
if (!refValor || !vencValor) {
throw new Error(
"Valor de referência e valor de vencimento são obrigatórios para cargo comissionado"
);
}
valor = (Number(refValor) + Number(vencValor)).toFixed(2);
} else {
if (!args.valor) {
throw new Error("Valor é obrigatório para função gratificada");
}
refValor = "";
vencValor = "";
valor = args.valor;
}
if (args.tipo === 'cargo_comissionado') {
if (!refValor || !vencValor) {
throw new Error(
'Valor de referência e valor de vencimento são obrigatórios para cargo comissionado'
);
}
valor = (Number(refValor) + Number(vencValor)).toFixed(2);
} else {
if (!args.valor) {
throw new Error('Valor é obrigatório para função gratificada');
}
refValor = '';
vencValor = '';
valor = args.valor;
}
await ctx.db.patch(args.id, {
nome: args.nome,
descricao: args.descricao,
repValor: refValor,
vencValor: vencValor,
tipo: args.tipo,
valor,
});
return null;
},
await ctx.db.patch(args.id, {
nome: args.nome,
descricao: args.descricao,
repValor: refValor,
vencValor: vencValor,
tipo: args.tipo,
valor
});
return null;
}
});
/**
* Remove símbolos duplicados, mantendo apenas a primeira ocorrência de cada símbolo
*/
export const removerDuplicados = mutation({
args: {},
returns: v.object({
removidos: v.number(),
mantidos: v.number(),
}),
handler: async (ctx) => {
const todosSimbolos = await ctx.db.query("simbolos").collect();
// Agrupar símbolos por nome
const simbolosPorNome = new Map<string, typeof todosSimbolos>();
for (const simbolo of todosSimbolos) {
const key = simbolo.nome.trim().toLowerCase();
if (!simbolosPorNome.has(key)) {
simbolosPorNome.set(key, []);
}
simbolosPorNome.get(key)!.push(simbolo);
}
let removidos = 0;
let mantidos = 0;
// Para cada grupo de símbolos com o mesmo nome
for (const [nome, simbolos] of simbolosPorNome) {
// Ordenar por _creationTime (mais antigo primeiro)
simbolos.sort((a, b) => a._creationTime - b._creationTime);
// Manter o primeiro (mais antigo) e remover os demais
const [primeiro, ...duplicados] = simbolos;
mantidos++;
// Remover duplicados
for (const duplicado of duplicados) {
await ctx.db.delete(duplicado._id);
removidos++;
}
}
console.log(`✅ Remoção concluída: ${mantidos} símbolos mantidos, ${removidos} duplicados removidos`);
return { removidos, mantidos };
},
});
args: {},
returns: v.object({
removidos: v.number(),
mantidos: v.number()
}),
handler: async (ctx) => {
const todosSimbolos = await ctx.db.query('simbolos').collect();
// Agrupar símbolos por nome
const simbolosPorNome = new Map<string, typeof todosSimbolos>();
for (const simbolo of todosSimbolos) {
const key = simbolo.nome.trim().toLowerCase();
if (!simbolosPorNome.has(key)) {
simbolosPorNome.set(key, []);
}
simbolosPorNome.get(key)!.push(simbolo);
}
let removidos = 0;
let mantidos = 0;
// Para cada grupo de símbolos com o mesmo nome
for (const [nome, simbolos] of simbolosPorNome) {
// Ordenar por _creationTime (mais antigo primeiro)
simbolos.sort((a, b) => a._creationTime - b._creationTime);
// Manter o primeiro (mais antigo) e remover os demais
const [primeiro, ...duplicados] = simbolos;
mantidos++;
// Remover duplicados
for (const duplicado of duplicados) {
await ctx.db.delete(duplicado._id);
removidos++;
}
}
console.log(
`✅ Remoção concluída: ${mantidos} símbolos mantidos, ${removidos} duplicados removidos`
);
return { removidos, mantidos };
}
});