@@ -2,6 +2,7 @@
|
|||||||
import { api } from '@sgse-app/backend/convex/_generated/api';
|
import { api } from '@sgse-app/backend/convex/_generated/api';
|
||||||
import { useConvexClient, useQuery } from 'convex-svelte';
|
import { useConvexClient, useQuery } from 'convex-svelte';
|
||||||
import type { FunctionReference } from 'convex/server';
|
import type { FunctionReference } from 'convex/server';
|
||||||
|
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
|
||||||
import {
|
import {
|
||||||
Home,
|
Home,
|
||||||
User,
|
User,
|
||||||
@@ -73,7 +74,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Estrutura do menu definida no frontend
|
// Estrutura do menu definida no frontend
|
||||||
const MENU_STRUCTURE: MenuItem[] = [
|
const MENU_STRUCTURE = [
|
||||||
{
|
{
|
||||||
label: 'Dashboard',
|
label: 'Dashboard',
|
||||||
icon: 'Home',
|
icon: 'Home',
|
||||||
@@ -83,12 +84,44 @@
|
|||||||
label: 'Gestão de Pessoas',
|
label: 'Gestão de Pessoas',
|
||||||
icon: 'Users',
|
icon: 'Users',
|
||||||
link: '/recursos-humanos',
|
link: '/recursos-humanos',
|
||||||
permission: { recurso: 'funcionarios', acao: 'ver' },
|
permission: { recurso: 'gestao_pessoas', acao: 'ver' },
|
||||||
submenus: [
|
submenus: [
|
||||||
{
|
{
|
||||||
label: 'Funcionários',
|
label: 'Funcionários',
|
||||||
link: '/recursos-humanos/funcionarios',
|
link: '/recursos-humanos/funcionarios',
|
||||||
permission: { recurso: 'funcionarios', acao: 'listar' }
|
permission: { recurso: 'funcionarios', acao: 'listar' },
|
||||||
|
exact: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Cadastro de Funcionários',
|
||||||
|
link: '/recursos-humanos/funcionarios/cadastro',
|
||||||
|
permission: { recurso: 'funcionarios', acao: 'criar' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Exclusão de Funcionários',
|
||||||
|
link: '/recursos-humanos/funcionarios/excluir',
|
||||||
|
permission: { recurso: 'funcionarios', acao: 'excluir' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Férias',
|
||||||
|
link: '/recursos-humanos/ferias',
|
||||||
|
permission: { recurso: 'ferias', acao: 'dashboard' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Atestados de Licenças',
|
||||||
|
link: '/recursos-humanos/atestados-licencas',
|
||||||
|
permission: { recurso: 'atestados_licencas', acao: 'listar' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Controle de Ponto',
|
||||||
|
link: '/recursos-humanos/controle-ponto',
|
||||||
|
permission: { recurso: 'ponto', acao: 'ver' },
|
||||||
|
exact: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Banco de Horas',
|
||||||
|
link: '/recursos-humanos/controle-ponto/banco-horas',
|
||||||
|
permission: { recurso: 'banco_horas', acao: 'ver' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Registro de Ponto',
|
label: 'Registro de Ponto',
|
||||||
@@ -129,25 +162,25 @@
|
|||||||
{
|
{
|
||||||
label: 'Objetos',
|
label: 'Objetos',
|
||||||
icon: 'Tag',
|
icon: 'Tag',
|
||||||
link: resolve('/compras/objetos'),
|
link: '/compras/objetos',
|
||||||
permission: { recurso: 'objetos', acao: 'listar' }
|
permission: { recurso: 'objetos', acao: 'listar' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Atas de Registro',
|
label: 'Atas de Registro',
|
||||||
icon: 'FileText',
|
icon: 'FileText',
|
||||||
link: resolve('/compras/atas'),
|
link: '/compras/atas',
|
||||||
permission: { recurso: 'atas', acao: 'listar' }
|
permission: { recurso: 'atas', acao: 'listar' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Contratos',
|
label: 'Contratos',
|
||||||
icon: 'FileText',
|
icon: 'FileText',
|
||||||
link: resolve('/licitacoes/contratos'),
|
link: '/licitacoes/contratos',
|
||||||
permission: { recurso: 'contratos', acao: 'listar' }
|
permission: { recurso: 'contratos', acao: 'listar' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Empresas',
|
label: 'Empresas',
|
||||||
icon: 'Briefcase',
|
icon: 'Briefcase',
|
||||||
link: resolve('/licitacoes/empresas'),
|
link: '/licitacoes/empresas',
|
||||||
permission: { recurso: 'empresas', acao: 'listar' }
|
permission: { recurso: 'empresas', acao: 'listar' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -174,7 +207,7 @@
|
|||||||
link: '/ti',
|
link: '/ti',
|
||||||
permission: { recurso: 'ti_painel_administrativo', acao: 'ver' }
|
permission: { recurso: 'ti_painel_administrativo', acao: 'ver' }
|
||||||
}
|
}
|
||||||
];
|
] as const satisfies readonly MenuItem[];
|
||||||
|
|
||||||
type IconType = typeof Home;
|
type IconType = typeof Home;
|
||||||
|
|
||||||
@@ -192,6 +225,20 @@
|
|||||||
const permissionsQuery = useQuery(api.menu.getUserPermissions as FunctionReference<'query'>, {});
|
const permissionsQuery = useQuery(api.menu.getUserPermissions as FunctionReference<'query'>, {});
|
||||||
|
|
||||||
// Filtrar menu baseado nas permissões do usuário
|
// Filtrar menu baseado nas permissões do usuário
|
||||||
|
function filterSubmenusByPermissions(
|
||||||
|
items: SubMenuItem[],
|
||||||
|
isMaster: boolean,
|
||||||
|
permissionsSet: Set<string>
|
||||||
|
): SubMenuItem[] {
|
||||||
|
if (isMaster) return items;
|
||||||
|
|
||||||
|
return items.filter((item) => {
|
||||||
|
if (!item.permission) return true;
|
||||||
|
const key = `${item.permission.recurso}.${item.permission.acao}`;
|
||||||
|
return permissionsSet.has(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function filterMenuByPermissions(
|
function filterMenuByPermissions(
|
||||||
items: MenuItem[],
|
items: MenuItem[],
|
||||||
isMaster: boolean,
|
isMaster: boolean,
|
||||||
@@ -199,30 +246,32 @@
|
|||||||
): MenuItem[] {
|
): MenuItem[] {
|
||||||
if (isMaster) return items;
|
if (isMaster) return items;
|
||||||
|
|
||||||
return items
|
const filtered: MenuItem[] = [];
|
||||||
.map((item) => {
|
|
||||||
// Verifica permissão do item atual
|
|
||||||
let hasPermission = true;
|
|
||||||
if (item.permission) {
|
|
||||||
const key = `${item.permission.recurso}.${item.permission.acao}`;
|
|
||||||
hasPermission = permissionsSet.has(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Se não tem permissão, não mostra
|
for (const item of items) {
|
||||||
if (!hasPermission) return null;
|
// Verifica permissão do item atual
|
||||||
|
let hasPermission = true;
|
||||||
|
if (item.permission) {
|
||||||
|
const key = `${item.permission.recurso}.${item.permission.acao}`;
|
||||||
|
hasPermission = permissionsSet.has(key);
|
||||||
|
}
|
||||||
|
|
||||||
// Se tiver submenus, filtra eles recursivamente
|
if (!hasPermission) continue;
|
||||||
let filteredSubmenus: MenuItem[] | undefined = undefined;
|
|
||||||
if (item.submenus) {
|
|
||||||
filteredSubmenus = filterMenuByPermissions(item.submenus, isMaster, permissionsSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
// Se tiver submenus, filtra e só mantém se sobrar algo
|
||||||
...item,
|
let filteredSubmenus: SubMenuItem[] | undefined = undefined;
|
||||||
submenus: filteredSubmenus && filteredSubmenus.length > 0 ? filteredSubmenus : undefined
|
if (item.submenus) {
|
||||||
};
|
const subs = filterSubmenusByPermissions(item.submenus, isMaster, permissionsSet);
|
||||||
})
|
filteredSubmenus = subs.length > 0 ? subs : undefined;
|
||||||
.filter((item): item is MenuItem => item !== null);
|
}
|
||||||
|
|
||||||
|
filtered.push({
|
||||||
|
...item,
|
||||||
|
submenus: filteredSubmenus
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Menu filtrado reativo
|
// Menu filtrado reativo
|
||||||
@@ -230,7 +279,7 @@
|
|||||||
const data = permissionsQuery.data;
|
const data = permissionsQuery.data;
|
||||||
if (!data) return [];
|
if (!data) return [];
|
||||||
|
|
||||||
const permissionsSet = new Set(data.permissions);
|
const permissionsSet = new Set((data.permissions ?? []) as string[]);
|
||||||
return filterMenuByPermissions(MENU_STRUCTURE, data.isMaster, permissionsSet);
|
return filterMenuByPermissions(MENU_STRUCTURE, data.isMaster, permissionsSet);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -438,7 +487,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Buscar o usuário no Convex usando getCurrentUser
|
// Buscar o usuário no Convex usando getCurrentUser
|
||||||
const usuario = await convexClient.query(api.auth.getCurrentUser, {});
|
// (o typesafe FunctionReference pode falhar aqui; tipamos o retorno e mantemos a chamada)
|
||||||
|
const usuario = (await convexClient.query(
|
||||||
|
api.auth.getCurrentUser as unknown as FunctionReference<'query'>,
|
||||||
|
{}
|
||||||
|
)) as { _id?: Id<'usuarios'> } | null;
|
||||||
|
|
||||||
if (usuario && usuario._id) {
|
if (usuario && usuario._id) {
|
||||||
await convexClient.mutation(api.logsLogin.registrarTentativaLogin, {
|
await convexClient.mutation(api.logsLogin.registrarTentativaLogin, {
|
||||||
|
|||||||
17
bun.lock
17
bun.lock
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
|
"configVersion": 0,
|
||||||
"workspaces": {
|
"workspaces": {
|
||||||
"": {
|
"": {
|
||||||
"name": "sgse-app",
|
"name": "sgse-app",
|
||||||
@@ -20,7 +21,7 @@
|
|||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
"prettier-plugin-tailwindcss": "^0.7.1",
|
"prettier-plugin-tailwindcss": "^0.7.1",
|
||||||
"svelte-dnd-action": "^0.9.67",
|
"svelte-dnd-action": "^0.9.67",
|
||||||
"turbo": "^2.5.8",
|
"turbo": "^2.6.3",
|
||||||
"typescript-eslint": "^8.46.3",
|
"typescript-eslint": "^8.46.3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1475,19 +1476,19 @@
|
|||||||
|
|
||||||
"tsyringe": ["tsyringe@4.10.0", "", { "dependencies": { "tslib": "^1.9.3" } }, "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw=="],
|
"tsyringe": ["tsyringe@4.10.0", "", { "dependencies": { "tslib": "^1.9.3" } }, "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw=="],
|
||||||
|
|
||||||
"turbo": ["turbo@2.5.8", "", { "optionalDependencies": { "turbo-darwin-64": "2.5.8", "turbo-darwin-arm64": "2.5.8", "turbo-linux-64": "2.5.8", "turbo-linux-arm64": "2.5.8", "turbo-windows-64": "2.5.8", "turbo-windows-arm64": "2.5.8" }, "bin": { "turbo": "bin/turbo" } }, "sha512-5c9Fdsr9qfpT3hA0EyYSFRZj1dVVsb6KIWubA9JBYZ/9ZEAijgUEae0BBR/Xl/wekt4w65/lYLTFaP3JmwSO8w=="],
|
"turbo": ["turbo@2.6.3", "", { "optionalDependencies": { "turbo-darwin-64": "2.6.3", "turbo-darwin-arm64": "2.6.3", "turbo-linux-64": "2.6.3", "turbo-linux-arm64": "2.6.3", "turbo-windows-64": "2.6.3", "turbo-windows-arm64": "2.6.3" }, "bin": { "turbo": "bin/turbo" } }, "sha512-bf6YKUv11l5Xfcmg76PyWoy/e2vbkkxFNBGJSnfdSXQC33ZiUfutYh6IXidc5MhsnrFkWfdNNLyaRk+kHMLlwA=="],
|
||||||
|
|
||||||
"turbo-darwin-64": ["turbo-darwin-64@2.5.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-Dh5bCACiHO8rUXZLpKw+m3FiHtAp2CkanSyJre+SInEvEr5kIxjGvCK/8MFX8SFRjQuhjtvpIvYYZJB4AGCxNQ=="],
|
"turbo-darwin-64": ["turbo-darwin-64@2.6.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-BlJJDc1CQ7SK5Y5qnl7AzpkvKSnpkfPmnA+HeU/sgny3oHZckPV2776ebO2M33CYDSor7+8HQwaodY++IINhYg=="],
|
||||||
|
|
||||||
"turbo-darwin-arm64": ["turbo-darwin-arm64@2.5.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-f1H/tQC9px7+hmXn6Kx/w8Jd/FneIUnvLlcI/7RGHunxfOkKJKvsoiNzySkoHQ8uq1pJnhJ0xNGTlYM48ZaJOQ=="],
|
"turbo-darwin-arm64": ["turbo-darwin-arm64@2.6.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-MwVt7rBKiOK7zdYerenfCRTypefw4kZCue35IJga9CH1+S50+KTiCkT6LBqo0hHeoH2iKuI0ldTF2a0aB72z3w=="],
|
||||||
|
|
||||||
"turbo-linux-64": ["turbo-linux-64@2.5.8", "", { "os": "linux", "cpu": "x64" }, "sha512-hMyvc7w7yadBlZBGl/bnR6O+dJTx3XkTeyTTH4zEjERO6ChEs0SrN8jTFj1lueNXKIHh1SnALmy6VctKMGnWfw=="],
|
"turbo-linux-64": ["turbo-linux-64@2.6.3", "", { "os": "linux", "cpu": "x64" }, "sha512-cqpcw+dXxbnPtNnzeeSyWprjmuFVpHJqKcs7Jym5oXlu/ZcovEASUIUZVN3OGEM6Y/OTyyw0z09tOHNt5yBAVg=="],
|
||||||
|
|
||||||
"turbo-linux-arm64": ["turbo-linux-arm64@2.5.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-LQELGa7bAqV2f+3rTMRPnj5G/OHAe2U+0N9BwsZvfMvHSUbsQ3bBMWdSQaYNicok7wOZcHjz2TkESn1hYK6xIQ=="],
|
"turbo-linux-arm64": ["turbo-linux-arm64@2.6.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-MterpZQmjXyr4uM7zOgFSFL3oRdNKeflY7nsjxJb2TklsYqiu3Z9pQ4zRVFFH8n0mLGna7MbQMZuKoWqqHb45w=="],
|
||||||
|
|
||||||
"turbo-windows-64": ["turbo-windows-64@2.5.8", "", { "os": "win32", "cpu": "x64" }, "sha512-3YdcaW34TrN1AWwqgYL9gUqmZsMT4T7g8Y5Azz+uwwEJW+4sgcJkIi9pYFyU4ZBSjBvkfuPZkGgfStir5BBDJQ=="],
|
"turbo-windows-64": ["turbo-windows-64@2.6.3", "", { "os": "win32", "cpu": "x64" }, "sha512-biDU70v9dLwnBdLf+daoDlNJVvqOOP8YEjqNipBHzgclbQlXbsi6Gqqelp5er81Qo3BiRgmTNx79oaZQTPb07Q=="],
|
||||||
|
|
||||||
"turbo-windows-arm64": ["turbo-windows-arm64@2.5.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-eFC5XzLmgXJfnAK3UMTmVECCwuBcORrWdewoiXBnUm934DY6QN8YowC/srhNnROMpaKaqNeRpoB5FxCww3eteQ=="],
|
"turbo-windows-arm64": ["turbo-windows-arm64@2.6.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-dDHVKpSeukah3VsI/xMEKeTnV9V9cjlpFSUs4bmsUiLu3Yv2ENlgVEZv65wxbeE0bh0jjpmElDT+P1KaCxArQQ=="],
|
||||||
|
|
||||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
"prettier-plugin-tailwindcss": "^0.7.1",
|
"prettier-plugin-tailwindcss": "^0.7.1",
|
||||||
"svelte-dnd-action": "^0.9.67",
|
"svelte-dnd-action": "^0.9.67",
|
||||||
"turbo": "^2.5.8",
|
"turbo": "^2.6.3",
|
||||||
"typescript-eslint": "^8.46.3"
|
"typescript-eslint": "^8.46.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
import { v } from 'convex/values';
|
import { v } from 'convex/values';
|
||||||
import { mutation, query } from './_generated/server';
|
import { mutation, query } from './_generated/server';
|
||||||
import { getCurrentUserFunction } from './auth';
|
import { getCurrentUserFunction } from './auth';
|
||||||
|
import { internal } from './_generated/api';
|
||||||
|
|
||||||
export const list = query({
|
export const list = query({
|
||||||
args: {},
|
args: {},
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'acoes',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
return await ctx.db.query('acoes').collect();
|
return await ctx.db.query('acoes').collect();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -15,6 +20,11 @@ export const create = mutation({
|
|||||||
tipo: v.union(v.literal('projeto'), v.literal('lei'))
|
tipo: v.union(v.literal('projeto'), v.literal('lei'))
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'acoes',
|
||||||
|
acao: 'criar'
|
||||||
|
});
|
||||||
|
|
||||||
const user = await getCurrentUserFunction(ctx);
|
const user = await getCurrentUserFunction(ctx);
|
||||||
if (!user) throw new Error('Unauthorized');
|
if (!user) throw new Error('Unauthorized');
|
||||||
|
|
||||||
@@ -33,6 +43,11 @@ export const update = mutation({
|
|||||||
tipo: v.union(v.literal('projeto'), v.literal('lei'))
|
tipo: v.union(v.literal('projeto'), v.literal('lei'))
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'acoes',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
|
|
||||||
const user = await getCurrentUserFunction(ctx);
|
const user = await getCurrentUserFunction(ctx);
|
||||||
if (!user) throw new Error('Unauthorized');
|
if (!user) throw new Error('Unauthorized');
|
||||||
|
|
||||||
@@ -48,6 +63,11 @@ export const remove = mutation({
|
|||||||
id: v.id('acoes')
|
id: v.id('acoes')
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'acoes',
|
||||||
|
acao: 'excluir'
|
||||||
|
});
|
||||||
|
|
||||||
const user = await getCurrentUserFunction(ctx);
|
const user = await getCurrentUserFunction(ctx);
|
||||||
if (!user) throw new Error('Unauthorized');
|
if (!user) throw new Error('Unauthorized');
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,15 @@ import { v } from 'convex/values';
|
|||||||
import { mutation, query } from './_generated/server';
|
import { mutation, query } from './_generated/server';
|
||||||
import type { Id } from './_generated/dataModel';
|
import type { Id } from './_generated/dataModel';
|
||||||
import { getCurrentUserFunction } from './auth';
|
import { getCurrentUserFunction } from './auth';
|
||||||
|
import { internal } from './_generated/api';
|
||||||
|
|
||||||
export const list = query({
|
export const list = query({
|
||||||
args: {},
|
args: {},
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atas',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
return await ctx.db.query('atas').collect();
|
return await ctx.db.query('atas').collect();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -13,6 +18,10 @@ export const list = query({
|
|||||||
export const get = query({
|
export const get = query({
|
||||||
args: { id: v.id('atas') },
|
args: { id: v.id('atas') },
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
return await ctx.db.get(args.id);
|
return await ctx.db.get(args.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -20,6 +29,10 @@ export const get = query({
|
|||||||
export const getObjetos = query({
|
export const getObjetos = query({
|
||||||
args: { id: v.id('atas') },
|
args: { id: v.id('atas') },
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
const links = await ctx.db
|
const links = await ctx.db
|
||||||
.query('atasObjetos')
|
.query('atasObjetos')
|
||||||
.withIndex('by_ataId', (q) => q.eq('ataId', args.id))
|
.withIndex('by_ataId', (q) => q.eq('ataId', args.id))
|
||||||
@@ -35,6 +48,10 @@ export const listByObjetoIds = query({
|
|||||||
objetoIds: v.array(v.id('objetos'))
|
objetoIds: v.array(v.id('objetos'))
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atas',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
if (args.objetoIds.length === 0) return [];
|
if (args.objetoIds.length === 0) return [];
|
||||||
|
|
||||||
// Buscar todos os vínculos ata-objeto para os objetos informados
|
// Buscar todos os vínculos ata-objeto para os objetos informados
|
||||||
@@ -66,6 +83,11 @@ export const create = mutation({
|
|||||||
objetosIds: v.array(v.id('objetos'))
|
objetosIds: v.array(v.id('objetos'))
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atas',
|
||||||
|
acao: 'criar'
|
||||||
|
});
|
||||||
|
|
||||||
const user = await getCurrentUserFunction(ctx);
|
const user = await getCurrentUserFunction(ctx);
|
||||||
if (!user) throw new Error('Unauthorized');
|
if (!user) throw new Error('Unauthorized');
|
||||||
|
|
||||||
@@ -103,6 +125,11 @@ export const update = mutation({
|
|||||||
objetosIds: v.array(v.id('objetos'))
|
objetosIds: v.array(v.id('objetos'))
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atas',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
|
|
||||||
const user = await getCurrentUserFunction(ctx);
|
const user = await getCurrentUserFunction(ctx);
|
||||||
if (!user) throw new Error('Unauthorized');
|
if (!user) throw new Error('Unauthorized');
|
||||||
|
|
||||||
@@ -139,6 +166,11 @@ export const update = mutation({
|
|||||||
export const remove = mutation({
|
export const remove = mutation({
|
||||||
args: { id: v.id('atas') },
|
args: { id: v.id('atas') },
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atas',
|
||||||
|
acao: 'excluir'
|
||||||
|
});
|
||||||
|
|
||||||
const user = await getCurrentUserFunction(ctx);
|
const user = await getCurrentUserFunction(ctx);
|
||||||
if (!user) throw new Error('Unauthorized');
|
if (!user) throw new Error('Unauthorized');
|
||||||
|
|
||||||
@@ -170,6 +202,10 @@ export const remove = mutation({
|
|||||||
export const generateUploadUrl = mutation({
|
export const generateUploadUrl = mutation({
|
||||||
args: {},
|
args: {},
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atas',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
return await ctx.storage.generateUploadUrl();
|
return await ctx.storage.generateUploadUrl();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -183,6 +219,11 @@ export const saveDocumento = mutation({
|
|||||||
tamanho: v.number()
|
tamanho: v.number()
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atas',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
|
|
||||||
const user = await getCurrentUserFunction(ctx);
|
const user = await getCurrentUserFunction(ctx);
|
||||||
if (!user) throw new Error('Unauthorized');
|
if (!user) throw new Error('Unauthorized');
|
||||||
|
|
||||||
@@ -201,6 +242,11 @@ export const saveDocumento = mutation({
|
|||||||
export const removeDocumento = mutation({
|
export const removeDocumento = mutation({
|
||||||
args: { id: v.id('atasDocumentos') },
|
args: { id: v.id('atasDocumentos') },
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atas',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
|
|
||||||
const user = await getCurrentUserFunction(ctx);
|
const user = await getCurrentUserFunction(ctx);
|
||||||
if (!user) throw new Error('Unauthorized');
|
if (!user) throw new Error('Unauthorized');
|
||||||
|
|
||||||
@@ -215,6 +261,11 @@ export const removeDocumento = mutation({
|
|||||||
export const getDocumentos = query({
|
export const getDocumentos = query({
|
||||||
args: { ataId: v.id('atas') },
|
args: { ataId: v.id('atas') },
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const docs = await ctx.db
|
const docs = await ctx.db
|
||||||
.query('atasDocumentos')
|
.query('atasDocumentos')
|
||||||
.withIndex('by_ataId', (q) => q.eq('ataId', args.ataId))
|
.withIndex('by_ataId', (q) => q.eq('ataId', args.ataId))
|
||||||
|
|||||||
@@ -147,6 +147,11 @@ export async function verificarLicencaAtiva(
|
|||||||
export const listarTodos = query({
|
export const listarTodos = query({
|
||||||
args: {},
|
args: {},
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [atestados, licencas] = await Promise.all([
|
const [atestados, licencas] = await Promise.all([
|
||||||
ctx.db.query('atestados').collect(),
|
ctx.db.query('atestados').collect(),
|
||||||
@@ -258,6 +263,11 @@ export const listarTodos = query({
|
|||||||
export const listarPorFuncionario = query({
|
export const listarPorFuncionario = query({
|
||||||
args: { funcionarioId: v.id('funcionarios') },
|
args: { funcionarioId: v.id('funcionarios') },
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
|
|
||||||
const [atestados, licencas] = await Promise.all([
|
const [atestados, licencas] = await Promise.all([
|
||||||
ctx.db
|
ctx.db
|
||||||
.query('atestados')
|
.query('atestados')
|
||||||
@@ -285,6 +295,11 @@ export const listarPorPeriodo = query({
|
|||||||
dataFim: v.string()
|
dataFim: v.string()
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
|
|
||||||
const dataInicioObj = new Date(args.dataInicio);
|
const dataInicioObj = new Date(args.dataInicio);
|
||||||
const dataFimObj = new Date(args.dataFim);
|
const dataFimObj = new Date(args.dataFim);
|
||||||
|
|
||||||
@@ -327,6 +342,10 @@ export const verificarStatusLicenca = query({
|
|||||||
},
|
},
|
||||||
returns: v.boolean(),
|
returns: v.boolean(),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
return await verificarLicencaAtiva(ctx, args.funcionarioId);
|
return await verificarLicencaAtiva(ctx, args.funcionarioId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -339,6 +358,11 @@ export const obterDadosGraficos = query({
|
|||||||
periodo: v.optional(v.number()) // dias (padrão: 30)
|
periodo: v.optional(v.number()) // dias (padrão: 30)
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'dashboard'
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const dias = args.periodo || 30;
|
const dias = args.periodo || 30;
|
||||||
const dataLimite = Date.now() - dias * 24 * 60 * 60 * 1000;
|
const dataLimite = Date.now() - dias * 24 * 60 * 60 * 1000;
|
||||||
@@ -588,6 +612,11 @@ export const obterDadosGraficos = query({
|
|||||||
export const obterEstatisticas = query({
|
export const obterEstatisticas = query({
|
||||||
args: {},
|
args: {},
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'dashboard'
|
||||||
|
});
|
||||||
|
|
||||||
const hoje = new Date();
|
const hoje = new Date();
|
||||||
hoje.setHours(0, 0, 0, 0);
|
hoje.setHours(0, 0, 0, 0);
|
||||||
const inicioMes = new Date(hoje.getFullYear(), hoje.getMonth(), 1);
|
const inicioMes = new Date(hoje.getFullYear(), hoje.getMonth(), 1);
|
||||||
@@ -657,6 +686,11 @@ export const obterEventosCalendario = query({
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'dashboard'
|
||||||
|
});
|
||||||
|
|
||||||
const eventos: Array<{
|
const eventos: Array<{
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
@@ -837,6 +871,11 @@ export const generateUploadUrl = mutation({
|
|||||||
args: {},
|
args: {},
|
||||||
returns: v.string(),
|
returns: v.string(),
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'criar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getUsuarioAutenticado(ctx);
|
const usuario = await getUsuarioAutenticado(ctx);
|
||||||
if (!usuario) throw new Error('Não autenticado');
|
if (!usuario) throw new Error('Não autenticado');
|
||||||
|
|
||||||
@@ -853,6 +892,11 @@ export const obterUrlDocumento = query({
|
|||||||
},
|
},
|
||||||
returns: v.union(v.string(), v.null()),
|
returns: v.union(v.string(), v.null()),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getUsuarioAutenticado(ctx);
|
const usuario = await getUsuarioAutenticado(ctx);
|
||||||
if (!usuario) throw new Error('Não autenticado');
|
if (!usuario) throw new Error('Não autenticado');
|
||||||
|
|
||||||
@@ -874,6 +918,11 @@ export const criarAtestadoMedico = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.id('atestados'),
|
returns: v.id('atestados'),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'criar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getUsuarioAutenticado(ctx);
|
const usuario = await getUsuarioAutenticado(ctx);
|
||||||
if (!usuario) throw new Error('Não autenticado');
|
if (!usuario) throw new Error('Não autenticado');
|
||||||
|
|
||||||
@@ -932,6 +981,11 @@ export const criarDeclaracaoComparecimento = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.id('atestados'),
|
returns: v.id('atestados'),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'criar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getUsuarioAutenticado(ctx);
|
const usuario = await getUsuarioAutenticado(ctx);
|
||||||
if (!usuario) throw new Error('Não autenticado');
|
if (!usuario) throw new Error('Não autenticado');
|
||||||
|
|
||||||
@@ -990,6 +1044,11 @@ export const criarLicencaMaternidade = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.id('licencas'),
|
returns: v.id('licencas'),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'criar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getUsuarioAutenticado(ctx);
|
const usuario = await getUsuarioAutenticado(ctx);
|
||||||
if (!usuario) throw new Error('Não autenticado');
|
if (!usuario) throw new Error('Não autenticado');
|
||||||
|
|
||||||
@@ -1054,6 +1113,11 @@ export const criarLicencaPaternidade = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.id('licencas'),
|
returns: v.id('licencas'),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'criar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getUsuarioAutenticado(ctx);
|
const usuario = await getUsuarioAutenticado(ctx);
|
||||||
if (!usuario) throw new Error('Não autenticado');
|
if (!usuario) throw new Error('Não autenticado');
|
||||||
|
|
||||||
@@ -1112,6 +1176,11 @@ export const prorrogarLicencaMaternidade = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.id('licencas'),
|
returns: v.id('licencas'),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getUsuarioAutenticado(ctx);
|
const usuario = await getUsuarioAutenticado(ctx);
|
||||||
if (!usuario) throw new Error('Não autenticado');
|
if (!usuario) throw new Error('Não autenticado');
|
||||||
|
|
||||||
@@ -1169,6 +1238,11 @@ export const excluirAtestado = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.null(),
|
returns: v.null(),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'excluir'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getUsuarioAutenticado(ctx);
|
const usuario = await getUsuarioAutenticado(ctx);
|
||||||
if (!usuario) throw new Error('Não autenticado');
|
if (!usuario) throw new Error('Não autenticado');
|
||||||
|
|
||||||
@@ -1215,6 +1289,11 @@ export const excluirLicenca = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.null(),
|
returns: v.null(),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'excluir'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getUsuarioAutenticado(ctx);
|
const usuario = await getUsuarioAutenticado(ctx);
|
||||||
if (!usuario) throw new Error('Não autenticado');
|
if (!usuario) throw new Error('Não autenticado');
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ import { getCurrentUserFunction } from './auth';
|
|||||||
export const listarTodas = query({
|
export const listarTodas = query({
|
||||||
args: {},
|
args: {},
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
|
|
||||||
const solicitacoes = await ctx.db.query('solicitacoesAusencias').collect();
|
const solicitacoes = await ctx.db.query('solicitacoesAusencias').collect();
|
||||||
|
|
||||||
const solicitacoesComDetalhes = await Promise.all(
|
const solicitacoesComDetalhes = await Promise.all(
|
||||||
@@ -65,6 +70,11 @@ export const listarMinhasSolicitacoes = query({
|
|||||||
_refresh: v.optional(v.number()) // Parâmetro para forçar atualização no frontend
|
_refresh: v.optional(v.number()) // Parâmetro para forçar atualização no frontend
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
|
|
||||||
const solicitacoes = await ctx.db
|
const solicitacoes = await ctx.db
|
||||||
.query('solicitacoesAusencias')
|
.query('solicitacoesAusencias')
|
||||||
.withIndex('by_funcionario', (q) => q.eq('funcionarioId', args.funcionarioId))
|
.withIndex('by_funcionario', (q) => q.eq('funcionarioId', args.funcionarioId))
|
||||||
@@ -104,6 +114,11 @@ export const listarMinhasSolicitacoes = query({
|
|||||||
export const listarSolicitacoesSubordinados = query({
|
export const listarSolicitacoesSubordinados = query({
|
||||||
args: { gestorId: v.id('usuarios') },
|
args: { gestorId: v.id('usuarios') },
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'aprovar'
|
||||||
|
});
|
||||||
|
|
||||||
// Buscar times onde o usuário é gestor
|
// Buscar times onde o usuário é gestor
|
||||||
const timesGestor = await ctx.db
|
const timesGestor = await ctx.db
|
||||||
.query('times')
|
.query('times')
|
||||||
@@ -170,6 +185,11 @@ export const listarSolicitacoesSubordinados = query({
|
|||||||
export const obterDetalhes = query({
|
export const obterDetalhes = query({
|
||||||
args: { solicitacaoId: v.id('solicitacoesAusencias') },
|
args: { solicitacaoId: v.id('solicitacoesAusencias') },
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
|
|
||||||
const solicitacao = await ctx.db.get(args.solicitacaoId);
|
const solicitacao = await ctx.db.get(args.solicitacaoId);
|
||||||
if (!solicitacao) return null;
|
if (!solicitacao) return null;
|
||||||
|
|
||||||
@@ -237,6 +257,11 @@ export const obterDetalhes = query({
|
|||||||
export const obterNotificacoesNaoLidas = query({
|
export const obterNotificacoesNaoLidas = query({
|
||||||
args: { usuarioId: v.id('usuarios') },
|
args: { usuarioId: v.id('usuarios') },
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
|
|
||||||
const notificacoes = await ctx.db
|
const notificacoes = await ctx.db
|
||||||
.query('notificacoesAusencias')
|
.query('notificacoesAusencias')
|
||||||
.withIndex('by_destinatario_and_lida', (q) =>
|
.withIndex('by_destinatario_and_lida', (q) =>
|
||||||
@@ -253,6 +278,11 @@ export const obterNotificacoesNaoLidas = query({
|
|||||||
export const contarPendentesGestor = query({
|
export const contarPendentesGestor = query({
|
||||||
args: { gestorId: v.id('usuarios') },
|
args: { gestorId: v.id('usuarios') },
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'aprovar'
|
||||||
|
});
|
||||||
|
|
||||||
// Buscar times onde o usuário é gestor
|
// Buscar times onde o usuário é gestor
|
||||||
const timesGestor = await ctx.db
|
const timesGestor = await ctx.db
|
||||||
.query('times')
|
.query('times')
|
||||||
@@ -359,6 +389,11 @@ export const criarSolicitacao = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.id('solicitacoesAusencias'),
|
returns: v.id('solicitacoesAusencias'),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'criar'
|
||||||
|
});
|
||||||
|
|
||||||
// Validações
|
// Validações
|
||||||
if (args.motivo.trim().length < 10) {
|
if (args.motivo.trim().length < 10) {
|
||||||
throw new Error('O motivo deve ter no mínimo 10 caracteres');
|
throw new Error('O motivo deve ter no mínimo 10 caracteres');
|
||||||
@@ -547,6 +582,11 @@ export const aprovar = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.null(),
|
returns: v.null(),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'aprovar'
|
||||||
|
});
|
||||||
|
|
||||||
const solicitacao = await ctx.db.get(args.solicitacaoId);
|
const solicitacao = await ctx.db.get(args.solicitacaoId);
|
||||||
if (!solicitacao) {
|
if (!solicitacao) {
|
||||||
throw new Error('Solicitação não encontrada');
|
throw new Error('Solicitação não encontrada');
|
||||||
@@ -710,6 +750,11 @@ export const reprovar = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.null(),
|
returns: v.null(),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'reprovar'
|
||||||
|
});
|
||||||
|
|
||||||
const solicitacao = await ctx.db.get(args.solicitacaoId);
|
const solicitacao = await ctx.db.get(args.solicitacaoId);
|
||||||
if (!solicitacao) {
|
if (!solicitacao) {
|
||||||
throw new Error('Solicitação não encontrada');
|
throw new Error('Solicitação não encontrada');
|
||||||
@@ -866,6 +911,11 @@ export const marcarComoLida = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.null(),
|
returns: v.null(),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
|
|
||||||
await ctx.db.patch(args.notificacaoId, {
|
await ctx.db.patch(args.notificacaoId, {
|
||||||
lida: true
|
lida: true
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -76,6 +76,11 @@ function agruparPorSolicitacao(registros: Array<Doc<'ferias'>>): Array<{
|
|||||||
export const listarTodas = query({
|
export const listarTodas = query({
|
||||||
args: {},
|
args: {},
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
|
|
||||||
const todasFerias = await ctx.db.query('ferias').collect();
|
const todasFerias = await ctx.db.query('ferias').collect();
|
||||||
|
|
||||||
const periodosComDetalhes = await Promise.all(
|
const periodosComDetalhes = await Promise.all(
|
||||||
@@ -146,6 +151,11 @@ export const listarMinhasSolicitacoes = query({
|
|||||||
_refresh: v.optional(v.number()) // Parâmetro para forçar atualização no frontend
|
_refresh: v.optional(v.number()) // Parâmetro para forçar atualização no frontend
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'dashboard'
|
||||||
|
});
|
||||||
|
|
||||||
const todasFerias = await ctx.db
|
const todasFerias = await ctx.db
|
||||||
.query('ferias')
|
.query('ferias')
|
||||||
.withIndex('by_funcionario', (q) => q.eq('funcionarioId', args.funcionarioId))
|
.withIndex('by_funcionario', (q) => q.eq('funcionarioId', args.funcionarioId))
|
||||||
@@ -180,6 +190,11 @@ export const listarMinhasSolicitacoes = query({
|
|||||||
export const listarSolicitacoesSubordinados = query({
|
export const listarSolicitacoesSubordinados = query({
|
||||||
args: { gestorId: v.id('usuarios') },
|
args: { gestorId: v.id('usuarios') },
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'dashboard'
|
||||||
|
});
|
||||||
|
|
||||||
// Buscar times onde o usuário é gestor
|
// Buscar times onde o usuário é gestor
|
||||||
const timesGestor = await ctx.db
|
const timesGestor = await ctx.db
|
||||||
.query('times')
|
.query('times')
|
||||||
@@ -259,6 +274,11 @@ export const obterDetalhes = query({
|
|||||||
feriasId: v.id('ferias')
|
feriasId: v.id('ferias')
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const ferias = await ctx.db.get(args.feriasId);
|
const ferias = await ctx.db.get(args.feriasId);
|
||||||
|
|
||||||
if (!ferias) return null;
|
if (!ferias) return null;
|
||||||
@@ -333,6 +353,11 @@ export const criarSolicitacao = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.array(v.id('ferias')),
|
returns: v.array(v.id('ferias')),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'criar'
|
||||||
|
});
|
||||||
|
|
||||||
if (args.periodos.length === 0) {
|
if (args.periodos.length === 0) {
|
||||||
throw new Error('É necessário adicionar pelo menos 1 período');
|
throw new Error('É necessário adicionar pelo menos 1 período');
|
||||||
}
|
}
|
||||||
@@ -394,6 +419,11 @@ export const aprovar = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.null(),
|
returns: v.null(),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'aprovar'
|
||||||
|
});
|
||||||
|
|
||||||
// Buscar o registro específico
|
// Buscar o registro específico
|
||||||
const registro = await ctx.db.get(args.feriasId);
|
const registro = await ctx.db.get(args.feriasId);
|
||||||
|
|
||||||
@@ -503,6 +533,11 @@ export const reprovar = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.null(),
|
returns: v.null(),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'reprovar'
|
||||||
|
});
|
||||||
|
|
||||||
// Buscar o registro específico
|
// Buscar o registro específico
|
||||||
const registro = await ctx.db.get(args.feriasId);
|
const registro = await ctx.db.get(args.feriasId);
|
||||||
|
|
||||||
@@ -565,6 +600,11 @@ export const ajustarEAprovar = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.null(),
|
returns: v.null(),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'aprovar'
|
||||||
|
});
|
||||||
|
|
||||||
// Buscar o registro específico
|
// Buscar o registro específico
|
||||||
const registroAntigo = await ctx.db.get(args.feriasId);
|
const registroAntigo = await ctx.db.get(args.feriasId);
|
||||||
|
|
||||||
@@ -676,6 +716,11 @@ export const verificarStatusFerias = query({
|
|||||||
args: { funcionarioId: v.id('funcionarios') },
|
args: { funcionarioId: v.id('funcionarios') },
|
||||||
returns: v.union(v.literal('ativo'), v.literal('em_ferias')),
|
returns: v.union(v.literal('ativo'), v.literal('em_ferias')),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const hoje = new Date();
|
const hoje = new Date();
|
||||||
hoje.setHours(0, 0, 0, 0);
|
hoje.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
@@ -721,6 +766,11 @@ export const verificarStatusFerias = query({
|
|||||||
export const obterNotificacoesNaoLidas = query({
|
export const obterNotificacoesNaoLidas = query({
|
||||||
args: { usuarioId: v.id('usuarios') },
|
args: { usuarioId: v.id('usuarios') },
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'dashboard'
|
||||||
|
});
|
||||||
|
|
||||||
return await ctx.db
|
return await ctx.db
|
||||||
.query('notificacoesFerias')
|
.query('notificacoesFerias')
|
||||||
.withIndex('by_destinatario_and_lida', (q) =>
|
.withIndex('by_destinatario_and_lida', (q) =>
|
||||||
@@ -735,6 +785,10 @@ export const marcarComoLida = mutation({
|
|||||||
args: { notificacaoId: v.id('notificacoesFerias') },
|
args: { notificacaoId: v.id('notificacoesFerias') },
|
||||||
returns: v.null(),
|
returns: v.null(),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'dashboard'
|
||||||
|
});
|
||||||
await ctx.db.patch(args.notificacaoId, { lida: true });
|
await ctx.db.patch(args.notificacaoId, { lida: true });
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -755,6 +809,11 @@ export const atualizarStatus = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.null(),
|
returns: v.null(),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'editar_status'
|
||||||
|
});
|
||||||
|
|
||||||
// Buscar o registro específico
|
// Buscar o registro específico
|
||||||
const registro = await ctx.db.get(args.feriasId);
|
const registro = await ctx.db.get(args.feriasId);
|
||||||
|
|
||||||
@@ -1184,6 +1243,11 @@ export const atualizarMeuStatus = mutation({
|
|||||||
args: {},
|
args: {},
|
||||||
returns: v.null(),
|
returns: v.null(),
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'atualizar_status'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario || !usuario.funcionarioId) {
|
if (!usuario || !usuario.funcionarioId) {
|
||||||
throw new Error('Usuário não encontrado ou não possui funcionário associado');
|
throw new Error('Usuário não encontrado ou não possui funcionário associado');
|
||||||
|
|||||||
@@ -8,15 +8,9 @@ const PERMISSOES_BASE = {
|
|||||||
permissoes: [
|
permissoes: [
|
||||||
// Funcionários
|
// Funcionários
|
||||||
{
|
{
|
||||||
nome: 'funcionarios.dashboard',
|
nome: 'funcionarios.detalhar',
|
||||||
recurso: 'funcionarios',
|
recurso: 'funcionarios',
|
||||||
acao: 'dashboard',
|
acao: 'detalhar',
|
||||||
descricao: 'Acessar o painel de funcionários'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
nome: 'funcionarios.ver',
|
|
||||||
recurso: 'funcionarios',
|
|
||||||
acao: 'ver',
|
|
||||||
descricao: 'Visualizar detalhes de funcionários'
|
descricao: 'Visualizar detalhes de funcionários'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -25,6 +19,12 @@ const PERMISSOES_BASE = {
|
|||||||
acao: 'listar',
|
acao: 'listar',
|
||||||
descricao: 'Listar funcionários'
|
descricao: 'Listar funcionários'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
nome: 'funcionarios.ver',
|
||||||
|
recurso: 'funcionarios',
|
||||||
|
acao: 'ver',
|
||||||
|
descricao: 'Visualizar dados completos de funcionários'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
nome: 'funcionarios.criar',
|
nome: 'funcionarios.criar',
|
||||||
recurso: 'funcionarios',
|
recurso: 'funcionarios',
|
||||||
@@ -50,11 +50,152 @@ const PERMISSOES_BASE = {
|
|||||||
descricao: 'Aprovar ausências de funcionários'
|
descricao: 'Aprovar ausências de funcionários'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
nome: 'funcionarios.aprovar_ferias',
|
nome: 'ferias.aprovar',
|
||||||
recurso: 'funcionarios',
|
recurso: 'ferias',
|
||||||
acao: 'aprovar_ferias',
|
acao: 'aprovar',
|
||||||
descricao: 'Aprovar férias de funcionários'
|
descricao: 'Aprovar férias de funcionários'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
nome: 'ferias.reprovar',
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'reprovar',
|
||||||
|
descricao: 'Reprovar férias de funcionários'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'ferias.dashboard',
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'dashboard',
|
||||||
|
descricao: 'Acessar o painel de férias de funcionários'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'ferias.listar',
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'listar',
|
||||||
|
descricao: 'Listar solicitações e períodos de férias'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'ferias.criar',
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'criar',
|
||||||
|
descricao: 'Criar solicitações de férias'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'ferias.editar_status',
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'editar_status',
|
||||||
|
descricao: 'Editar/cancelar status de solicitações de férias'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'ferias.atualizar_status',
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'atualizar_status',
|
||||||
|
descricao: 'Atualizar status automático de férias (administração)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'ferias.ver',
|
||||||
|
recurso: 'ferias',
|
||||||
|
acao: 'ver',
|
||||||
|
descricao: 'Visualizar detalhes de uma solicitação/período de férias'
|
||||||
|
},
|
||||||
|
// Atestados e Licenças
|
||||||
|
{
|
||||||
|
nome: 'atestados_licencas.listar',
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'listar',
|
||||||
|
descricao: 'Listar atestados e licenças'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'atestados_licencas.criar',
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'criar',
|
||||||
|
descricao: 'Registrar novos atestados ou licenças'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'atestados_licencas.editar',
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'editar',
|
||||||
|
descricao: 'Editar atestados ou licenças'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'atestados_licencas.excluir',
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'excluir',
|
||||||
|
descricao: 'Excluir atestados ou licenças'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'atestados_licencas.dashboard',
|
||||||
|
recurso: 'atestados_licencas',
|
||||||
|
acao: 'dashboard',
|
||||||
|
descricao: 'Acessar painel e gráficos de atestados e licenças'
|
||||||
|
},
|
||||||
|
// Ausências
|
||||||
|
{
|
||||||
|
nome: 'ausencias.listar',
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'listar',
|
||||||
|
descricao: 'Listar solicitações de ausência'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'ausencias.criar',
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'criar',
|
||||||
|
descricao: 'Criar solicitações de ausência'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'ausencias.aprovar',
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'aprovar',
|
||||||
|
descricao: 'Aprovar solicitações de ausência'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'ausencias.reprovar',
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'reprovar',
|
||||||
|
descricao: 'Reprovar solicitações de ausência'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'ausencias.excluir',
|
||||||
|
recurso: 'ausencias',
|
||||||
|
acao: 'excluir',
|
||||||
|
descricao: 'Excluir solicitações de ausência'
|
||||||
|
},
|
||||||
|
// Ponto e Banco de Horas
|
||||||
|
{
|
||||||
|
nome: 'ponto.ver',
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'ver',
|
||||||
|
descricao: 'Visualizar telas e relatórios de ponto'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'ponto.registrar',
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'registrar',
|
||||||
|
descricao: 'Registrar batidas de ponto'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'ponto.editar',
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'editar',
|
||||||
|
descricao: 'Editar registros de ponto (homologação)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'banco_horas.ver',
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ver',
|
||||||
|
descricao: 'Visualizar saldo e extrato de banco de horas'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'banco_horas.ajustar',
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ajustar',
|
||||||
|
descricao: 'Criar e aprovar ajustes de banco de horas'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
nome: 'banco_horas.configurar',
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'configurar',
|
||||||
|
descricao: 'Configurar regras e alertas de banco de horas'
|
||||||
|
},
|
||||||
// Símbolos
|
// Símbolos
|
||||||
{
|
{
|
||||||
nome: 'simbolos.dashboard',
|
nome: 'simbolos.dashboard',
|
||||||
|
|||||||
@@ -321,6 +321,11 @@ function validarAcelerometro(
|
|||||||
export const generateUploadUrl = mutation({
|
export const generateUploadUrl = mutation({
|
||||||
args: {},
|
args: {},
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'registrar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -543,6 +548,11 @@ export const registrarPonto = mutation({
|
|||||||
justificativa: v.optional(v.string())
|
justificativa: v.optional(v.string())
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'registrar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -921,6 +931,15 @@ export const listarRegistrosDia = query({
|
|||||||
_refresh: v.optional(v.number()) // Parâmetro usado pelo frontend para forçar refresh
|
_refresh: v.optional(v.number()) // Parâmetro usado pelo frontend para forçar refresh
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
try {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario || !usuario.funcionarioId) {
|
if (!usuario || !usuario.funcionarioId) {
|
||||||
return [];
|
return [];
|
||||||
@@ -967,6 +986,11 @@ export const obterSaldoDiario = query({
|
|||||||
data: v.string() // YYYY-MM-DD
|
data: v.string() // YYYY-MM-DD
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
// Buscar banco de horas do dia
|
// Buscar banco de horas do dia
|
||||||
const bancoHoras = await ctx.db
|
const bancoHoras = await ctx.db
|
||||||
.query('bancoHoras')
|
.query('bancoHoras')
|
||||||
@@ -1007,15 +1031,22 @@ export const listarRegistrosPeriodo = query({
|
|||||||
dataFim: v.string() // YYYY-MM-DD
|
dataFim: v.string() // YYYY-MM-DD
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
try {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
console.warn('[listarRegistrosPeriodo] Usuário não autenticado');
|
console.warn('[listarRegistrosPeriodo] Usuário não autenticado');
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar permissão (RH ou TI)
|
// Permissão já verificada acima (ponto.ver)
|
||||||
// Por enquanto, permitir se tiver funcionarioId ou for admin
|
|
||||||
// TODO: Implementar verificação de permissão adequada
|
|
||||||
|
|
||||||
// Validar formato das datas
|
// Validar formato das datas
|
||||||
if (!args.dataInicio || !args.dataFim) {
|
if (!args.dataInicio || !args.dataFim) {
|
||||||
@@ -1185,6 +1216,22 @@ export const obterEstatisticas = query({
|
|||||||
funcionarioId: v.optional(v.id('funcionarios'))
|
funcionarioId: v.optional(v.id('funcionarios'))
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
try {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
totalRegistros: 0,
|
||||||
|
dentroDoPrazo: 0,
|
||||||
|
foraDoPrazo: 0,
|
||||||
|
totalFuncionarios: 0,
|
||||||
|
funcionariosDentroPrazo: 0,
|
||||||
|
funcionariosForaPrazo: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
// Retornar estatísticas zeradas quando não autenticado
|
// Retornar estatísticas zeradas quando não autenticado
|
||||||
@@ -1198,7 +1245,7 @@ export const obterEstatisticas = query({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Verificar permissão (RH ou TI)
|
// Permissão já verificada acima (ponto.ver)
|
||||||
|
|
||||||
let registros = await ctx.db
|
let registros = await ctx.db
|
||||||
.query('registrosPonto')
|
.query('registrosPonto')
|
||||||
@@ -1245,6 +1292,11 @@ export const obterRegistro = query({
|
|||||||
registroId: v.id('registrosPonto')
|
registroId: v.id('registrosPonto')
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -1255,11 +1307,7 @@ export const obterRegistro = query({
|
|||||||
throw new Error('Registro não encontrado');
|
throw new Error('Registro não encontrado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar se o usuário tem permissão (próprio registro ou RH/TI)
|
// Permissão já verificada acima (ponto.ver)
|
||||||
if (registro.funcionarioId !== usuario.funcionarioId) {
|
|
||||||
// TODO: Verificar se é RH ou TI
|
|
||||||
// Por enquanto, permitir
|
|
||||||
}
|
|
||||||
|
|
||||||
const funcionario = await ctx.db.get(registro.funcionarioId);
|
const funcionario = await ctx.db.get(registro.funcionarioId);
|
||||||
let simbolo = null;
|
let simbolo = null;
|
||||||
@@ -1813,6 +1861,20 @@ export const obterHistoricoESaldoDia = query({
|
|||||||
_refresh: v.optional(v.number()) // Parâmetro usado pelo frontend para forçar refresh
|
_refresh: v.optional(v.number()) // Parâmetro usado pelo frontend para forçar refresh
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
try {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
registros: [],
|
||||||
|
cargaHorariaDiaria: 0,
|
||||||
|
horasTrabalhadas: 0,
|
||||||
|
saldoMinutos: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario || !usuario.funcionarioId) {
|
if (!usuario || !usuario.funcionarioId) {
|
||||||
console.warn('[obterHistoricoESaldoDia] Usuário não autenticado ou sem funcionarioId');
|
console.warn('[obterHistoricoESaldoDia] Usuário não autenticado ou sem funcionarioId');
|
||||||
@@ -1825,10 +1887,7 @@ export const obterHistoricoESaldoDia = query({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar se é o próprio funcionário ou tem permissão
|
// Permissão já verificada acima (ponto.ver)
|
||||||
if (usuario.funcionarioId !== args.funcionarioId) {
|
|
||||||
// TODO: Verificar permissão de RH
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buscar registros do dia
|
// Buscar registros do dia
|
||||||
const registros = await ctx.db
|
const registros = await ctx.db
|
||||||
@@ -1890,15 +1949,17 @@ export const obterBancoHorasFuncionario = query({
|
|||||||
funcionarioId: v.id('funcionarios')
|
funcionarioId: v.id('funcionarios')
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar se é o próprio funcionário ou tem permissão
|
// Permissão já verificada acima (banco_horas.ver)
|
||||||
if (usuario.funcionarioId !== args.funcionarioId) {
|
|
||||||
// TODO: Verificar permissão de RH
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buscar todos os registros de banco de horas do funcionário
|
// Buscar todos os registros de banco de horas do funcionário
|
||||||
const bancosHoras = await ctx.db
|
const bancosHoras = await ctx.db
|
||||||
@@ -2056,15 +2117,17 @@ export const obterBancoHorasMensal = query({
|
|||||||
mes: v.string() // YYYY-MM
|
mes: v.string() // YYYY-MM
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar se é o próprio funcionário ou tem permissão
|
// Permissão já verificada acima (banco_horas.ver)
|
||||||
if (usuario.funcionarioId !== args.funcionarioId) {
|
|
||||||
// TODO: Verificar permissão de RH
|
|
||||||
}
|
|
||||||
|
|
||||||
const bancoMensal = await ctx.db
|
const bancoMensal = await ctx.db
|
||||||
.query('bancoHorasMensal')
|
.query('bancoHorasMensal')
|
||||||
@@ -2119,15 +2182,17 @@ export const listarHistoricoMensal = query({
|
|||||||
mesFim: v.optional(v.string()) // YYYY-MM
|
mesFim: v.optional(v.string()) // YYYY-MM
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar se é o próprio funcionário ou tem permissão
|
// Permissão já verificada acima (banco_horas.ver)
|
||||||
if (usuario.funcionarioId !== args.funcionarioId) {
|
|
||||||
// TODO: Verificar permissão de RH
|
|
||||||
}
|
|
||||||
|
|
||||||
let query = ctx.db
|
let query = ctx.db
|
||||||
.query('bancoHorasMensal')
|
.query('bancoHorasMensal')
|
||||||
@@ -2242,15 +2307,17 @@ export const verificarAlertasBancoHoras = query({
|
|||||||
funcionarioId: v.id('funcionarios')
|
funcionarioId: v.id('funcionarios')
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar se é o próprio funcionário ou tem permissão
|
// Permissão já verificada acima (banco_horas.ver)
|
||||||
if (usuario.funcionarioId !== args.funcionarioId) {
|
|
||||||
// TODO: Verificar permissão de RH
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buscar banco de horas mensal mais recente
|
// Buscar banco de horas mensal mais recente
|
||||||
const hoje = new Date();
|
const hoje = new Date();
|
||||||
@@ -2356,6 +2423,11 @@ export const editarRegistroPonto = mutation({
|
|||||||
observacoes: v.optional(v.string())
|
observacoes: v.optional(v.string())
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -2441,6 +2513,11 @@ export const ajustarBancoHoras = mutation({
|
|||||||
ajusteMinutos: v.number()
|
ajusteMinutos: v.number()
|
||||||
}),
|
}),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ajustar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -2564,6 +2641,11 @@ export const listarHomologacoes = query({
|
|||||||
funcionarioId: v.optional(v.id('funcionarios'))
|
funcionarioId: v.optional(v.id('funcionarios'))
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -2650,6 +2732,11 @@ export const excluirHomologacao = mutation({
|
|||||||
homologacaoId: v.id('homologacoesPonto')
|
homologacaoId: v.id('homologacoesPonto')
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -2694,6 +2781,11 @@ export const excluirHomologacao = mutation({
|
|||||||
export const obterMotivosAtestados = query({
|
export const obterMotivosAtestados = query({
|
||||||
args: {},
|
args: {},
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
|
|
||||||
// Buscar tipos de atestados e declarações
|
// Buscar tipos de atestados e declarações
|
||||||
const atestados = await ctx.db.query('atestados').collect();
|
const atestados = await ctx.db.query('atestados').collect();
|
||||||
const tiposUnicos = new Set<string>();
|
const tiposUnicos = new Set<string>();
|
||||||
@@ -2733,6 +2825,11 @@ export const criarDispensaRegistro = mutation({
|
|||||||
isento: v.boolean()
|
isento: v.boolean()
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -2780,6 +2877,11 @@ export const removerDispensaRegistro = mutation({
|
|||||||
dispensaId: v.id('dispensasRegistro')
|
dispensaId: v.id('dispensasRegistro')
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -2814,6 +2916,11 @@ export const listarDispensas = query({
|
|||||||
apenasAtivas: v.optional(v.boolean())
|
apenasAtivas: v.optional(v.boolean())
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -2917,12 +3024,17 @@ export const obterEstatisticasBancoHorasGerencial = query({
|
|||||||
funcionarioId: v.optional(v.id('funcionarios'))
|
funcionarioId: v.optional(v.id('funcionarios'))
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Verificar permissão de RH/TI
|
// Permissão já verificada acima (banco_horas.ver)
|
||||||
|
|
||||||
// Buscar todos os bancos de horas do mês
|
// Buscar todos os bancos de horas do mês
|
||||||
let bancosMensais = await ctx.db
|
let bancosMensais = await ctx.db
|
||||||
@@ -2997,15 +3109,17 @@ export const listarHistoricoAlteracoesBancoHoras = query({
|
|||||||
mes: v.optional(v.string()) // YYYY-MM - se fornecido, filtra por mês
|
mes: v.optional(v.string()) // YYYY-MM - se fornecido, filtra por mês
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar se é o próprio funcionário ou tem permissão
|
// Permissão já verificada acima (banco_horas.ver)
|
||||||
if (usuario.funcionarioId !== args.funcionarioId) {
|
|
||||||
// TODO: Verificar permissão de RH
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buscar homologações do funcionário
|
// Buscar homologações do funcionário
|
||||||
let homologacoes = await ctx.db
|
let homologacoes = await ctx.db
|
||||||
@@ -3089,6 +3203,11 @@ export const verificarDispensaAtiva = query({
|
|||||||
minuto: v.optional(v.number())
|
minuto: v.optional(v.number())
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'ponto',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const dispensas = await ctx.db
|
const dispensas = await ctx.db
|
||||||
.query('dispensasRegistro')
|
.query('dispensasRegistro')
|
||||||
.withIndex('by_funcionario', (q) => q.eq('funcionarioId', args.funcionarioId))
|
.withIndex('by_funcionario', (q) => q.eq('funcionarioId', args.funcionarioId))
|
||||||
@@ -3217,15 +3336,17 @@ export const obterBancoHorasCompleto = query({
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar se é o próprio funcionário ou tem permissão
|
// Permissão já verificada acima (banco_horas.ver)
|
||||||
if (usuario.funcionarioId !== args.funcionarioId) {
|
|
||||||
// TODO: Verificar permissão de RH
|
|
||||||
}
|
|
||||||
|
|
||||||
const bancoHoras = await ctx.db
|
const bancoHoras = await ctx.db
|
||||||
.query('bancoHoras')
|
.query('bancoHoras')
|
||||||
@@ -3314,15 +3435,17 @@ export const listarAjustesBancoHoras = query({
|
|||||||
})
|
})
|
||||||
),
|
),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar se é o próprio funcionário ou tem permissão
|
// Permissão já verificada acima (banco_horas.ver)
|
||||||
if (usuario.funcionarioId !== args.funcionarioId) {
|
|
||||||
// TODO: Verificar permissão de RH
|
|
||||||
}
|
|
||||||
|
|
||||||
let query = ctx.db
|
let query = ctx.db
|
||||||
.query('ajustesBancoHoras')
|
.query('ajustesBancoHoras')
|
||||||
@@ -3402,6 +3525,11 @@ export const listarInconsistenciasBancoHoras = query({
|
|||||||
})
|
})
|
||||||
),
|
),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -3492,12 +3620,17 @@ export const obterConfiguracaoBancoHoras = query({
|
|||||||
v.null()
|
v.null()
|
||||||
),
|
),
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'configurar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Verificar permissão de TI
|
// Permissão já verificada acima (banco_horas.configurar)
|
||||||
|
|
||||||
const config = await ctx.db.query('configuracaoBancoHoras').order('desc').first();
|
const config = await ctx.db.query('configuracaoBancoHoras').order('desc').first();
|
||||||
|
|
||||||
@@ -3540,12 +3673,17 @@ export const obterAlertasConfigurados = query({
|
|||||||
})
|
})
|
||||||
),
|
),
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'configurar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Verificar permissão de TI
|
// Permissão já verificada acima (banco_horas.configurar)
|
||||||
|
|
||||||
// Retornar todos os alertas (ativos e inativos) para permitir edição
|
// Retornar todos os alertas (ativos e inativos) para permitir edição
|
||||||
const alertas = await ctx.db.query('alertasBancoHoras').collect();
|
const alertas = await ctx.db.query('alertasBancoHoras').collect();
|
||||||
@@ -3591,15 +3729,17 @@ export const verificarInconsistencias = query({
|
|||||||
})
|
})
|
||||||
),
|
),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verificar se é o próprio funcionário ou tem permissão
|
// Permissão já verificada acima (banco_horas.ver)
|
||||||
if (usuario.funcionarioId !== args.funcionarioId) {
|
|
||||||
// TODO: Verificar permissão de RH
|
|
||||||
}
|
|
||||||
|
|
||||||
let query = ctx.db
|
let query = ctx.db
|
||||||
.query('inconsistenciasBancoHoras')
|
.query('inconsistenciasBancoHoras')
|
||||||
@@ -3650,6 +3790,11 @@ export const criarAjusteBancoHoras = mutation({
|
|||||||
success: v.boolean()
|
success: v.boolean()
|
||||||
}),
|
}),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ajustar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -3745,6 +3890,11 @@ export const resolverInconsistencia = mutation({
|
|||||||
success: v.boolean()
|
success: v.boolean()
|
||||||
}),
|
}),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'ajustar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -3794,12 +3944,17 @@ export const atualizarConfiguracaoBancoHoras = mutation({
|
|||||||
configId: v.id('configuracaoBancoHoras')
|
configId: v.id('configuracaoBancoHoras')
|
||||||
}),
|
}),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'configurar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Verificar permissão de TI
|
// Permissão já verificada acima (banco_horas.configurar)
|
||||||
|
|
||||||
// Buscar configuração existente ou criar nova
|
// Buscar configuração existente ou criar nova
|
||||||
const configExistente = await ctx.db.query('configuracaoBancoHoras').order('desc').first();
|
const configExistente = await ctx.db.query('configuracaoBancoHoras').order('desc').first();
|
||||||
@@ -3854,12 +4009,17 @@ export const criarAlertaBancoHoras = mutation({
|
|||||||
alertaId: v.id('alertasBancoHoras')
|
alertaId: v.id('alertasBancoHoras')
|
||||||
}),
|
}),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'configurar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Verificar permissão de TI
|
// Permissão já verificada acima (banco_horas.configurar)
|
||||||
|
|
||||||
// Verificar se já existe alerta do mesmo tipo
|
// Verificar se já existe alerta do mesmo tipo
|
||||||
const alertaExistente = await ctx.db
|
const alertaExistente = await ctx.db
|
||||||
@@ -3907,12 +4067,17 @@ export const atualizarConfiguracaoAlerta = mutation({
|
|||||||
success: v.boolean()
|
success: v.boolean()
|
||||||
}),
|
}),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'configurar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Verificar permissão de TI
|
// Permissão já verificada acima (banco_horas.configurar)
|
||||||
|
|
||||||
const alerta = await ctx.db.get(args.alertaId);
|
const alerta = await ctx.db.get(args.alertaId);
|
||||||
if (!alerta) {
|
if (!alerta) {
|
||||||
@@ -3952,6 +4117,11 @@ export const recalcularBancoHoras = mutation({
|
|||||||
diasRecalculados: v.number()
|
diasRecalculados: v.number()
|
||||||
}),
|
}),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'configurar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
@@ -4194,7 +4364,7 @@ export const detectarEEnviarAlertasBancoHoras = internalMutation({
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'dias_sem_registro':
|
case 'dias_sem_registro': {
|
||||||
// Verificar últimos 7 dias
|
// Verificar últimos 7 dias
|
||||||
const ultimos7Dias: string[] = [];
|
const ultimos7Dias: string[] = [];
|
||||||
for (let i = 0; i < 7; i++) {
|
for (let i = 0; i < 7; i++) {
|
||||||
@@ -4221,6 +4391,7 @@ export const detectarEEnviarAlertasBancoHoras = internalMutation({
|
|||||||
mensagem = `O funcionário não possui registro de ponto em ${diasSemRegistro.length} dos últimos 7 dias.`;
|
mensagem = `O funcionário não possui registro de ponto em ${diasSemRegistro.length} dos últimos 7 dias.`;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'limite_saldo_excedido':
|
case 'limite_saldo_excedido':
|
||||||
if (bancoMensal) {
|
if (bancoMensal) {
|
||||||
@@ -4329,6 +4500,11 @@ export const inicializarAlertasPadrao = mutation({
|
|||||||
alertasCriados: v.number()
|
alertasCriados: v.number()
|
||||||
}),
|
}),
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'banco_horas',
|
||||||
|
acao: 'configurar'
|
||||||
|
});
|
||||||
|
|
||||||
const usuario = await getCurrentUserFunction(ctx);
|
const usuario = await getCurrentUserFunction(ctx);
|
||||||
if (!usuario) {
|
if (!usuario) {
|
||||||
throw new Error('Usuário não autenticado');
|
throw new Error('Usuário não autenticado');
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { v } from 'convex/values';
|
import { v } from 'convex/values';
|
||||||
import { mutation, query } from './_generated/server';
|
import { mutation, query } from './_generated/server';
|
||||||
|
import { internal } from './_generated/api';
|
||||||
import { simboloTipo } from './tables/funcionarios';
|
import { simboloTipo } from './tables/funcionarios';
|
||||||
|
|
||||||
export const getAll = query({
|
export const getAll = query({
|
||||||
@@ -17,6 +18,10 @@ export const getAll = query({
|
|||||||
})
|
})
|
||||||
),
|
),
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'simbolos',
|
||||||
|
acao: 'listar'
|
||||||
|
});
|
||||||
return await ctx.db.query('simbolos').collect();
|
return await ctx.db.query('simbolos').collect();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -39,6 +44,10 @@ export const getById = query({
|
|||||||
v.null()
|
v.null()
|
||||||
),
|
),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'simbolos',
|
||||||
|
acao: 'ver'
|
||||||
|
});
|
||||||
return await ctx.db.get(args.id);
|
return await ctx.db.get(args.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -53,6 +62,11 @@ export const create = mutation({
|
|||||||
valor: v.optional(v.string())
|
valor: v.optional(v.string())
|
||||||
},
|
},
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'simbolos',
|
||||||
|
acao: 'criar'
|
||||||
|
});
|
||||||
|
|
||||||
let refValor = args.refValor;
|
let refValor = args.refValor;
|
||||||
let vencValor = args.vencValor;
|
let vencValor = args.vencValor;
|
||||||
let valor = args.valor ?? '';
|
let valor = args.valor ?? '';
|
||||||
@@ -90,6 +104,10 @@ export const remove = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.null(),
|
returns: v.null(),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'simbolos',
|
||||||
|
acao: 'excluir'
|
||||||
|
});
|
||||||
await ctx.db.delete(args.id);
|
await ctx.db.delete(args.id);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -107,6 +125,11 @@ export const update = mutation({
|
|||||||
},
|
},
|
||||||
returns: v.null(),
|
returns: v.null(),
|
||||||
handler: async (ctx, args) => {
|
handler: async (ctx, args) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'simbolos',
|
||||||
|
acao: 'editar'
|
||||||
|
});
|
||||||
|
|
||||||
let refValor = args.refValor;
|
let refValor = args.refValor;
|
||||||
let vencValor = args.vencValor;
|
let vencValor = args.vencValor;
|
||||||
let valor = args.valor ?? '';
|
let valor = args.valor ?? '';
|
||||||
@@ -149,6 +172,11 @@ export const removerDuplicados = mutation({
|
|||||||
mantidos: v.number()
|
mantidos: v.number()
|
||||||
}),
|
}),
|
||||||
handler: async (ctx) => {
|
handler: async (ctx) => {
|
||||||
|
await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, {
|
||||||
|
recurso: 'simbolos',
|
||||||
|
acao: 'excluir'
|
||||||
|
});
|
||||||
|
|
||||||
const todosSimbolos = await ctx.db.query('simbolos').collect();
|
const todosSimbolos = await ctx.db.query('simbolos').collect();
|
||||||
|
|
||||||
// Agrupar símbolos por nome
|
// Agrupar símbolos por nome
|
||||||
|
|||||||
Reference in New Issue
Block a user